@jskit-ai/jskit-cli 0.2.88 → 0.2.90

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 (25) hide show
  1. package/package.json +4 -4
  2. package/src/server/commandHandlers/session.js +173 -142
  3. package/src/server/core/argParser.js +0 -4
  4. package/src/server/core/commandCatalog.js +47 -35
  5. package/src/server/sessionRuntime/constants.js +130 -353
  6. package/src/server/sessionRuntime/io.js +2 -2
  7. package/src/server/sessionRuntime/preconditions.js +40 -144
  8. package/src/server/sessionRuntime/promptRenderer.js +2 -15
  9. package/src/server/sessionRuntime/prompts/app_blueprint.md +2 -7
  10. package/src/server/sessionRuntime/prompts/{automated_checks.md → automated_checks_run.md} +2 -17
  11. package/src/server/sessionRuntime/prompts/{update_blueprint.md → blueprint_updated.md} +2 -11
  12. package/src/server/sessionRuntime/prompts/{deep_ui_check.md → deep_ui_check_run.md} +2 -19
  13. package/src/server/sessionRuntime/prompts/final_report_created.md +44 -0
  14. package/src/server/sessionRuntime/prompts/issue_created.md +26 -0
  15. package/src/server/sessionRuntime/prompts/issue_prompt_rendered.md +1 -0
  16. package/src/server/sessionRuntime/prompts/{plan_issue.md → make_plan.md} +8 -37
  17. package/src/server/sessionRuntime/prompts/{execute_plan.md → plan_executed.md} +4 -29
  18. package/src/server/sessionRuntime/prompts/{prepare_pr_merge.md → pr_merge_prepared.md} +3 -3
  19. package/src/server/sessionRuntime/prompts/{resolve_deslop_findings.md → review_changes_accepted_resolve.md} +2 -6
  20. package/src/server/sessionRuntime/prompts/{review_changes.md → review_prompt_rendered.md} +3 -28
  21. package/src/server/sessionRuntime/prompts/{user_check.md → user_check_completed.md} +1 -11
  22. package/src/server/sessionRuntime/responses.js +504 -295
  23. package/src/server/sessionRuntime.js +1300 -961
  24. package/src/server/sessionRuntime/prompts/issue_details.md +0 -49
  25. package/src/server/sessionRuntime/prompts/new_issue.md +0 -46
@@ -13,123 +13,16 @@ const SESSION_STATUS = Object.freeze({
13
13
 
14
14
  const SESSION_ID_PATTERN = /^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(?:-[a-z0-9]{4})?$/u;
15
15
  const SESSION_STATE_RELATIVE_PATH = ".jskit/sessions";
16
- const SESSION_WORKFLOW_VERSION = "6";
16
+ const SESSION_WORKFLOW_VERSION = "7";
17
+ const DEPENDENCIES_INSTALL_RESULT_FILE = "dependencies_install_result";
17
18
  const REVIEW_PASS_LIMIT = 0;
18
19
  const PROMPT_DIRECTORY = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "prompts");
19
20
  const JSKIT_CLI_SHELL_COMMAND = "npx --no-install jskit";
20
- const JSKIT_CLI_SHELL_RULE = [
21
- "Shell command rule:",
22
- "",
23
- `- When running JSKIT CLI commands from the shell, use \`${JSKIT_CLI_SHELL_COMMAND} ...\`.`,
24
- "- Do not run bare `jskit ...` unless you are inside an npm script where `node_modules/.bin` is on PATH.",
25
- "- Do not run `npx jskit ...` without `--no-install`; it may fetch packages instead of using this app's installed CLI.",
26
- "- If `npx --no-install jskit ...` is unavailable, continue with filesystem inspection when possible and report that the local JSKIT CLI is missing."
27
- ].join("\n");
28
- const DEFAULT_NEXT_COMMAND_TEMPLATE = `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step`;
21
+ const DEFAULT_NEXT_COMMAND_TEMPLATE = `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} next`;
29
22
 
30
23
  const INPUT_NONE = Object.freeze({ type: "none" });
31
- const ISSUE_TITLE_INPUT = Object.freeze({
32
- extract: "issue_title",
33
- formatHint: "text",
34
- label: "Approved issue title",
35
- name: "issueTitle",
36
- required: true,
37
- type: "text"
38
- });
39
- const ISSUE_TEXT_INPUT = Object.freeze({
40
- extract: "issue_text",
41
- formatHint: "markdown",
42
- label: "Approved issue body",
43
- multiline: true,
44
- name: "issue",
45
- required: true,
46
- type: "text"
47
- });
48
- const ISSUE_DRAFT_INPUT = Object.freeze({
49
- fields: Object.freeze([
50
- ISSUE_TITLE_INPUT,
51
- ISSUE_TEXT_INPUT
52
- ]),
53
- type: "object"
54
- });
55
- const ISSUE_TITLE_OUTPUT = Object.freeze({
56
- extract: "issue_title",
57
- field: "issueTitle",
58
- formatHint: "text",
59
- label: "Issue title",
60
- required: true
61
- });
62
- const ISSUE_TEXT_OUTPUT = Object.freeze({
63
- extract: "issue_text",
64
- field: "issue",
65
- formatHint: "markdown",
66
- label: "Issue body",
67
- multiline: true,
68
- required: true
69
- });
70
- const PLAN_INPUT = Object.freeze({
71
- extract: "plan",
72
- formatHint: "markdown",
73
- label: "Approved plan",
74
- multiline: true,
75
- name: "plan",
76
- required: true,
77
- type: "text"
78
- });
79
- const PLAN_OUTPUT = Object.freeze({
80
- extract: "plan",
81
- field: "plan",
82
- formatHint: "markdown",
83
- label: "Plan",
84
- multiline: true,
85
- required: true
86
- });
87
- const ISSUE_DETAILS_INPUT = Object.freeze({
88
- extract: "issue_details",
89
- formatHint: "markdown",
90
- label: "Confirmed issue details",
91
- multiline: true,
92
- name: "issueDetails",
93
- required: true,
94
- type: "text"
95
- });
96
- const ISSUE_DETAILS_OUTPUT = Object.freeze({
97
- extract: "issue_details",
98
- field: "issueDetails",
99
- formatHint: "markdown",
100
- label: "Issue details",
101
- multiline: true,
102
- required: true
103
- });
104
- const ISSUE_CATEGORY_OUTPUT = Object.freeze({
105
- extract: "issue_category",
106
- field: "issueCategory",
107
- formatHint: "text",
108
- label: "Issue category",
109
- options: Object.freeze([
110
- Object.freeze({ label: "Client", value: "client" }),
111
- Object.freeze({ label: "Server", value: "server" }),
112
- Object.freeze({ label: "Client and server", value: "client_server" }),
113
- Object.freeze({ label: "Tooling", value: "tooling" }),
114
- Object.freeze({ label: "Unknown", value: "unknown" })
115
- ]),
116
- required: true
117
- });
118
- const UI_IMPACT_OUTPUT = Object.freeze({
119
- extract: "ui_impact",
120
- field: "uiImpact",
121
- formatHint: "text",
122
- label: "UI impact",
123
- options: Object.freeze([
124
- Object.freeze({ label: "No UI impact", value: "none" }),
125
- Object.freeze({ label: "Possible UI impact", value: "possible" }),
126
- Object.freeze({ label: "Definite UI impact", value: "definite" }),
127
- Object.freeze({ label: "Unknown", value: "unknown" })
128
- ]),
129
- required: true
130
- });
131
24
  const USER_CHECK_INPUT = Object.freeze({
132
- label: "User check result",
25
+ label: "Choose user check result",
133
26
  name: "userCheck",
134
27
  options: Object.freeze([
135
28
  Object.freeze({ label: "Passed", value: "passed" }),
@@ -139,72 +32,19 @@ const USER_CHECK_INPUT = Object.freeze({
139
32
  type: "choice"
140
33
  });
141
34
 
142
- const JSKIT_STEP_RESULT_CONTRACT = Object.freeze({
143
- completionBehavior: "auto_advance",
144
- kind: "completion_marker",
145
- marker: "jskit_step_result",
146
- missingMarkerBehavior: "resend",
147
- required: true,
148
- stepField: "step"
149
- });
150
- const MANUAL_JSKIT_STEP_RESULT_CONTRACT = Object.freeze({
151
- ...JSKIT_STEP_RESULT_CONTRACT,
152
- completionBehavior: "manual_advance"
153
- });
154
- const DESLOP_RESULT_CONTRACT = Object.freeze({
155
- autoResolvePriorities: Object.freeze(["high", "medium"]),
156
- completionBehavior: "deslop_loop",
157
- kind: "deslop_result",
158
- marker: "deslop_result",
159
- missingMarkerBehavior: "resend",
160
- required: true,
161
- resolvePrompt: Object.freeze({
162
- findingsPlaceholder: "{{findings}}",
163
- marker: "resolve_deslop_findings",
164
- templateFile: "resolve_deslop_findings.md"
165
- })
166
- });
167
-
168
- function fieldResponseContract(outputDefinitions) {
169
- const fields = outputDefinitions
170
- .filter((output) => output?.field && output?.extract)
171
- .map((output) => Object.freeze({
172
- extract: output.extract,
173
- field: output.field,
174
- formatHint: output.formatHint || "",
175
- label: output.label || output.field,
176
- manualEntry: true,
177
- ...(output.multiline === true ? { multiline: true } : {}),
178
- ...(Array.isArray(output.options) ? { options: Object.freeze(output.options.map((option) => Object.freeze({ ...option }))) } : {}),
179
- required: output.required !== false
180
- }));
181
- return Object.freeze({
182
- fields: Object.freeze(fields),
183
- kind: "fields",
184
- missingMarkerBehavior: "manual_or_resend",
185
- required: fields.some((field) => field.required)
186
- });
187
- }
188
-
189
- function codexHandoff(outputDefinition, {
190
- autoInject = false,
35
+ function codexHandoff({
191
36
  promptActionLabel = "",
192
37
  promptIntroText = "",
193
38
  promptWaitingText = "",
194
- responseContract = undefined
39
+ sendPrompt = false
195
40
  } = {}) {
196
- const outputDefinitions = Object.freeze(Array.isArray(outputDefinition) ? [...outputDefinition] : [outputDefinition]);
197
- const resolvedResponseContract = responseContract === undefined
198
- ? fieldResponseContract(outputDefinitions)
199
- : responseContract;
200
41
  return Object.freeze({
201
- ...(autoInject ? { autoInject: true } : {}),
202
42
  mode: "inject_prompt",
203
43
  promptField: "prompt",
204
44
  ...(promptActionLabel ? { promptActionLabel } : {}),
205
45
  ...(promptIntroText ? { promptIntroText } : {}),
206
46
  ...(promptWaitingText ? { promptWaitingText } : {}),
207
- ...(resolvedResponseContract ? { responseContract: resolvedResponseContract } : {})
47
+ ...(sendPrompt ? { sendPrompt: true } : {})
208
48
  });
209
49
  }
210
50
 
@@ -221,57 +61,58 @@ function stepAutomationFor({
221
61
  return Object.freeze({ mode: "terminal" });
222
62
  }
223
63
  if (kind === "automatic") {
224
- return Object.freeze({ mode: "immediate" });
64
+ return Object.freeze({ mode: "manual" });
225
65
  }
226
- if (kind === "codex_prompt" && codex?.autoInject === true) {
66
+ if (kind === "codex_prompt" && codex?.sendPrompt === true) {
227
67
  return Object.freeze({ mode: "codex_prompt" });
228
68
  }
229
- if (kind === "codex_output" && codex?.autoInject === true) {
230
- return Object.freeze({ mode: "codex_output_prompt" });
231
- }
232
69
  return Object.freeze({ mode: "manual" });
233
70
  }
234
71
 
235
- const PLAN_EXECUTION_CODEX_HANDOFF = codexHandoff([], {
236
- autoInject: true,
237
- promptActionLabel: "Get Codex to execute plan",
238
- responseContract: MANUAL_JSKIT_STEP_RESULT_CONTRACT
72
+ const ISSUE_DEFINITION_CODEX_HANDOFF = codexHandoff({
73
+ promptActionLabel: "Define issue",
74
+ sendPrompt: true
75
+ });
76
+ const ISSUE_FILE_CODEX_HANDOFF = codexHandoff({
77
+ promptActionLabel: "Create issue file",
78
+ sendPrompt: true
79
+ });
80
+ const PLAN_CODEX_HANDOFF = codexHandoff({
81
+ promptActionLabel: "Make plan",
82
+ sendPrompt: true
239
83
  });
240
- const ISSUE_DETAILS_CODEX_HANDOFF = codexHandoff([
241
- ISSUE_CATEGORY_OUTPUT,
242
- UI_IMPACT_OUTPUT,
243
- ISSUE_DETAILS_OUTPUT
244
- ], {
245
- autoInject: true,
246
- promptActionLabel: "Start details conversation",
247
- promptIntroText: "Codex will gather issue details and classify the issue.",
248
- promptWaitingText: "Please respond and finalise things with Codex"
84
+ const PLAN_EXECUTION_CODEX_HANDOFF = codexHandoff({
85
+ promptActionLabel: "Execute plan",
86
+ sendPrompt: true
249
87
  });
250
- const REVIEW_EXECUTION_CODEX_HANDOFF = codexHandoff([], {
251
- autoInject: true,
88
+ const REVIEW_EXECUTION_CODEX_HANDOFF = codexHandoff({
252
89
  promptActionLabel: "Run deslop",
253
- responseContract: DESLOP_RESULT_CONTRACT
90
+ sendPrompt: true
254
91
  });
255
- const DEEP_UI_CHECK_CODEX_HANDOFF = codexHandoff([], {
256
- autoInject: true,
257
- promptActionLabel: "Run Deep UI check",
258
- responseContract: JSKIT_STEP_RESULT_CONTRACT
92
+ const RESOLVE_DESLOP_CODEX_HANDOFF = codexHandoff({
93
+ promptActionLabel: "Resolve deslop",
94
+ sendPrompt: true
259
95
  });
260
- const AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF = codexHandoff([], {
261
- autoInject: true,
96
+ const DEEP_UI_CHECK_CODEX_HANDOFF = codexHandoff({
97
+ promptActionLabel: "Run deep UI check",
98
+ sendPrompt: true
99
+ });
100
+ const AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF = codexHandoff({
262
101
  promptActionLabel: "Run automated checks",
263
- responseContract: JSKIT_STEP_RESULT_CONTRACT
102
+ sendPrompt: true
264
103
  });
265
- const BLUEPRINT_CODEX_HANDOFF = codexHandoff([], {
266
- autoInject: true,
104
+ const BLUEPRINT_CODEX_HANDOFF = codexHandoff({
267
105
  promptActionLabel: "Update blueprint",
268
- responseContract: JSKIT_STEP_RESULT_CONTRACT
106
+ sendPrompt: true
107
+ });
108
+ const PR_FILE_CODEX_HANDOFF = codexHandoff({
109
+ promptActionLabel: "Create PR file",
110
+ sendPrompt: true
269
111
  });
270
- const PR_MERGE_PREP_CODEX_HANDOFF = codexHandoff([], {
271
- autoInject: true,
272
- promptActionLabel: "Get Codex ready to merge PR",
112
+ const PR_MERGE_PREP_CODEX_HANDOFF = codexHandoff({
113
+ promptActionLabel: "Prepare PR merge",
273
114
  promptWaitingText: "Codex is preparing the PR for merge. Continue only when you decide the PR is ready.",
274
- responseContract: null
115
+ sendPrompt: true
275
116
  });
276
117
 
277
118
  function defineStep({
@@ -317,29 +158,25 @@ function defineStep({
317
158
  }
318
159
 
319
160
  const STEP_DEFINITIONS = Object.freeze([
320
- defineStep({
321
- buttonLabel: "Create session",
322
- description: "JSKIT creates the filesystem-backed session record and initial receipt.",
323
- id: "session_created",
324
- label: "Session created"
325
- }),
326
161
  defineStep({
327
162
  buttonLabel: "Create worktree",
328
163
  description: "JSKIT creates the isolated Git branch and session worktree where Codex will work.",
329
164
  id: "worktree_created",
330
- label: "Worktree created",
165
+ label: "Create worktree",
331
166
  preconditions: ["session_exists", "git_repository", "git_current_branch"]
332
167
  }),
333
168
  defineStep({
334
169
  buttonLabel: "Install dependencies",
335
170
  description: "JSKIT installs Node dependencies inside the session worktree before Codex starts.",
336
171
  id: "dependencies_installed",
337
- label: "Dependencies installed",
172
+ label: "Install dependencies",
338
173
  preconditions: ["session_exists", "worktree_exists"]
339
174
  }),
340
175
  defineStep({
341
- buttonLabel: "Set initial prompt",
342
- description: "User describes the requested change; JSKIT records it and prepares the Codex issue-drafting prompt.",
176
+ buttonLabel: "Define issue",
177
+ description: "User describes the requested change; Codex helps scope and define the issue in the terminal.",
178
+ displayGroupId: "define_create_issue",
179
+ displayGroupLabel: "Define issue and create file",
343
180
  id: "issue_prompt_rendered",
344
181
  input: Object.freeze({
345
182
  label: "What should change?",
@@ -350,103 +187,73 @@ const STEP_DEFINITIONS = Object.freeze([
350
187
  type: "text"
351
188
  }),
352
189
  kind: "human_input",
353
- label: "Initial issue prompt",
354
- nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --prompt "<what should change>"`,
190
+ label: "Define issue",
191
+ nextCommandTemplate: DEFAULT_NEXT_COMMAND_TEMPLATE,
355
192
  preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"]
356
193
  }),
357
194
  defineStep({
358
- buttonLabel: "Finalise issue",
359
- codex: codexHandoff([
360
- ISSUE_TITLE_OUTPUT,
361
- ISSUE_TEXT_OUTPUT
362
- ], {
363
- autoInject: true,
364
- promptActionLabel: "Get Codex to create issue text",
365
- promptIntroText: "Codex will create a comprehensive issue."
366
- }),
367
- description: "Codex drafts the issue title and body; user reviews or edits them; JSKIT saves the approved draft.",
368
- id: "issue_drafted",
369
- input: ISSUE_DRAFT_INPUT,
370
- kind: "codex_output",
371
- label: "Issue drafted",
372
- nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --issue -`,
373
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"]
374
- }),
375
- defineStep({
376
- buttonLabel: "Create issue",
377
- description: "JSKIT creates the GitHub issue from the approved draft and records the issue URL.",
195
+ buttonLabel: "Create issue file",
196
+ description: "JSKIT renders the issue-file prompt; Codex writes issue.md and issue_title for review.",
197
+ displayGroupId: "define_create_issue",
198
+ displayGroupLabel: "Define issue and create file",
378
199
  id: "issue_created",
379
- label: "Issue created",
380
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "github_auth", "github_origin"],
200
+ label: "Create issue file",
201
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"],
381
202
  requiresExplicitRun: false
382
203
  }),
383
204
  defineStep({
384
- buttonLabel: "Save issue details",
385
- codex: ISSUE_DETAILS_CODEX_HANDOFF,
386
- description: "Codex finalises with user issue details and classification; user reviews or edits final outcome; JSKIT saves the confirmed details.",
387
- displayGroupId: "issue_details",
388
- displayGroupLabel: "Get issue details",
389
- id: "issue_details_gathered",
390
- input: ISSUE_DETAILS_INPUT,
391
- kind: "codex_output",
392
- label: "Issue details gathered",
393
- nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --issue-details -`,
394
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists"]
205
+ buttonLabel: "Create issue on GH",
206
+ description: "JSKIT creates the GitHub issue from the reviewed issue files and records the issue metadata.",
207
+ id: "issue_submitted",
208
+ label: "Edit and submit issue",
209
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists"],
210
+ requiresExplicitRun: false
395
211
  }),
396
212
  defineStep({
397
- buttonLabel: "Save plan",
398
- codex: codexHandoff(PLAN_OUTPUT, {
399
- autoInject: true,
400
- promptActionLabel: "Get Codex to create plan",
401
- promptIntroText: "Codex will create an implementation plan based on the issue."
402
- }),
403
- description: "Codex writes an implementation plan for the active cycle; cycle 001 plans from the issue, later cycles plan from user rework notes.",
213
+ buttonLabel: "Make plan",
214
+ codex: PLAN_CODEX_HANDOFF,
215
+ description: "Codex writes the plan in the terminal; JSKIT records it when the user continues.",
404
216
  id: "plan_made",
405
- input: PLAN_INPUT,
406
- kind: "codex_output",
407
- label: "Plan made",
408
- nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --plan -`,
409
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists", "issue_details_exists", "issue_metadata_exists", "active_cycle_exists"]
217
+ kind: "codex_prompt",
218
+ label: "Make plan",
219
+ nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} next`,
220
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists"]
410
221
  }),
411
222
  defineStep({
412
- buttonLabel: "Get Codex to execute plan",
223
+ buttonLabel: "Execute plan",
413
224
  codex: PLAN_EXECUTION_CODEX_HANDOFF,
414
- description: "JSKIT sends the active cycle plan to Codex; Codex implements it; the user advances after reviewing completion.",
225
+ description: "JSKIT sends the plan to Codex; Codex implements it; the user advances after reviewing completion.",
415
226
  id: "plan_executed",
416
227
  kind: "codex_prompt",
417
- label: "Plan executed",
418
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists", "issue_details_exists", "issue_metadata_exists", "active_cycle_exists", "plan_text_exists"]
228
+ label: "Execute plan",
229
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists"]
419
230
  }),
420
231
  defineStep({
421
- buttonLabel: "Run Deep UI check",
232
+ buttonLabel: "Run deep UI check",
422
233
  codex: DEEP_UI_CHECK_CODEX_HANDOFF,
423
- description: "JSKIT asks Codex for a focused UI quality pass when the issue affects UI, or records a skip receipt when it does not.",
234
+ description: "JSKIT can ask Codex for a focused UI quality pass; use Next to continue without one.",
424
235
  id: "deep_ui_check_run",
425
236
  kind: "codex_prompt",
426
- label: "Deep UI check run",
427
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists"]
237
+ label: "Run deep UI check",
238
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"]
428
239
  }),
429
240
  defineStep({
430
241
  buttonLabel: "Run deslop",
431
242
  codex: REVIEW_EXECUTION_CODEX_HANDOFF,
432
- description: "JSKIT sends the current implementation to Codex for a review/deslop pass; Codex reports findings and applies the selected cleanup.",
433
- displayGroupId: "review_deslop",
434
- displayGroupLabel: "Review/deslop",
243
+ description: "JSKIT sends the current implementation to Codex for a review/deslop pass; the user decides whether to resolve findings, run deslop again, or continue.",
435
244
  id: "review_prompt_rendered",
436
245
  kind: "codex_prompt",
437
- label: "Review/deslop",
438
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"]
246
+ label: "Run deslop",
247
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "deep_ui_check_satisfied"]
439
248
  }),
440
249
  defineStep({
441
- buttonLabel: "I am done",
442
- description: "User confirms the review/deslop loop is done; JSKIT records the loop result without committing yet.",
443
- displayGroupId: "review_deslop",
444
- displayGroupLabel: "Review/deslop",
250
+ buttonLabel: "Accept review/deslop",
251
+ description: "User chooses whether to resolve the last deslop result, run deslop again, or continue.",
445
252
  id: "review_changes_accepted",
446
253
  kind: "user_check",
447
- label: "Review/deslop",
254
+ label: "Accept review/deslop",
448
255
  nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --review-findings-remaining false`,
449
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"],
256
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "deep_ui_check_satisfied"],
450
257
  submitOptions: Object.freeze({
451
258
  reviewFindingsRemaining: false
452
259
  })
@@ -454,21 +261,21 @@ const STEP_DEFINITIONS = Object.freeze([
454
261
  defineStep({
455
262
  buttonLabel: "Run automated checks",
456
263
  codex: AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF,
457
- description: "JSKIT asks Codex to run the official verification command in the worktree, fix failures, and report the final passing result.",
264
+ description: "JSKIT can ask Codex to run the official verification command in the worktree; use Next to continue without one.",
458
265
  id: "automated_checks_run",
459
266
  kind: "codex_prompt",
460
- label: "Automated checks",
461
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"]
267
+ label: "Run automated checks",
268
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "deep_ui_check_satisfied"]
462
269
  }),
463
270
  defineStep({
464
- buttonLabel: "Save user check",
465
- description: "User manually checks the result; JSKIT records pass or collects rework notes for another plan cycle.",
271
+ buttonLabel: "Complete user check",
272
+ description: "User manually checks the result; if it fails, rewind to the step that should be redone.",
466
273
  id: "user_check_completed",
467
274
  input: USER_CHECK_INPUT,
468
275
  kind: "user_check",
469
- label: "User check",
276
+ label: "Complete user check",
470
277
  nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --user-check passed`,
471
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied"],
278
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "automated_checks_passed", "deep_ui_check_satisfied"],
472
279
  utilityActions: Object.freeze([
473
280
  Object.freeze({
474
281
  id: "session_app_test",
@@ -477,82 +284,58 @@ const STEP_DEFINITIONS = Object.freeze([
477
284
  })
478
285
  ])
479
286
  }),
480
- defineStep({
481
- buttonLabel: "Commit accepted changes",
482
- description: "JSKIT commits the user-accepted session changes in the session worktree.",
483
- id: "changes_committed",
484
- label: "Changes committed",
485
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "issue_url_exists", "github_auth", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied", "active_cycle_user_check_passed"]
486
- }),
487
287
  defineStep({
488
288
  buttonLabel: "Update blueprint",
489
289
  codex: BLUEPRINT_CODEX_HANDOFF,
490
- description: "JSKIT asks Codex to update durable app memory from the accepted work; Codex edits .jskit/APP_BLUEPRINT.md; JSKIT records and commits the update.",
290
+ description: "JSKIT asks Codex to update durable app memory from the accepted work; Codex edits .jskit/APP_BLUEPRINT.md; JSKIT records the update for the accepted-work commit.",
491
291
  id: "blueprint_updated",
492
292
  kind: "codex_prompt",
493
- label: "Blueprint updated",
494
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied", "active_cycle_user_check_passed", "accepted_changes_committed"]
293
+ label: "Update blueprint",
294
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "automated_checks_passed", "deep_ui_check_satisfied", "user_check_passed"]
495
295
  }),
496
296
  defineStep({
497
- buttonLabel: "Create final report",
498
- description: "JSKIT creates the deterministic final session report and comments it on the GitHub issue.",
297
+ buttonLabel: "Commit changes",
298
+ description: "JSKIT commits the accepted session changes, including durable app memory updates, in the session worktree.",
299
+ id: "changes_committed",
300
+ label: "Commit changes",
301
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_url_exists", "github_auth", "automated_checks_passed", "deep_ui_check_satisfied", "user_check_passed", "blueprint_update_satisfied"]
302
+ }),
303
+ defineStep({
304
+ buttonLabel: "Create PR file",
305
+ codex: PR_FILE_CODEX_HANDOFF,
306
+ description: "JSKIT renders the PR-file prompt; Codex writes pull_request.md for review.",
499
307
  id: "final_report_created",
500
- label: "Final report created",
501
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied", "active_cycle_user_check_passed", "accepted_changes_committed", "blueprint_update_satisfied"]
308
+ kind: "codex_prompt",
309
+ label: "Create PR file",
310
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "automated_checks_passed", "deep_ui_check_satisfied", "user_check_passed", "blueprint_update_satisfied", "accepted_changes_committed"]
502
311
  }),
503
312
  defineStep({
504
- buttonLabel: "Push branch and create PR",
505
- description: "JSKIT pushes the session branch to origin, creates or reuses the GitHub pull request, and records the PR URL.",
313
+ buttonLabel: "Create PR on GH",
314
+ description: "JSKIT creates the GitHub pull request from the reviewed pull_request.md and records the PR URL.",
506
315
  id: "pr_created",
507
- label: "Branch pushed, PR created",
508
- preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied", "active_cycle_user_check_passed", "accepted_changes_committed", "blueprint_update_satisfied", "final_report_exists"]
316
+ label: "Edit and create PR",
317
+ preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "automated_checks_passed", "deep_ui_check_satisfied", "user_check_passed", "accepted_changes_committed", "blueprint_update_satisfied", "pull_request_file_exists"]
509
318
  }),
510
319
  defineStep({
511
- buttonLabel: "Continue to merge",
320
+ buttonLabel: "Merge",
512
321
  codex: PR_MERGE_PREP_CODEX_HANDOFF,
513
- description: "User can ask Codex to prepare the pull request for merge, then explicitly continue to the merge decision.",
322
+ description: "Prepare the pull request for merge, merge it, or use Next to continue without merging.",
514
323
  id: "pr_merge_prepared",
515
- label: "PR merge prepared",
516
- preconditions: ["session_exists", "pr_url_exists", "worktree_exists"],
517
- requiresExplicitRun: true,
518
- submitOptions: Object.freeze({
519
- continueToMerge: true
520
- }),
521
- utilityActions: Object.freeze([
522
- Object.freeze({
523
- id: "prepare_pr_merge",
524
- kind: "codex_prompt",
525
- label: "Get Codex ready to merge PR",
526
- submitOptions: Object.freeze({
527
- prepareMerge: true
528
- })
529
- })
530
- ])
531
- }),
532
- defineStep({
533
- buttonLabel: "Merge PR",
534
- description: "User chooses whether JSKIT merges the pull request or skips merge; JSKIT records the PR outcome.",
535
- id: "pr_finalized",
536
- label: "PR finalized",
537
- preconditions: ["session_exists", "pr_url_exists", "worktree_exists"],
538
- requiresExplicitRun: true,
539
- submitOptions: Object.freeze({
540
- mergePr: true
541
- })
324
+ label: "Merge PR",
325
+ preconditions: ["session_exists", "worktree_exists"]
542
326
  }),
543
327
  defineStep({
544
328
  buttonLabel: "Sync main checkout",
545
- description: "JSKIT fast-forwards the main checkout after a merged PR, or records an explicit skip before cleanup.",
329
+ description: "JSKIT fast-forwards the main checkout after a merged PR. If the PR was not merged, use Next to record that no sync was needed.",
546
330
  id: "main_checkout_synced",
547
- label: "Main checkout synced",
548
- preconditions: ["session_exists", "worktree_exists"],
549
- requiresExplicitRun: true
331
+ label: "Sync main checkout",
332
+ preconditions: ["session_exists", "worktree_exists"]
550
333
  }),
551
334
  defineStep({
552
- buttonLabel: "Finish session",
553
- description: "JSKIT removes the session worktree, writes the final receipt, and archives the completed session.",
335
+ buttonLabel: "Finish",
336
+ description: "Congratulations! Finish the session by removing the session worktree and archiving the completed session.",
554
337
  id: "session_finished",
555
- label: "Worktree removed, session finished",
338
+ label: "Congratulations!",
556
339
  preconditions: ["session_exists", "main_checkout_sync_satisfied"]
557
340
  })
558
341
  ]);
@@ -560,19 +343,9 @@ const STEP_DEFINITIONS = Object.freeze([
560
343
  const STEP_IDS = Object.freeze(STEP_DEFINITIONS.map((step) => step.id));
561
344
  const STEP_LABEL_BY_ID = Object.freeze(Object.fromEntries(STEP_DEFINITIONS.map((step) => [step.id, step.label])));
562
345
  const STEP_DEFINITION_BY_ID = Object.freeze(Object.fromEntries(STEP_DEFINITIONS.map((step) => [step.id, step])));
563
- const CYCLE_STEP_IDS = Object.freeze([
564
- "plan_made",
565
- "plan_executed",
566
- "deep_ui_check_run",
567
- "review_prompt_rendered",
568
- "review_changes_accepted",
569
- "automated_checks_run",
570
- "user_check_completed"
571
- ]);
346
+ const CYCLE_STEP_IDS = Object.freeze([]);
572
347
  const STEP_PRECONDITION_NAMES = Object.freeze(Object.fromEntries(
573
- STEP_DEFINITIONS
574
- .filter((step) => step.id !== "session_created")
575
- .map((step) => [step.id, step.preconditions])
348
+ STEP_DEFINITIONS.map((step) => [step.id, step.preconditions])
576
349
  ));
577
350
 
578
351
  export {
@@ -580,6 +353,7 @@ export {
580
353
  SESSION_ID_PATTERN,
581
354
  SESSION_STATUS,
582
355
  SESSION_WORKFLOW_VERSION,
356
+ DEPENDENCIES_INSTALL_RESULT_FILE,
583
357
  REVIEW_PASS_LIMIT,
584
358
  CYCLE_STEP_IDS,
585
359
  STEP_DEFINITION_BY_ID,
@@ -587,14 +361,17 @@ export {
587
361
  STEP_IDS,
588
362
  STEP_LABEL_BY_ID,
589
363
  STEP_PRECONDITION_NAMES,
590
- ISSUE_DETAILS_CODEX_HANDOFF,
364
+ ISSUE_DEFINITION_CODEX_HANDOFF,
365
+ ISSUE_FILE_CODEX_HANDOFF,
366
+ PLAN_CODEX_HANDOFF,
591
367
  PLAN_EXECUTION_CODEX_HANDOFF,
592
368
  REVIEW_EXECUTION_CODEX_HANDOFF,
369
+ RESOLVE_DESLOP_CODEX_HANDOFF,
593
370
  DEEP_UI_CHECK_CODEX_HANDOFF,
594
371
  AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF,
595
372
  BLUEPRINT_CODEX_HANDOFF,
373
+ PR_FILE_CODEX_HANDOFF,
596
374
  PR_MERGE_PREP_CODEX_HANDOFF,
597
375
  JSKIT_CLI_SHELL_COMMAND,
598
- JSKIT_CLI_SHELL_RULE,
599
376
  SESSION_STATE_RELATIVE_PATH
600
377
  };