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
@@ -1,5 +1,6 @@
1
1
  export * from "./containerRuntime.js";
2
2
  export * from "./dockerRuntime.js";
3
+ export * from "./gitGithubTransport.js";
3
4
  export * from "./gitToolchainMounts.js";
4
5
  export * from "./launchTargetTerminal.js";
5
6
  export * from "./managedDatabases.js";
@@ -1,3 +1,4 @@
1
+ import { Buffer } from "node:buffer";
1
2
  import crypto from "node:crypto";
2
3
  import { spawn as spawnPty } from "node-pty";
3
4
 
@@ -47,8 +48,14 @@ function terminalSessionResponse(session) {
47
48
  id: session.id,
48
49
  commandPreview: session.commandPreview,
49
50
  exitCode: session.exitCode,
51
+ inputVersion: session.inputVersion || 0,
52
+ lastInputAt: session.lastInputAt || "",
53
+ lastInputBytes: session.lastInputBytes || 0,
54
+ lastOutputAt: session.lastOutputAt || "",
55
+ lastOutputBytes: session.lastOutputBytes || 0,
50
56
  metadata: session.metadata || {},
51
57
  output: session.output,
58
+ outputVersion: session.outputVersion || 0,
52
59
  rows: session.rows || DEFAULT_TERMINAL_ROWS,
53
60
  status: session.status
54
61
  };
@@ -101,6 +108,36 @@ function applySessionMetadata(session, metadata = {}) {
101
108
  return terminalSessionResponse(session);
102
109
  }
103
110
 
111
+ function byteLength(value = "") {
112
+ return Buffer.byteLength(String(value || ""), "utf8");
113
+ }
114
+
115
+ function recordTerminalInput(session, data = "") {
116
+ const bytes = byteLength(data);
117
+ if (bytes < 1) {
118
+ return;
119
+ }
120
+ session.inputVersion = Number(session.inputVersion || 0) + 1;
121
+ session.lastInputAt = new Date().toISOString();
122
+ session.lastInputBytes = bytes;
123
+ sendToSubscribers(session, {
124
+ bytes,
125
+ inputVersion: session.inputVersion,
126
+ lastInputAt: session.lastInputAt,
127
+ type: "input"
128
+ });
129
+ }
130
+
131
+ function recordTerminalOutput(session, data = "") {
132
+ const bytes = byteLength(data);
133
+ if (bytes < 1) {
134
+ return;
135
+ }
136
+ session.outputVersion = Number(session.outputVersion || 0) + 1;
137
+ session.lastOutputAt = new Date().toISOString();
138
+ session.lastOutputBytes = bytes;
139
+ }
140
+
104
141
  function sendToSubscribers(session, message) {
105
142
  if (!session?.subscribers?.size) {
106
143
  return;
@@ -300,7 +337,13 @@ function startTerminalSession({
300
337
  : {},
301
338
  onClose,
302
339
  onStop,
340
+ inputVersion: 0,
341
+ lastInputAt: "",
342
+ lastInputBytes: 0,
343
+ lastOutputAt: "",
344
+ lastOutputBytes: 0,
303
345
  output: "",
346
+ outputVersion: 0,
304
347
  rows: DEFAULT_TERMINAL_ROWS,
305
348
  status: "running",
306
349
  subscribers: new Set(),
@@ -308,9 +351,12 @@ function startTerminalSession({
308
351
  };
309
352
 
310
353
  terminal.onData((data) => {
354
+ recordTerminalOutput(session, data);
311
355
  session.output = trimBuffer(session.output + data);
312
356
  sendToSubscribers(session, {
313
357
  chunk: data,
358
+ lastOutputAt: session.lastOutputAt,
359
+ outputVersion: session.outputVersion,
314
360
  type: "output"
315
361
  });
316
362
  if (typeof onOutput === "function") {
@@ -420,7 +466,11 @@ function writeTerminalSession(id, data, { namespace = "default" } = {}) {
420
466
  return readTerminalSession(id, { namespace });
421
467
  }
422
468
 
423
- session.terminal.write(String(data || ""));
469
+ const input = String(data || "");
470
+ if (input) {
471
+ recordTerminalInput(session, input);
472
+ session.terminal.write(input);
473
+ }
424
474
  return readTerminalSession(id, { namespace });
425
475
  }
426
476
 
@@ -233,6 +233,10 @@ class TargetAdapter {
233
233
  return [];
234
234
  }
235
235
 
236
+ async listProjectTools() {
237
+ return [];
238
+ }
239
+
236
240
  async createCommandTerminalSpec(commandId) {
237
241
  return {
238
242
  ok: false,
@@ -62,6 +62,7 @@ import {
62
62
  } from "./currentApp.js";
63
63
  import {
64
64
  createLaravelRuntimeContainers,
65
+ listLaravelDatabaseProjectTools,
65
66
  selectedLaravelDatabaseRuntime
66
67
  } from "./databaseRuntime.js";
67
68
  import {
@@ -428,6 +429,10 @@ class LaravelTargetAdapter extends Vibe64DescribedWorkflowTargetAdapter {
428
429
  }
429
430
  });
430
431
  }
432
+
433
+ async listProjectTools(context = {}) {
434
+ return listLaravelDatabaseProjectTools(context);
435
+ }
431
436
  }
432
437
 
433
438
  export {
@@ -141,6 +141,54 @@ function createLaravelRuntimeContainers({
141
141
  return [];
142
142
  }
143
143
 
144
+ function mysqlCompatibleLaravelRuntime(config = {}) {
145
+ return ["mysql", "mariadb"].includes(selectedLaravelDatabaseRuntime(config));
146
+ }
147
+
148
+ function mysqlClientScript() {
149
+ return [
150
+ "set -e",
151
+ "if command -v mysql >/dev/null 2>&1; then",
152
+ " exec mysql",
153
+ "fi",
154
+ "if command -v mariadb >/dev/null 2>&1; then",
155
+ " exec mariadb",
156
+ "fi",
157
+ "printf '[studio] No MySQL-compatible client was found in this toolchain.\\n' >&2",
158
+ "exit 127"
159
+ ].join("\n");
160
+ }
161
+
162
+ function listLaravelDatabaseProjectTools({
163
+ config = {},
164
+ targetRoot = ""
165
+ } = {}) {
166
+ if (!mysqlCompatibleLaravelRuntime(config)) {
167
+ return [];
168
+ }
169
+ return [
170
+ {
171
+ id: "connect_mysql",
172
+ label: "Connect to MySQL",
173
+ description: "Open an interactive client for the configured Vibe64-managed MySQL or MariaDB service.",
174
+ type: "command",
175
+ parameters: [],
176
+ async command() {
177
+ return {
178
+ args: [
179
+ "-lc",
180
+ mysqlClientScript()
181
+ ],
182
+ command: "bash",
183
+ commandPreview: "mysql",
184
+ cwd: targetRoot,
185
+ ok: true
186
+ };
187
+ }
188
+ }
189
+ ];
190
+ }
191
+
144
192
  function laravelRuntimeContainerName({
145
193
  config = {},
146
194
  targetRoot = ""
@@ -232,6 +280,8 @@ export {
232
280
  laravelDatabaseEnvWriteScript,
233
281
  laravelDatabaseNameFromTargetRoot,
234
282
  laravelRuntimeContainerName,
283
+ listLaravelDatabaseProjectTools,
284
+ mysqlCompatibleLaravelRuntime,
235
285
  selectedLaravelDatabaseRuntime,
236
286
  startLaravelRuntimeRepair
237
287
  };
@@ -18,6 +18,8 @@ import {
18
18
  const VIBE64_CONFIG_DIR = "config";
19
19
  const VIBE64_RUNTIME_DIR = "runtime";
20
20
  const VIBE64_CONFIG_HELPER_FILE = "vibe64-config.sh";
21
+ const VIBE64_DEPLOY_PRODUCTION_COMMAND_CONFIG = "deploy_production_command";
22
+ const VIBE64_DEPLOY_STAGING_COMMAND_CONFIG = "deploy_staging_command";
21
23
  const CONFIG_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/u;
22
24
  const CONFIG_FIELD_TYPES = new Set(["boolean", "path", "select", "string"]);
23
25
 
@@ -45,6 +47,22 @@ const VIBE64_GENERAL_CONFIG_FIELDS = deepFreeze([
45
47
  }
46
48
  ],
47
49
  type: "select"
50
+ },
51
+ {
52
+ defaultValue: "",
53
+ description: "Command Studio should run from the main checkout when you choose Tools > Push to production.",
54
+ id: VIBE64_DEPLOY_PRODUCTION_COMMAND_CONFIG,
55
+ label: "Production deploy command",
56
+ required: false,
57
+ type: "string"
58
+ },
59
+ {
60
+ defaultValue: "",
61
+ description: "Command Studio should run from the main checkout when you choose Tools > Push to staging.",
62
+ id: VIBE64_DEPLOY_STAGING_COMMAND_CONFIG,
63
+ label: "Staging deploy command",
64
+ required: false,
65
+ type: "string"
48
66
  }
49
67
  ]);
50
68
 
@@ -444,8 +462,9 @@ function createVibe64ProjectConfigStore({
444
462
  }));
445
463
  const fieldValues = Object.fromEntries(entries);
446
464
  const values = Object.fromEntries(entries.map(([fieldId, state]) => [fieldId, state.value]));
465
+ const fieldById = new Map(normalizedDefinition.fields.map((field) => [field.id, field]));
447
466
  const missing = entries
448
- .filter(([, state]) => !state.saved)
467
+ .filter(([fieldId, state]) => fieldById.get(fieldId)?.required !== false && !state.saved)
449
468
  .map(([fieldId]) => fieldId)
450
469
  .sort((left, right) => left.localeCompare(right));
451
470
  const invalid = entries
@@ -524,6 +543,8 @@ function createVibe64ProjectConfigStore({
524
543
  export {
525
544
  VIBE64_CONFIG_DIR,
526
545
  VIBE64_CONFIG_HELPER_FILE,
546
+ VIBE64_DEPLOY_PRODUCTION_COMMAND_CONFIG,
547
+ VIBE64_DEPLOY_STAGING_COMMAND_CONFIG,
527
548
  VIBE64_GENERAL_CONFIG_FIELDS,
528
549
  VIBE64_RUNTIME_DIR,
529
550
  createVibe64ProjectConfigStore,
@@ -32,11 +32,9 @@ General rules:
32
32
  - Do not modify Vibe64 session internals or artifact files.
33
33
 
34
34
  Workflow-specific behavior:
35
- - If `session.currentStep` is `agent_conversation`, this is the General coding change-making step. Make the requested code or project changes directly, following the adapter and framework guidance. When you are done, report what changed, what you checked, and what remains unresolved. The user decides when to continue to validation.
36
35
  - If `session.currentStep` is `implementation_reviewed`, the user is reviewing the implemented work before slower checks. Make only the focused tweak requested by `conversationRequest`, run the focused checks that prove it when practical, and submit the response through the current-step input helper.
37
36
  - If `session.currentStep` is `changes_accepted`, the user is doing final review after validation. Make only the requested final tweak. Vibe64 will send the workflow back through review and validation after this prompt completes.
38
37
  - If this step needs to show a response in Vibe64, submit that response through the current-step input helper.
39
- - If `metadata.workflow_definition` is `non_code_maintenance`, make the requested documentation or non-code project changes in the session worktree. Do not modify application code unless the user explicitly asks for it or it is strictly required for the non-code task.
40
38
  - For other workflow definitions, answer, inspect, or edit according to the user's request and the current step contract.
41
39
 
42
40
  Response artifact contract:
@@ -0,0 +1,18 @@
1
+ You are defining the work for this Vibe64 session.
2
+
3
+ Use the user's request or feedback to propose:
4
+ - a concise work title
5
+ - a Markdown work description with the requested change, useful context, and acceptance criteria
6
+ - a short Vibe64 session label/word derived from the work title
7
+
8
+ If session metadata `github_issue_mode` is `create`, the saved title and description will be used to create a GitHub issue later in this same workflow step.
9
+ If `github_issue_mode` is `skip`, no GitHub issue will be created; the saved title and description are the work anchor for planning.
10
+
11
+ If Action input contains feedback about an existing draft, read the current draft artifacts from the session artifacts root before revising it:
12
+ - issue_title
13
+ - issue.md
14
+ - issue_word
15
+
16
+ If the request is too vague to define useful work, ask for the missing information through the current-step helper instead of guessing.
17
+
18
+ When you have enough information, call the current-step helper with the proposed title, body, and word. Do not write Vibe64 workflow artifacts directly.
@@ -1,4 +1,4 @@
1
- Make plan
1
+ Make a plan
2
2
 
3
3
  Vibe64 standard planning instructions.
4
4
 
@@ -7,6 +7,7 @@ Session:
7
7
  - current step: {{session.currentStep}}
8
8
  - target root: {{session.targetRoot}}
9
9
  - worktree path: {{session.worktreePath}}
10
+ - artifacts root: {{session.artifactsRoot}}
10
11
 
11
12
  Known session metadata:
12
13
  {{session.metadata.json}}
@@ -19,4 +20,15 @@ Action input:
19
20
  Missing information policy:
20
21
  {{prompt.missingInformationPolicy}}
21
22
 
22
- Create a clear, ordered implementation plan as your normal Codex response. Use the current Codex conversation, Action input, adapter facts, and project files as context. Do not modify files while creating the plan. Do not run shell commands just to display the plan.
23
+ Work anchor source of truth:
24
+ - If the saved work artifacts exist, read them before planning:
25
+ - `{{session.artifactsRoot}}/issue_title`
26
+ - `{{session.artifactsRoot}}/issue.md`
27
+ - `{{session.artifactsRoot}}/issue_word`
28
+ - Treat those artifacts as the work title, work description, and Vibe64 session word for this plan.
29
+ - When `github_issue_mode` is `create` or `reuse`, the work artifacts describe the GitHub issue context. Use `issue_url` and `issue_number` metadata only as references. Do not call GitHub to rediscover the issue content unless the artifacts are missing or empty.
30
+ - When `github_issue_mode` is `skip`, do not require or create a GitHub issue before planning. Plan from the saved work artifacts, the current Codex conversation, Action input, adapter facts, and project files.
31
+ - If `work_source` is `existing_pr` and issue artifacts are absent, use the source PR metadata as the work anchor instead: `source_pr_url`, `source_pr_title`, `source_pr_head_ref`, and `source_pr_head_sha`.
32
+ - For an existing PR work anchor, do not require or create an issue before planning. Plan from the PR context, the current Codex conversation, Action input, adapter facts, and project files.
33
+
34
+ Create a clear, ordered implementation plan as your normal Codex response. Use the work anchor, current Codex conversation, Action input, adapter facts, and project files as context. Do not modify files while creating the plan. Do not run shell commands just to display the plan.
@@ -29,4 +29,6 @@ Check the PR state, identify merge blockers, resolve blockers that can be fixed
29
29
 
30
30
  Also inspect the main checkout at the target root. Confirm the base branch can be fetched, checked out, and fast-forwarded after the PR merge. If the main checkout has dirty user changes, untracked files that would be overwritten, a detached or unexpected branch state, or another local condition that makes syncing unsafe, fix only the safe mechanical blockers. Do not discard or overwrite user work. If user-owned changes block the sync, report the blocker clearly.
31
31
 
32
+ When you complete this step, include `fields.mergePreparationSummary` in the current-step input helper result. If no extra merge-preparation work was needed after pull request creation, set it to an empty string. If you changed files, created commits, adjusted repository state, fixed merge blockers, or performed any other extra work after pull request creation, set it to a concise Markdown summary of that work.
33
+
32
34
  Report whether the PR is ready to merge, whether the main checkout is ready to sync, and what remains blocked.
@@ -23,6 +23,7 @@ Body guidance:
23
23
  - Summarize the user-visible change.
24
24
  - List important files or areas changed.
25
25
  - List verification already run, or clearly say when verification is still pending.
26
+ - If this session stacks on `source_pr_url`, mention that relationship in the pull request body.
26
27
  - Mention blockers or risks only when they matter to the reviewer.
27
28
 
28
29
  After the helper reports success, stop.
@@ -1,6 +1,6 @@
1
- Run deep UI check
1
+ Check user interface
2
2
 
3
- Vibe64 standard deep UI check instructions.
3
+ Vibe64 standard user interface check instructions.
4
4
 
5
5
  Session:
6
6
  - id: {{session.id}}
@@ -19,4 +19,8 @@ Action input:
19
19
  Missing information policy:
20
20
  {{prompt.missingInformationPolicy}}
21
21
 
22
- Inspect the user-facing application behavior carefully. Focus on real UI defects, broken flows, layout issues, state mistakes, and mismatches with the requested work. Fix clear defects directly when the project supports it. Report what you changed, which checks ran, and why no edit was needed if the UI is already sound.
22
+ Changed-files scope:
23
+ Before inspecting the application, identify the session worktree diff and changed files. Only check user-facing behavior that could plausibly be affected by those changed files and the requested work. Do not run a broad whole-application UI audit. If the changed files do not affect UI behavior, say that directly and complete the step without spending time on unrelated screens.
24
+ Hard stop: if the diff only contains non-UI files, documentation, generated helper-map output, or inert root files such as an empty `.txt` file, do not launch the app, browse unrelated screens, or run a whole UI check. Report that no user-interface check is needed for the changed files and complete the step.
25
+
26
+ Inspect the affected user-facing application behavior carefully. Focus on real UI defects, broken flows, layout issues, state mistakes, and mismatches with the requested work. Fix clear defects directly when the project supports it. Report what you changed, which checks ran, and why no edit was needed if the affected UI is already sound.
@@ -17,13 +17,10 @@ import {
17
17
 
18
18
  function commitChangesScript(session = {}) {
19
19
  const issueTitlePath = metadataFilePath(session, "issue_title");
20
- const directExistingPr = normalizeText(session.metadata?.work_source) === "existing_pr" &&
21
- normalizeText(session.metadata?.source_pr_update_mode) === "direct";
22
20
  const baseBranch = normalizeText(session.metadata?.base_branch) ||
21
+ normalizeText(session.metadata?.source_pr_head_ref) ||
23
22
  normalizeText(session.metadata?.source_pr_base_ref) ||
24
23
  "main";
25
- const sourcePrHeadRef = normalizeText(session.metadata?.source_pr_head_ref);
26
- const sourcePrHeadRepo = normalizeText(session.metadata?.source_pr_head_repo);
27
24
  return [
28
25
  "set -e",
29
26
  `COMMIT_TITLE="$(cat ${shellQuote(issueTitlePath)} 2>/dev/null | head -n 1 | sed 's/[[:space:]]*$//')"`,
@@ -51,24 +48,9 @@ function commitChangesScript(session = {}) {
51
48
  " exit 1",
52
49
  "fi",
53
50
  "ACCEPTED_COMMIT=\"$(git rev-parse --verify HEAD)\"",
54
- ...(directExistingPr ? [
55
- `SOURCE_PR_HEAD_REF=${shellQuote(sourcePrHeadRef)}`,
56
- `SOURCE_PR_HEAD_REPO=${shellQuote(sourcePrHeadRepo)}`,
57
- "if [ -z \"$SOURCE_PR_HEAD_REF\" ] || [ -z \"$SOURCE_PR_HEAD_REPO\" ]; then",
58
- " printf '[studio] Existing PR push target is missing.\\n' >&2",
59
- " exit 1",
60
- "fi",
61
- "PR_HEAD_REMOTE=\"vibe64-pr-head\"",
62
- "git remote remove \"$PR_HEAD_REMOTE\" >/dev/null 2>&1 || true",
63
- "git remote add \"$PR_HEAD_REMOTE\" \"https://github.com/$SOURCE_PR_HEAD_REPO.git\"",
64
- "printf '[studio] Pushing changes to existing PR branch %s/%s\\n' \"$SOURCE_PR_HEAD_REPO\" \"$SOURCE_PR_HEAD_REF\"",
65
- "git push \"$PR_HEAD_REMOTE\" \"HEAD:refs/heads/$SOURCE_PR_HEAD_REF\"",
66
- recordCommandFactScript("branch_pushed", "\"$SOURCE_PR_HEAD_REF\"")
67
- ] : [
68
- "printf '[studio] Pushing branch %s\\n' \"$CURRENT_BRANCH\"",
69
- "git push -u origin \"$CURRENT_BRANCH\"",
70
- recordCommandFactScript("branch_pushed", "\"$CURRENT_BRANCH\"")
71
- ]),
51
+ "printf '[studio] Pushing branch %s\\n' \"$CURRENT_BRANCH\"",
52
+ "git push -u origin \"$CURRENT_BRANCH\"",
53
+ recordCommandFactScript("branch_pushed", "\"$CURRENT_BRANCH\""),
72
54
  recordCommandFactScript("accepted_commit", "\"$ACCEPTED_COMMIT\""),
73
55
  "printf '[studio] Committed %s\\n' \"$ACCEPTED_COMMIT\""
74
56
  ].join("\n");
@@ -37,27 +37,23 @@ function createWorktreeSuccessMetadataFromFacts({ facts = {}, session = {} } = {
37
37
  return commandMetadataResult();
38
38
  }
39
39
 
40
- const updateMode = normalizeText(facts.source_pr_update_mode);
41
- if (updateMode === "direct") {
42
- return commandMetadataResult({
43
- metadata: {
44
- pr_source: "existing",
45
- pr_url: normalizeText(facts.pr_url) || normalizeText(session.metadata?.source_pr_url),
46
- source_pr_update_mode: "direct"
47
- }
48
- });
49
- }
50
-
51
- if (updateMode === "replacement") {
52
- return commandMetadataResult({
53
- deleteMetadata: ["pr_url"],
54
- metadata: {
55
- source_pr_update_mode: "replacement"
56
- }
57
- });
40
+ const updateMode = normalizeText(facts.source_pr_update_mode) ||
41
+ normalizeText(session.metadata?.source_pr_update_mode);
42
+ if (updateMode !== "stacked" && !normalizeText(session.metadata?.source_pr_url)) {
43
+ return commandMetadataResult();
58
44
  }
59
45
 
60
- return commandMetadataResult();
46
+ const sessionPrUrl = normalizeText(session.metadata?.pr_url);
47
+ const sourcePrUrl = normalizeText(session.metadata?.source_pr_url);
48
+ const deletePrMetadata = sessionPrUrl && sessionPrUrl === sourcePrUrl
49
+ ? ["pr_url", "pr_source", "pr_number", "pr_title"]
50
+ : [];
51
+ return commandMetadataResult({
52
+ deleteMetadata: deletePrMetadata,
53
+ metadata: {
54
+ source_pr_update_mode: "stacked"
55
+ }
56
+ });
61
57
  }
62
58
 
63
59
  function commitChangesSuccessMetadataFromFacts({ facts = {} } = {}) {
@@ -80,7 +76,12 @@ function createIssueSuccessMetadataFromFacts({ facts = {} } = {}) {
80
76
  }
81
77
  return commandMetadataResult({
82
78
  metadata: {
79
+ github_issue_mode: "create",
83
80
  issue_source: "created",
81
+ work_anchor_number: normalizeText(metadata.issue_number),
82
+ work_anchor_title: normalizeText(metadata.issue_title),
83
+ work_anchor_type: "issue",
84
+ work_anchor_url: normalizeText(metadata.issue_url),
84
85
  ...metadata
85
86
  }
86
87
  });
@@ -99,7 +100,7 @@ function createPrSuccessMetadataFromFacts({ facts = {}, session = {} } = {}) {
99
100
  return commandMetadataResult({
100
101
  metadata: {
101
102
  ...metadata,
102
- pr_source: normalizeText(metadata.pr_source) || (normalizeText(session.metadata?.source_pr_url) ? "replacement" : "created")
103
+ pr_source: normalizeText(metadata.pr_source) || (normalizeText(session.metadata?.source_pr_url) ? "stacked" : "created")
103
104
  }
104
105
  });
105
106
  }
@@ -46,12 +46,16 @@ function createIssueOnGhScript(session = {}) {
46
46
  }
47
47
 
48
48
  function createPrOnGhScript(session = {}) {
49
- const stepId = "create_pull_request";
49
+ const stepId = "create_and_merge_pull_request";
50
50
  const prBodyPath = artifactFilePath(session, `tmp/${stepId}.body.md`);
51
51
  const prTitlePath = artifactFilePath(session, `tmp/${stepId}.title.txt`);
52
+ const sourcePrHeadSha = normalizeText(session.metadata?.source_pr_head_sha);
53
+ const sourcePrNumber = normalizeText(session.metadata?.source_pr_number);
52
54
  const sourcePrUrl = normalizeText(session.metadata?.source_pr_url);
53
55
  const branch = normalizeText(session.metadata?.branch);
54
- const baseBranch = normalizeText(session.metadata?.base_branch) || "main";
56
+ const baseBranch = normalizeText(session.metadata?.base_branch) ||
57
+ normalizeText(session.metadata?.source_pr_head_ref) ||
58
+ "main";
55
59
  const quotedBaseBranch = shellQuote(baseBranch);
56
60
  const quotedBranch = shellQuote(branch);
57
61
  return [
@@ -71,6 +75,25 @@ function createPrOnGhScript(session = {}) {
71
75
  " printf '[studio] Worktree is on branch %s, expected %s.\\n' \"$CURRENT_BRANCH\" \"$EXPECTED_BRANCH\" >&2",
72
76
  " exit 1",
73
77
  "fi",
78
+ `SOURCE_PR_NUMBER=${shellQuote(sourcePrNumber)}`,
79
+ `SOURCE_PR_HEAD_SHA=${shellQuote(sourcePrHeadSha)}`,
80
+ "if [ -n \"$SOURCE_PR_NUMBER\" ]; then",
81
+ " printf '[studio] Validating stacked PR base #%s\\n' \"$SOURCE_PR_NUMBER\"",
82
+ " SOURCE_PR_STATE=\"$(gh pr view \"$SOURCE_PR_NUMBER\" --json state --jq '.state' 2>/dev/null | head -n 1 | sed 's/[[:space:]]*$//')\"",
83
+ " SOURCE_PR_CURRENT_SHA=\"$(gh pr view \"$SOURCE_PR_NUMBER\" --json headRefOid --jq '.headRefOid' 2>/dev/null | head -n 1 | sed 's/[[:space:]]*$//')\"",
84
+ " if [ -z \"$SOURCE_PR_STATE\" ] || [ -z \"$SOURCE_PR_CURRENT_SHA\" ]; then",
85
+ " printf '[studio] Could not validate existing PR #%s. Check GitHub access, then retry.\\n' \"$SOURCE_PR_NUMBER\" >&2",
86
+ " exit 1",
87
+ " fi",
88
+ " if [ \"$SOURCE_PR_STATE\" != \"OPEN\" ]; then",
89
+ " printf '[studio] Existing PR #%s is %s. Start a new session from the current work anchor.\\n' \"$SOURCE_PR_NUMBER\" \"$SOURCE_PR_STATE\" >&2",
90
+ " exit 1",
91
+ " fi",
92
+ " if [ -n \"$SOURCE_PR_HEAD_SHA\" ] && [ \"$SOURCE_PR_CURRENT_SHA\" != \"$SOURCE_PR_HEAD_SHA\" ]; then",
93
+ " printf '[studio] Existing PR #%s moved from %s to %s. Start a new session from the updated PR.\\n' \"$SOURCE_PR_NUMBER\" \"$SOURCE_PR_HEAD_SHA\" \"$SOURCE_PR_CURRENT_SHA\" >&2",
94
+ " exit 1",
95
+ " fi",
96
+ "fi",
74
97
  "git fetch origin \"$BASE_BRANCH\"",
75
98
  "BASE_REF=\"origin/$BASE_BRANCH\"",
76
99
  "if ! git rev-parse --verify \"$BASE_REF\" >/dev/null 2>&1; then",
@@ -88,7 +111,7 @@ function createPrOnGhScript(session = {}) {
88
111
  "fi",
89
112
  `SOURCE_PR_URL=${shellQuote(sourcePrUrl)}`,
90
113
  "if [ -n \"$SOURCE_PR_URL\" ]; then",
91
- " PR_SOURCE=replacement",
114
+ " PR_SOURCE=stacked",
92
115
  "else",
93
116
  " PR_SOURCE=created",
94
117
  "fi",
@@ -96,7 +119,7 @@ function createPrOnGhScript(session = {}) {
96
119
  "if [ -n \"$SOURCE_PR_URL\" ]; then",
97
120
  " PR_BODY_FILE=\"$(mktemp)\"",
98
121
  ` cat ${shellQuote(prBodyPath)} > "$PR_BODY_FILE"`,
99
- " printf '\\n\\nContinues existing pull request: %s\\n' \"$SOURCE_PR_URL\" >> \"$PR_BODY_FILE\"",
122
+ " printf '\\n\\nStacks on existing pull request: %s\\n' \"$SOURCE_PR_URL\" >> \"$PR_BODY_FILE\"",
100
123
  "fi",
101
124
  "find_existing_pull_request_url() {",
102
125
  " gh pr list --head \"$EXPECTED_BRANCH\" --base \"$BASE_BRANCH\" --state open --json url --jq '.[0].url' 2>/dev/null | head -n 1 | sed 's/[[:space:]]*$//'",
@@ -21,6 +21,7 @@ function mergePrScript({
21
21
  session = {}
22
22
  } = {}) {
23
23
  const prUrl = normalizeText(session.metadata?.pr_url);
24
+ const mergePreparationSummary = normalizeText(session.metadata?.merge_preparation_summary);
24
25
  const mergeFlag = {
25
26
  merge: "--merge",
26
27
  rebase: "--rebase",
@@ -30,18 +31,50 @@ function mergePrScript({
30
31
  "set -e",
31
32
  beforeMergeScript,
32
33
  `printf '[studio] Merging pull request %s\\n' ${shellQuote(prUrl)}`,
33
- `gh pr merge ${shellQuote(prUrl)} ${mergeFlag}`
34
+ `gh pr merge ${shellQuote(prUrl)} ${mergeFlag}`,
35
+ mergePreparationCommentScript({
36
+ prUrl,
37
+ summary: mergePreparationSummary
38
+ })
34
39
  ].filter(Boolean).join("\n");
35
40
  }
36
41
 
37
- function syncMainCheckoutScript(session = {}, targetRoot = "") {
38
- const baseBranch = normalizeText(session.metadata?.base_branch) || "main";
42
+ function mergePreparationCommentScript({
43
+ prUrl = "",
44
+ summary = ""
45
+ } = {}) {
46
+ const normalizedSummary = normalizeText(summary);
47
+ if (!normalizedSummary) {
48
+ return "";
49
+ }
50
+ const comment = [
51
+ "## Vibe64 merge preparation",
52
+ "",
53
+ "Additional merge-preparation work was performed after this pull request was created and before it was merged.",
54
+ "",
55
+ normalizedSummary
56
+ ].join("\n");
57
+ return [
58
+ `MERGE_PREPARATION_COMMENT_FILE="$(mktemp)"`,
59
+ `printf '%s\\n' ${shellQuote(comment)} > "$MERGE_PREPARATION_COMMENT_FILE"`,
60
+ `if ! gh pr comment ${shellQuote(prUrl)} --body-file "$MERGE_PREPARATION_COMMENT_FILE"; then`,
61
+ ` printf '[studio] Merge-preparation comment failed; pull request was already merged.\\n' >&2`,
62
+ "fi",
63
+ `rm -f "$MERGE_PREPARATION_COMMENT_FILE"`
64
+ ].join("\n");
65
+ }
66
+
67
+ function syncMainCheckoutScript({
68
+ baseBranch = "main",
69
+ targetRoot = ""
70
+ } = {}) {
71
+ const normalizedBaseBranch = normalizeText(baseBranch) || "main";
39
72
  return [
40
73
  "set -e",
41
- `printf '[studio] Syncing main checkout %s to %s\\n' ${shellQuote(targetRoot)} ${shellQuote(baseBranch)}`,
42
- `git -C ${shellQuote(targetRoot)} fetch origin ${shellQuote(baseBranch)}`,
43
- `git -C ${shellQuote(targetRoot)} checkout ${shellQuote(baseBranch)}`,
44
- `git -C ${shellQuote(targetRoot)} pull --ff-only origin ${shellQuote(baseBranch)}`
74
+ `printf '[studio] Syncing main checkout %s to %s\\n' ${shellQuote(targetRoot)} ${shellQuote(normalizedBaseBranch)}`,
75
+ `git -C ${shellQuote(targetRoot)} fetch origin ${shellQuote(normalizedBaseBranch)}`,
76
+ `git -C ${shellQuote(targetRoot)} checkout ${shellQuote(normalizedBaseBranch)}`,
77
+ `git -C ${shellQuote(targetRoot)} pull --ff-only origin ${shellQuote(normalizedBaseBranch)}`
45
78
  ].join("\n");
46
79
  }
47
80
 
@@ -102,11 +135,35 @@ async function syncMainCheckoutTerminalSpec({
102
135
  metadata: {
103
136
  main_checkout_synced: "yes"
104
137
  },
105
- script: syncMainCheckoutScript(session, syncRoot)
138
+ script: syncMainCheckoutScript({
139
+ baseBranch: session.metadata?.base_branch,
140
+ targetRoot: syncRoot
141
+ })
142
+ });
143
+ }
144
+
145
+ async function projectSyncMainCheckoutTerminalSpec({
146
+ baseBranch = "main",
147
+ targetRoot = ""
148
+ } = {}) {
149
+ const syncRoot = targetRoot || process.cwd();
150
+ return completedMetadataSpec({
151
+ commandPreview: "git fetch && git pull --ff-only",
152
+ cwd: syncRoot,
153
+ label: "Sync main checkout",
154
+ metadata: {
155
+ main_checkout_synced: "yes"
156
+ },
157
+ script: syncMainCheckoutScript({
158
+ baseBranch,
159
+ targetRoot: syncRoot
160
+ })
106
161
  });
107
162
  }
108
163
 
109
164
  export {
110
165
  mergePrTerminalSpec,
166
+ projectSyncMainCheckoutTerminalSpec,
167
+ syncMainCheckoutScript,
111
168
  syncMainCheckoutTerminalSpec
112
169
  };