@jskit-ai/jskit-cli 0.2.81 → 0.2.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -4
- package/src/server/appBlueprint.js +1 -1
- package/src/server/commandHandlers/helperMap.js +104 -0
- package/src/server/commandHandlers/session.js +127 -3
- package/src/server/commandHandlers/show.js +169 -34
- package/src/server/core/argParser.js +8 -0
- package/src/server/core/commandCatalog.js +60 -2
- package/src/server/core/createCommandHandlers.js +4 -1
- package/src/server/helperMap.js +463 -0
- package/src/server/helperMapPaths.js +7 -0
- package/src/server/sessionRuntime/appReadiness.js +55 -0
- package/src/server/sessionRuntime/constants.js +326 -87
- package/src/server/sessionRuntime/preconditions.js +382 -5
- package/src/server/sessionRuntime/promptRenderer.js +15 -2
- package/src/server/sessionRuntime/prompts/automated_checks.md +42 -0
- package/src/server/sessionRuntime/prompts/deep_ui_check.md +53 -0
- package/src/server/sessionRuntime/prompts/execute_plan.md +33 -7
- package/src/server/sessionRuntime/prompts/final_comment.md +3 -1
- package/src/server/sessionRuntime/prompts/issue_details.md +46 -0
- package/src/server/sessionRuntime/prompts/new_issue.md +15 -2
- package/src/server/sessionRuntime/prompts/plan_issue.md +40 -9
- package/src/server/sessionRuntime/prompts/resolve_deslop_findings.md +16 -0
- package/src/server/sessionRuntime/prompts/review_changes.md +46 -5
- package/src/server/sessionRuntime/prompts/update_blueprint.md +38 -0
- package/src/server/sessionRuntime/prompts/user_check.md +15 -1
- package/src/server/sessionRuntime/responses.js +860 -62
- package/src/server/sessionRuntime.js +1699 -140
- package/src/server/sessionRuntime/prompts/doctor_failure.md +0 -26
|
@@ -13,7 +13,19 @@ 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";
|
|
17
|
+
const REVIEW_PASS_LIMIT = 0;
|
|
16
18
|
const PROMPT_DIRECTORY = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "prompts");
|
|
19
|
+
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`;
|
|
17
29
|
|
|
18
30
|
const INPUT_NONE = Object.freeze({ type: "none" });
|
|
19
31
|
const ISSUE_TITLE_INPUT = Object.freeze({
|
|
@@ -72,6 +84,50 @@ const PLAN_OUTPUT = Object.freeze({
|
|
|
72
84
|
multiline: true,
|
|
73
85
|
required: true
|
|
74
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
|
+
});
|
|
75
131
|
const USER_CHECK_INPUT = Object.freeze({
|
|
76
132
|
label: "User check result",
|
|
77
133
|
name: "userCheck",
|
|
@@ -82,28 +138,130 @@ const USER_CHECK_INPUT = Object.freeze({
|
|
|
82
138
|
required: true,
|
|
83
139
|
type: "choice"
|
|
84
140
|
});
|
|
85
|
-
|
|
141
|
+
|
|
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 DESLOP_RESULT_CONTRACT = Object.freeze({
|
|
151
|
+
autoResolvePriorities: Object.freeze(["high", "medium"]),
|
|
152
|
+
completionBehavior: "deslop_loop",
|
|
153
|
+
kind: "deslop_result",
|
|
154
|
+
marker: "deslop_result",
|
|
155
|
+
missingMarkerBehavior: "resend",
|
|
156
|
+
required: true,
|
|
157
|
+
resolvePrompt: Object.freeze({
|
|
158
|
+
findingsPlaceholder: "{{findings}}",
|
|
159
|
+
marker: "resolve_deslop_findings",
|
|
160
|
+
templateFile: "resolve_deslop_findings.md"
|
|
161
|
+
})
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
function fieldResponseContract(outputDefinitions) {
|
|
165
|
+
const fields = outputDefinitions
|
|
166
|
+
.filter((output) => output?.field && output?.extract)
|
|
167
|
+
.map((output) => Object.freeze({
|
|
168
|
+
extract: output.extract,
|
|
169
|
+
field: output.field,
|
|
170
|
+
formatHint: output.formatHint || "",
|
|
171
|
+
label: output.label || output.field,
|
|
172
|
+
manualEntry: true,
|
|
173
|
+
...(output.multiline === true ? { multiline: true } : {}),
|
|
174
|
+
...(Array.isArray(output.options) ? { options: Object.freeze(output.options.map((option) => Object.freeze({ ...option }))) } : {}),
|
|
175
|
+
required: output.required !== false
|
|
176
|
+
}));
|
|
177
|
+
return Object.freeze({
|
|
178
|
+
fields: Object.freeze(fields),
|
|
179
|
+
kind: "fields",
|
|
180
|
+
missingMarkerBehavior: "manual_or_resend",
|
|
181
|
+
required: fields.some((field) => field.required)
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function codexHandoff(outputDefinition, {
|
|
86
186
|
autoInject = false,
|
|
87
|
-
promptActionLabel = ""
|
|
187
|
+
promptActionLabel = "",
|
|
188
|
+
promptIntroText = "",
|
|
189
|
+
promptWaitingText = "",
|
|
190
|
+
responseContract = undefined
|
|
88
191
|
} = {}) {
|
|
89
|
-
const
|
|
192
|
+
const outputDefinitions = Object.freeze(Array.isArray(outputDefinition) ? [...outputDefinition] : [outputDefinition]);
|
|
193
|
+
const resolvedResponseContract = responseContract === undefined
|
|
194
|
+
? fieldResponseContract(outputDefinitions)
|
|
195
|
+
: responseContract;
|
|
90
196
|
return Object.freeze({
|
|
91
197
|
...(autoInject ? { autoInject: true } : {}),
|
|
92
|
-
expectedOutput: expectedOutputs[expectedOutputs.length - 1] || null,
|
|
93
|
-
expectedOutputs,
|
|
94
198
|
mode: "inject_prompt",
|
|
95
199
|
promptField: "prompt",
|
|
96
|
-
...(promptActionLabel ? { promptActionLabel } : {})
|
|
200
|
+
...(promptActionLabel ? { promptActionLabel } : {}),
|
|
201
|
+
...(promptIntroText ? { promptIntroText } : {}),
|
|
202
|
+
...(promptWaitingText ? { promptWaitingText } : {}),
|
|
203
|
+
...(resolvedResponseContract ? { responseContract: resolvedResponseContract } : {})
|
|
97
204
|
});
|
|
98
205
|
}
|
|
99
206
|
|
|
207
|
+
function stepAutomationFor({
|
|
208
|
+
codex = undefined,
|
|
209
|
+
id,
|
|
210
|
+
kind,
|
|
211
|
+
requiresExplicitRun = false
|
|
212
|
+
}) {
|
|
213
|
+
if (requiresExplicitRun) {
|
|
214
|
+
return Object.freeze({ mode: "manual" });
|
|
215
|
+
}
|
|
216
|
+
if (id === "dependencies_installed") {
|
|
217
|
+
return Object.freeze({ mode: "terminal" });
|
|
218
|
+
}
|
|
219
|
+
if (kind === "automatic") {
|
|
220
|
+
return Object.freeze({ mode: "immediate" });
|
|
221
|
+
}
|
|
222
|
+
if (kind === "codex_prompt" && codex?.autoInject === true) {
|
|
223
|
+
return Object.freeze({ mode: "codex_prompt" });
|
|
224
|
+
}
|
|
225
|
+
if (kind === "codex_output" && codex?.autoInject === true) {
|
|
226
|
+
return Object.freeze({ mode: "codex_output_prompt" });
|
|
227
|
+
}
|
|
228
|
+
return Object.freeze({ mode: "manual" });
|
|
229
|
+
}
|
|
230
|
+
|
|
100
231
|
const PLAN_EXECUTION_CODEX_HANDOFF = codexHandoff([], {
|
|
101
232
|
autoInject: true,
|
|
102
|
-
promptActionLabel: "
|
|
233
|
+
promptActionLabel: "Get Codex to execute plan",
|
|
234
|
+
responseContract: JSKIT_STEP_RESULT_CONTRACT
|
|
235
|
+
});
|
|
236
|
+
const ISSUE_DETAILS_CODEX_HANDOFF = codexHandoff([
|
|
237
|
+
ISSUE_CATEGORY_OUTPUT,
|
|
238
|
+
UI_IMPACT_OUTPUT,
|
|
239
|
+
ISSUE_DETAILS_OUTPUT
|
|
240
|
+
], {
|
|
241
|
+
autoInject: true,
|
|
242
|
+
promptActionLabel: "Start details conversation",
|
|
243
|
+
promptIntroText: "Codex will gather issue details and classify the issue.",
|
|
244
|
+
promptWaitingText: "Please respond and finalise things with Codex"
|
|
103
245
|
});
|
|
104
246
|
const REVIEW_EXECUTION_CODEX_HANDOFF = codexHandoff([], {
|
|
105
247
|
autoInject: true,
|
|
106
|
-
promptActionLabel: "
|
|
248
|
+
promptActionLabel: "Run deslop",
|
|
249
|
+
responseContract: DESLOP_RESULT_CONTRACT
|
|
250
|
+
});
|
|
251
|
+
const DEEP_UI_CHECK_CODEX_HANDOFF = codexHandoff([], {
|
|
252
|
+
autoInject: true,
|
|
253
|
+
promptActionLabel: "Run Deep UI check",
|
|
254
|
+
responseContract: JSKIT_STEP_RESULT_CONTRACT
|
|
255
|
+
});
|
|
256
|
+
const AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF = codexHandoff([], {
|
|
257
|
+
autoInject: true,
|
|
258
|
+
promptActionLabel: "Run automated checks",
|
|
259
|
+
responseContract: JSKIT_STEP_RESULT_CONTRACT
|
|
260
|
+
});
|
|
261
|
+
const BLUEPRINT_CODEX_HANDOFF = codexHandoff([], {
|
|
262
|
+
autoInject: true,
|
|
263
|
+
promptActionLabel: "Update blueprint",
|
|
264
|
+
responseContract: JSKIT_STEP_RESULT_CONTRACT
|
|
107
265
|
});
|
|
108
266
|
|
|
109
267
|
function defineStep({
|
|
@@ -114,20 +272,36 @@ function defineStep({
|
|
|
114
272
|
input = INPUT_NONE,
|
|
115
273
|
kind = "automatic",
|
|
116
274
|
label,
|
|
117
|
-
nextCommandTemplate =
|
|
275
|
+
nextCommandTemplate = DEFAULT_NEXT_COMMAND_TEMPLATE,
|
|
118
276
|
preconditions = [],
|
|
119
|
-
|
|
277
|
+
requiresExplicitRun = false,
|
|
278
|
+
submitOptions = {},
|
|
279
|
+
automation = undefined,
|
|
280
|
+
utilityActions = [],
|
|
281
|
+
displayGroupId = "",
|
|
282
|
+
displayGroupLabel = ""
|
|
120
283
|
}) {
|
|
284
|
+
const resolvedAutomation = automation || stepAutomationFor({
|
|
285
|
+
codex,
|
|
286
|
+
id,
|
|
287
|
+
kind,
|
|
288
|
+
requiresExplicitRun
|
|
289
|
+
});
|
|
121
290
|
return Object.freeze({
|
|
291
|
+
automation: Object.freeze({ ...resolvedAutomation }),
|
|
122
292
|
buttonLabel,
|
|
123
293
|
codex,
|
|
124
294
|
description,
|
|
295
|
+
displayGroupId,
|
|
296
|
+
displayGroupLabel,
|
|
125
297
|
id,
|
|
126
298
|
input,
|
|
127
299
|
kind,
|
|
128
300
|
label,
|
|
129
301
|
nextCommandTemplate,
|
|
130
302
|
preconditions: Object.freeze([...preconditions]),
|
|
303
|
+
requiresExplicitRun,
|
|
304
|
+
submitOptions: Object.freeze({ ...submitOptions }),
|
|
131
305
|
utilityActions: Object.freeze([...utilityActions])
|
|
132
306
|
});
|
|
133
307
|
}
|
|
@@ -135,27 +309,27 @@ function defineStep({
|
|
|
135
309
|
const STEP_DEFINITIONS = Object.freeze([
|
|
136
310
|
defineStep({
|
|
137
311
|
buttonLabel: "Create session",
|
|
138
|
-
description: "
|
|
312
|
+
description: "JSKIT creates the filesystem-backed session record and initial receipt.",
|
|
139
313
|
id: "session_created",
|
|
140
314
|
label: "Session created"
|
|
141
315
|
}),
|
|
142
316
|
defineStep({
|
|
143
317
|
buttonLabel: "Create worktree",
|
|
144
|
-
description: "
|
|
318
|
+
description: "JSKIT creates the isolated Git branch and session worktree where Codex will work.",
|
|
145
319
|
id: "worktree_created",
|
|
146
320
|
label: "Worktree created",
|
|
147
321
|
preconditions: ["session_exists", "git_repository", "git_current_branch"]
|
|
148
322
|
}),
|
|
149
323
|
defineStep({
|
|
150
324
|
buttonLabel: "Install dependencies",
|
|
151
|
-
description: "
|
|
325
|
+
description: "JSKIT installs Node dependencies inside the session worktree before Codex starts.",
|
|
152
326
|
id: "dependencies_installed",
|
|
153
327
|
label: "Dependencies installed",
|
|
154
328
|
preconditions: ["session_exists", "worktree_exists"]
|
|
155
329
|
}),
|
|
156
330
|
defineStep({
|
|
157
|
-
buttonLabel: "
|
|
158
|
-
description: "
|
|
331
|
+
buttonLabel: "Set initial prompt",
|
|
332
|
+
description: "User describes the requested change; JSKIT records it and prepares the Codex issue-drafting prompt.",
|
|
159
333
|
id: "issue_prompt_rendered",
|
|
160
334
|
input: Object.freeze({
|
|
161
335
|
label: "What should change?",
|
|
@@ -167,129 +341,176 @@ const STEP_DEFINITIONS = Object.freeze([
|
|
|
167
341
|
}),
|
|
168
342
|
kind: "human_input",
|
|
169
343
|
label: "Initial issue prompt",
|
|
170
|
-
nextCommandTemplate:
|
|
171
|
-
preconditions: ["session_exists"]
|
|
344
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --prompt "<what should change>"`,
|
|
345
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"]
|
|
172
346
|
}),
|
|
173
347
|
defineStep({
|
|
174
|
-
buttonLabel: "
|
|
348
|
+
buttonLabel: "Finalise issue",
|
|
175
349
|
codex: codexHandoff([
|
|
176
350
|
ISSUE_TITLE_OUTPUT,
|
|
177
351
|
ISSUE_TEXT_OUTPUT
|
|
178
|
-
]
|
|
179
|
-
|
|
352
|
+
], {
|
|
353
|
+
autoInject: true,
|
|
354
|
+
promptActionLabel: "Get Codex to create issue text",
|
|
355
|
+
promptIntroText: "Codex will create a comprehensive issue."
|
|
356
|
+
}),
|
|
357
|
+
description: "Codex drafts the issue title and body; user reviews or edits them; JSKIT saves the approved draft.",
|
|
180
358
|
id: "issue_drafted",
|
|
181
359
|
input: ISSUE_DRAFT_INPUT,
|
|
182
360
|
kind: "codex_output",
|
|
183
361
|
label: "Issue drafted",
|
|
184
|
-
nextCommandTemplate:
|
|
185
|
-
preconditions: ["session_exists"]
|
|
362
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --issue -`,
|
|
363
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app"]
|
|
186
364
|
}),
|
|
187
365
|
defineStep({
|
|
188
|
-
buttonLabel: "Create
|
|
189
|
-
description: "
|
|
366
|
+
buttonLabel: "Create issue",
|
|
367
|
+
description: "JSKIT creates the GitHub issue from the approved draft and records the issue URL.",
|
|
190
368
|
id: "issue_created",
|
|
191
369
|
label: "Issue created",
|
|
192
|
-
preconditions: ["session_exists", "issue_text_exists", "github_auth", "github_origin"]
|
|
370
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "github_auth", "github_origin"],
|
|
371
|
+
requiresExplicitRun: false
|
|
372
|
+
}),
|
|
373
|
+
defineStep({
|
|
374
|
+
buttonLabel: "Save issue details",
|
|
375
|
+
codex: ISSUE_DETAILS_CODEX_HANDOFF,
|
|
376
|
+
description: "Codex finalises with user issue details and classification; user reviews or edits final outcome; JSKIT saves the confirmed details.",
|
|
377
|
+
displayGroupId: "issue_details",
|
|
378
|
+
displayGroupLabel: "Get issue details",
|
|
379
|
+
id: "issue_details_gathered",
|
|
380
|
+
input: ISSUE_DETAILS_INPUT,
|
|
381
|
+
kind: "codex_output",
|
|
382
|
+
label: "Issue details gathered",
|
|
383
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --issue-details -`,
|
|
384
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_text_exists", "issue_url_exists"]
|
|
193
385
|
}),
|
|
194
386
|
defineStep({
|
|
195
|
-
buttonLabel: "
|
|
196
|
-
codex: codexHandoff(PLAN_OUTPUT
|
|
197
|
-
|
|
387
|
+
buttonLabel: "Save plan",
|
|
388
|
+
codex: codexHandoff(PLAN_OUTPUT, {
|
|
389
|
+
autoInject: true,
|
|
390
|
+
promptActionLabel: "Get Codex to create plan",
|
|
391
|
+
promptIntroText: "Codex will create an implementation plan based on the issue."
|
|
392
|
+
}),
|
|
393
|
+
description: "Codex writes an implementation plan for the active cycle; cycle 001 plans from the issue, later cycles plan from user rework notes.",
|
|
198
394
|
id: "plan_made",
|
|
199
395
|
input: PLAN_INPUT,
|
|
200
396
|
kind: "codex_output",
|
|
201
|
-
label: "Plan
|
|
202
|
-
nextCommandTemplate:
|
|
203
|
-
preconditions: ["session_exists", "issue_text_exists", "issue_url_exists", "
|
|
397
|
+
label: "Plan made",
|
|
398
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --plan -`,
|
|
399
|
+
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"]
|
|
204
400
|
}),
|
|
205
401
|
defineStep({
|
|
206
|
-
buttonLabel: "
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Object.freeze({
|
|
214
|
-
id: "session_diff",
|
|
215
|
-
kind: "diff",
|
|
216
|
-
label: "Review changes",
|
|
217
|
-
nextCommandTemplate: "jskit session {{session_id}} diff"
|
|
218
|
-
})
|
|
219
|
-
])
|
|
402
|
+
buttonLabel: "Get Codex to execute plan",
|
|
403
|
+
codex: PLAN_EXECUTION_CODEX_HANDOFF,
|
|
404
|
+
description: "JSKIT sends the active cycle plan to Codex; Codex implements it; Studio advances when Codex finishes.",
|
|
405
|
+
id: "plan_executed",
|
|
406
|
+
kind: "codex_prompt",
|
|
407
|
+
label: "Plan executed",
|
|
408
|
+
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"]
|
|
220
409
|
}),
|
|
221
410
|
defineStep({
|
|
222
|
-
buttonLabel: "
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
411
|
+
buttonLabel: "Run Deep UI check",
|
|
412
|
+
codex: DEEP_UI_CHECK_CODEX_HANDOFF,
|
|
413
|
+
description: "JSKIT asks Codex for a focused UI quality pass when the issue affects UI, or records a skip receipt when it does not.",
|
|
414
|
+
id: "deep_ui_check_run",
|
|
415
|
+
kind: "codex_prompt",
|
|
416
|
+
label: "Deep UI check run",
|
|
417
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists"]
|
|
227
418
|
}),
|
|
228
419
|
defineStep({
|
|
229
|
-
buttonLabel: "
|
|
230
|
-
|
|
420
|
+
buttonLabel: "Run deslop",
|
|
421
|
+
codex: REVIEW_EXECUTION_CODEX_HANDOFF,
|
|
422
|
+
description: "JSKIT sends the current implementation to Codex for a review/deslop pass; Codex reports findings and applies the selected cleanup.",
|
|
423
|
+
displayGroupId: "review_deslop",
|
|
424
|
+
displayGroupLabel: "Review/deslop",
|
|
231
425
|
id: "review_prompt_rendered",
|
|
232
426
|
kind: "codex_prompt",
|
|
233
|
-
label: "Review
|
|
234
|
-
preconditions: ["session_exists", "worktree_exists"]
|
|
427
|
+
label: "Review/deslop",
|
|
428
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"]
|
|
235
429
|
}),
|
|
236
430
|
defineStep({
|
|
237
|
-
buttonLabel: "
|
|
238
|
-
description: "
|
|
431
|
+
buttonLabel: "I am done",
|
|
432
|
+
description: "User confirms the review/deslop loop is done; JSKIT records the loop result without committing yet.",
|
|
433
|
+
displayGroupId: "review_deslop",
|
|
434
|
+
displayGroupLabel: "Review/deslop",
|
|
239
435
|
id: "review_changes_accepted",
|
|
240
436
|
kind: "user_check",
|
|
241
|
-
label: "Review
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
label: "Review changes",
|
|
248
|
-
nextCommandTemplate: "jskit session {{session_id}} diff"
|
|
249
|
-
})
|
|
250
|
-
])
|
|
437
|
+
label: "Review/deslop",
|
|
438
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --review-findings-remaining false`,
|
|
439
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"],
|
|
440
|
+
submitOptions: Object.freeze({
|
|
441
|
+
reviewFindingsRemaining: false
|
|
442
|
+
})
|
|
251
443
|
}),
|
|
252
444
|
defineStep({
|
|
253
|
-
buttonLabel: "
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
445
|
+
buttonLabel: "Run automated checks",
|
|
446
|
+
codex: AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF,
|
|
447
|
+
description: "JSKIT asks Codex to run the official verification command in the worktree, fix failures, and report the final passing result.",
|
|
448
|
+
id: "automated_checks_run",
|
|
449
|
+
kind: "codex_prompt",
|
|
450
|
+
label: "Automated checks",
|
|
451
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "deep_ui_check_satisfied"]
|
|
258
452
|
}),
|
|
259
453
|
defineStep({
|
|
260
454
|
buttonLabel: "Save user check",
|
|
261
|
-
description: "
|
|
455
|
+
description: "User manually checks the result; JSKIT records pass or collects rework notes for another plan cycle.",
|
|
262
456
|
id: "user_check_completed",
|
|
263
457
|
input: USER_CHECK_INPUT,
|
|
264
458
|
kind: "user_check",
|
|
265
459
|
label: "User check",
|
|
266
|
-
nextCommandTemplate:
|
|
267
|
-
preconditions: ["session_exists"]
|
|
460
|
+
nextCommandTemplate: `${JSKIT_CLI_SHELL_COMMAND} session {{session_id}} step --user-check passed`,
|
|
461
|
+
preconditions: ["session_exists", "worktree_exists", "dependencies_installed", "ready_jskit_app", "issue_metadata_exists", "active_cycle_exists", "automated_checks_passed", "deep_ui_check_satisfied"],
|
|
462
|
+
utilityActions: Object.freeze([
|
|
463
|
+
Object.freeze({
|
|
464
|
+
id: "session_app_test",
|
|
465
|
+
kind: "app_test",
|
|
466
|
+
label: "Test app"
|
|
467
|
+
})
|
|
468
|
+
])
|
|
268
469
|
}),
|
|
269
470
|
defineStep({
|
|
270
|
-
buttonLabel: "
|
|
271
|
-
description: "
|
|
272
|
-
id: "
|
|
273
|
-
label: "
|
|
274
|
-
preconditions: ["session_exists", "worktree_exists"]
|
|
471
|
+
buttonLabel: "Commit accepted changes",
|
|
472
|
+
description: "JSKIT commits the user-accepted session changes in the session worktree.",
|
|
473
|
+
id: "changes_committed",
|
|
474
|
+
label: "Changes committed",
|
|
475
|
+
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"]
|
|
476
|
+
}),
|
|
477
|
+
defineStep({
|
|
478
|
+
buttonLabel: "Update blueprint",
|
|
479
|
+
codex: BLUEPRINT_CODEX_HANDOFF,
|
|
480
|
+
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.",
|
|
481
|
+
id: "blueprint_updated",
|
|
482
|
+
kind: "codex_prompt",
|
|
483
|
+
label: "Blueprint updated",
|
|
484
|
+
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"]
|
|
485
|
+
}),
|
|
486
|
+
defineStep({
|
|
487
|
+
buttonLabel: "Create final report",
|
|
488
|
+
description: "JSKIT creates the deterministic final session report and comments it on the GitHub issue.",
|
|
489
|
+
id: "final_report_created",
|
|
490
|
+
label: "Final report created",
|
|
491
|
+
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"]
|
|
275
492
|
}),
|
|
276
493
|
defineStep({
|
|
277
494
|
buttonLabel: "Push branch and create PR",
|
|
278
|
-
description: "
|
|
495
|
+
description: "JSKIT pushes the session branch to origin, creates or reuses the GitHub pull request, and records the PR URL.",
|
|
279
496
|
id: "pr_created",
|
|
280
497
|
label: "Branch pushed, PR created",
|
|
281
|
-
preconditions: ["session_exists", "worktree_exists"]
|
|
498
|
+
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"]
|
|
282
499
|
}),
|
|
283
500
|
defineStep({
|
|
284
|
-
buttonLabel: "Merge PR
|
|
285
|
-
description: "
|
|
286
|
-
id: "
|
|
287
|
-
label: "PR
|
|
288
|
-
preconditions: ["session_exists", "pr_url_exists", "worktree_exists"]
|
|
501
|
+
buttonLabel: "Merge PR",
|
|
502
|
+
description: "User chooses whether JSKIT merges the pull request or finishes without merge; JSKIT then removes the session worktree.",
|
|
503
|
+
id: "pr_finalized",
|
|
504
|
+
label: "PR finalized, worktree removed",
|
|
505
|
+
preconditions: ["session_exists", "pr_url_exists", "worktree_exists"],
|
|
506
|
+
requiresExplicitRun: true,
|
|
507
|
+
submitOptions: Object.freeze({
|
|
508
|
+
mergePr: true
|
|
509
|
+
})
|
|
289
510
|
}),
|
|
290
511
|
defineStep({
|
|
291
512
|
buttonLabel: "Finish session",
|
|
292
|
-
description: "
|
|
513
|
+
description: "JSKIT writes the final receipt and archives the completed session.",
|
|
293
514
|
id: "session_finished",
|
|
294
515
|
label: "Session finished",
|
|
295
516
|
preconditions: ["session_exists"]
|
|
@@ -299,6 +520,15 @@ const STEP_DEFINITIONS = Object.freeze([
|
|
|
299
520
|
const STEP_IDS = Object.freeze(STEP_DEFINITIONS.map((step) => step.id));
|
|
300
521
|
const STEP_LABEL_BY_ID = Object.freeze(Object.fromEntries(STEP_DEFINITIONS.map((step) => [step.id, step.label])));
|
|
301
522
|
const STEP_DEFINITION_BY_ID = Object.freeze(Object.fromEntries(STEP_DEFINITIONS.map((step) => [step.id, step])));
|
|
523
|
+
const CYCLE_STEP_IDS = Object.freeze([
|
|
524
|
+
"plan_made",
|
|
525
|
+
"plan_executed",
|
|
526
|
+
"deep_ui_check_run",
|
|
527
|
+
"review_prompt_rendered",
|
|
528
|
+
"review_changes_accepted",
|
|
529
|
+
"automated_checks_run",
|
|
530
|
+
"user_check_completed"
|
|
531
|
+
]);
|
|
302
532
|
const STEP_PRECONDITION_NAMES = Object.freeze(Object.fromEntries(
|
|
303
533
|
STEP_DEFINITIONS
|
|
304
534
|
.filter((step) => step.id !== "session_created")
|
|
@@ -309,12 +539,21 @@ export {
|
|
|
309
539
|
PROMPT_DIRECTORY,
|
|
310
540
|
SESSION_ID_PATTERN,
|
|
311
541
|
SESSION_STATUS,
|
|
542
|
+
SESSION_WORKFLOW_VERSION,
|
|
543
|
+
REVIEW_PASS_LIMIT,
|
|
544
|
+
CYCLE_STEP_IDS,
|
|
312
545
|
STEP_DEFINITION_BY_ID,
|
|
313
546
|
STEP_DEFINITIONS,
|
|
314
547
|
STEP_IDS,
|
|
315
548
|
STEP_LABEL_BY_ID,
|
|
316
549
|
STEP_PRECONDITION_NAMES,
|
|
550
|
+
ISSUE_DETAILS_CODEX_HANDOFF,
|
|
317
551
|
PLAN_EXECUTION_CODEX_HANDOFF,
|
|
318
552
|
REVIEW_EXECUTION_CODEX_HANDOFF,
|
|
553
|
+
DEEP_UI_CHECK_CODEX_HANDOFF,
|
|
554
|
+
AUTOMATED_CHECK_REPAIR_CODEX_HANDOFF,
|
|
555
|
+
BLUEPRINT_CODEX_HANDOFF,
|
|
556
|
+
JSKIT_CLI_SHELL_COMMAND,
|
|
557
|
+
JSKIT_CLI_SHELL_RULE,
|
|
319
558
|
SESSION_STATE_RELATIVE_PATH
|
|
320
559
|
};
|