@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
@@ -10,7 +10,7 @@ function normalizeText(value) {
10
10
  return String(value || "").trim();
11
11
  }
12
12
 
13
- function timestampForReceipt(now = new Date()) {
13
+ function timestampForStepRecord(now = new Date()) {
14
14
  return now.toISOString();
15
15
  }
16
16
 
@@ -92,6 +92,6 @@ export {
92
92
  runCommand,
93
93
  runGit,
94
94
  runGitInWorktree,
95
- timestampForReceipt,
95
+ timestampForStepRecord,
96
96
  writeTextFile
97
97
  };
@@ -271,7 +271,7 @@ async function assertDependenciesInstalled(paths) {
271
271
  error: createError({
272
272
  code: "dependencies_not_installed",
273
273
  message: "Cannot start issue work until dependencies are installed in the session worktree.",
274
- repairCommand: jskitCommand(`session ${paths.sessionId} step`)
274
+ repairCommand: jskitCommand(`session ${paths.sessionId} run_npm_install`)
275
275
  }),
276
276
  precondition: createPrecondition({
277
277
  id: "dependencies_installed",
@@ -337,14 +337,16 @@ async function assertActiveCycleExists(paths) {
337
337
 
338
338
  async function assertActiveCycleUserCheckPassed(paths) {
339
339
  const activeCycle = await readTrimmedFile(path.join(paths.sessionRoot, "active_cycle"));
340
- const receiptPath = path.join(paths.sessionRoot, "steps", `cycle_${activeCycle}`, "user_check_completed");
341
- if (await pathExists(receiptPath)) {
340
+ if (
341
+ await pathExists(path.join(paths.sessionRoot, "steps", "user_check_completed")) ||
342
+ await pathExists(path.join(paths.sessionRoot, "steps", `cycle_${activeCycle || "001"}`, "user_check_completed"))
343
+ ) {
342
344
  return {
343
345
  ok: true,
344
346
  precondition: createPrecondition({
345
- id: "active_cycle_user_check_passed",
347
+ id: "user_check_passed",
346
348
  ok: true,
347
- message: "The active cycle user check has passed."
349
+ message: "The user check has passed."
348
350
  })
349
351
  };
350
352
  }
@@ -352,20 +354,24 @@ async function assertActiveCycleUserCheckPassed(paths) {
352
354
  ok: false,
353
355
  error: createError({
354
356
  code: "user_check_not_passed",
355
- message: "Finalization cannot continue until the active cycle user check has passed.",
357
+ message: "Finalization cannot continue until the user check has passed.",
356
358
  repairCommand: jskitCommand(`session ${paths.sessionId} step --user-check passed`)
357
359
  }),
358
360
  precondition: createPrecondition({
359
- id: "active_cycle_user_check_passed",
361
+ id: "user_check_passed",
360
362
  ok: false,
361
- message: "The active cycle user check has passed."
363
+ message: "The user check has passed."
362
364
  })
363
365
  };
364
366
  }
365
367
 
368
+ async function assertUserCheckPassed(paths) {
369
+ return assertActiveCycleUserCheckPassed(paths);
370
+ }
371
+
366
372
  async function assertAcceptedChangesCommitted(paths) {
367
- const receiptPath = path.join(paths.sessionRoot, "steps", "changes_committed");
368
- if (await pathExists(receiptPath)) {
373
+ const recordPath = path.join(paths.sessionRoot, "steps", "changes_committed");
374
+ if (await pathExists(recordPath)) {
369
375
  return {
370
376
  ok: true,
371
377
  precondition: createPrecondition({
@@ -379,7 +385,7 @@ async function assertAcceptedChangesCommitted(paths) {
379
385
  ok: false,
380
386
  error: createError({
381
387
  code: "accepted_changes_not_committed",
382
- message: "Accepted changes must be committed before app memory and finalization steps continue.",
388
+ message: "Accepted changes must be committed before finalization steps continue.",
383
389
  repairCommand: jskitCommand(`session ${paths.sessionId} step`)
384
390
  }),
385
391
  precondition: createPrecondition({
@@ -390,15 +396,17 @@ async function assertAcceptedChangesCommitted(paths) {
390
396
  };
391
397
  }
392
398
 
393
- async function assertActiveCycleStepReceipt(paths, {
399
+ async function assertActiveCycleStepRecord(paths, {
394
400
  code,
395
401
  id,
396
402
  message,
397
403
  stepId
398
404
  }) {
399
405
  const activeCycle = await readTrimmedFile(path.join(paths.sessionRoot, "active_cycle"));
400
- const receiptPath = path.join(paths.sessionRoot, "steps", `cycle_${activeCycle}`, stepId);
401
- if (await pathExists(receiptPath)) {
406
+ if (
407
+ await pathExists(path.join(paths.sessionRoot, "steps", stepId)) ||
408
+ await pathExists(path.join(paths.sessionRoot, "steps", `cycle_${activeCycle || "001"}`, stepId))
409
+ ) {
402
410
  return {
403
411
  ok: true,
404
412
  precondition: createPrecondition({
@@ -424,16 +432,16 @@ async function assertActiveCycleStepReceipt(paths, {
424
432
  }
425
433
 
426
434
  async function assertAutomatedChecksPassed(paths) {
427
- return assertActiveCycleStepReceipt(paths, {
435
+ return assertActiveCycleStepRecord(paths, {
428
436
  code: "automated_checks_not_passed",
429
437
  id: "automated_checks_passed",
430
- message: "Automated checks have passed.",
438
+ message: "Run automated checks completed successfully.",
431
439
  stepId: "automated_checks_run"
432
440
  });
433
441
  }
434
442
 
435
443
  async function assertDeepUiCheckSatisfied(paths) {
436
- return assertActiveCycleStepReceipt(paths, {
444
+ return assertActiveCycleStepRecord(paths, {
437
445
  code: "deep_ui_check_not_satisfied",
438
446
  id: "deep_ui_check_satisfied",
439
447
  message: "Deep UI check is satisfied.",
@@ -441,60 +449,6 @@ async function assertDeepUiCheckSatisfied(paths) {
441
449
  });
442
450
  }
443
451
 
444
- async function assertIssueMetadataExists(paths) {
445
- const source = await readTextIfExists(path.join(paths.sessionRoot, "issue_metadata.json"));
446
- if (!source) {
447
- return {
448
- ok: false,
449
- error: createError({
450
- code: "issue_metadata_missing",
451
- message: "Cannot continue before issue_metadata.json records the issue category and UI impact.",
452
- repairCommand: jskitCommand(`session ${paths.sessionId} step --issue-details -`)
453
- }),
454
- precondition: createPrecondition({
455
- id: "issue_metadata_exists",
456
- ok: false,
457
- message: "Issue metadata records issue category and UI impact."
458
- })
459
- };
460
- }
461
-
462
- let metadata = null;
463
- try {
464
- metadata = JSON.parse(source);
465
- } catch {
466
- metadata = null;
467
- }
468
- const issueCategory = String(metadata?.issueCategory || "").trim().toLowerCase();
469
- const uiImpact = String(metadata?.uiImpact || "").trim().toLowerCase();
470
- const validIssueCategories = new Set(["client", "server", "client_server", "tooling", "unknown"]);
471
- const validUiImpacts = new Set(["none", "possible", "definite", "unknown"]);
472
- if (validIssueCategories.has(issueCategory) && validUiImpacts.has(uiImpact)) {
473
- return {
474
- ok: true,
475
- precondition: createPrecondition({
476
- id: "issue_metadata_exists",
477
- ok: true,
478
- message: "Issue metadata records issue category and UI impact."
479
- })
480
- };
481
- }
482
-
483
- return {
484
- ok: false,
485
- error: createError({
486
- code: "issue_metadata_invalid",
487
- message: "issue_metadata.json must include a valid issueCategory and uiImpact.",
488
- repairCommand: jskitCommand(`session ${paths.sessionId} step --issue-details -`)
489
- }),
490
- precondition: createPrecondition({
491
- id: "issue_metadata_exists",
492
- ok: false,
493
- message: "Issue metadata records issue category and UI impact."
494
- })
495
- };
496
- }
497
-
498
452
  async function assertIssueTextExists(paths) {
499
453
  const issueText = await readTrimmedFile(path.join(paths.sessionRoot, "issue.md"));
500
454
  if (issueText) {
@@ -512,7 +466,7 @@ async function assertIssueTextExists(paths) {
512
466
  error: createError({
513
467
  code: "issue_text_missing",
514
468
  message: "Cannot create a GitHub issue before issue.md exists.",
515
- repairCommand: jskitCommand(`session ${paths.sessionId} step --issue -`)
469
+ repairCommand: jskitCommand(`session ${paths.sessionId} step`)
516
470
  }),
517
471
  precondition: createPrecondition({
518
472
  id: "issue_text_exists",
@@ -549,62 +503,6 @@ async function assertIssueUrlExists(paths) {
549
503
  };
550
504
  }
551
505
 
552
- async function assertPlanTextExists(paths) {
553
- const activeCycle = await readTrimmedFile(path.join(paths.sessionRoot, "active_cycle"));
554
- const planPath = path.join(paths.sessionRoot, "cycles", `cycle_${activeCycle || "001"}`, "plan.md");
555
- const planText = await readTrimmedFile(planPath);
556
- if (planText) {
557
- return {
558
- ok: true,
559
- precondition: createPrecondition({
560
- id: "plan_text_exists",
561
- ok: true,
562
- message: "Plan text exists."
563
- })
564
- };
565
- }
566
- return {
567
- ok: false,
568
- error: createError({
569
- code: "plan_text_missing",
570
- message: "Cannot execute a plan before the active cycle plan exists.",
571
- repairCommand: jskitCommand(`session ${paths.sessionId} step --plan -`)
572
- }),
573
- precondition: createPrecondition({
574
- id: "plan_text_exists",
575
- ok: false,
576
- message: "Plan text exists."
577
- })
578
- };
579
- }
580
-
581
- async function assertIssueDetailsExists(paths) {
582
- const issueDetails = await readTrimmedFile(path.join(paths.sessionRoot, "issue_details.md"));
583
- if (issueDetails) {
584
- return {
585
- ok: true,
586
- precondition: createPrecondition({
587
- id: "issue_details_exists",
588
- ok: true,
589
- message: "Issue details exist."
590
- })
591
- };
592
- }
593
- return {
594
- ok: false,
595
- error: createError({
596
- code: "issue_details_missing",
597
- message: "Cannot create a plan before issue_details.md exists.",
598
- repairCommand: jskitCommand(`session ${paths.sessionId} step --issue-details -`)
599
- }),
600
- precondition: createPrecondition({
601
- id: "issue_details_exists",
602
- ok: false,
603
- message: "Issue details exist."
604
- })
605
- };
606
- }
607
-
608
506
  async function assertBlueprintUpdateSatisfied(paths) {
609
507
  if (await pathExists(path.join(paths.sessionRoot, "steps", "blueprint_updated"))) {
610
508
  return {
@@ -631,28 +529,28 @@ async function assertBlueprintUpdateSatisfied(paths) {
631
529
  };
632
530
  }
633
531
 
634
- async function assertFinalReportExists(paths) {
635
- if (await pathExists(path.join(paths.sessionRoot, "final_report.md"))) {
532
+ async function assertPullRequestFileExists(paths) {
533
+ if (await pathExists(path.join(paths.sessionRoot, "pull_request.md"))) {
636
534
  return {
637
535
  ok: true,
638
536
  precondition: createPrecondition({
639
- id: "final_report_exists",
537
+ id: "pull_request_file_exists",
640
538
  ok: true,
641
- message: "Final report exists."
539
+ message: "Pull request draft exists."
642
540
  })
643
541
  };
644
542
  }
645
543
  return {
646
544
  ok: false,
647
545
  error: createError({
648
- code: "final_report_missing",
649
- message: "Cannot publish the PR before final_report.md exists.",
650
- repairCommand: jskitCommand(`session ${paths.sessionId} step`)
546
+ code: "pull_request_file_missing",
547
+ message: "Cannot publish the PR before pull_request.md exists.",
548
+ repairCommand: jskitCommand(`session ${paths.sessionId} create_pull_request_file`)
651
549
  }),
652
550
  precondition: createPrecondition({
653
- id: "final_report_exists",
551
+ id: "pull_request_file_exists",
654
552
  ok: false,
655
- message: "Final report exists."
553
+ message: "Pull request draft exists."
656
554
  })
657
555
  };
658
556
  }
@@ -673,7 +571,7 @@ async function assertWorktreeExists(paths) {
673
571
  error: createError({
674
572
  code: "worktree_missing",
675
573
  message: "Session worktree does not exist.",
676
- repairCommand: jskitCommand(`session ${paths.sessionId} step`)
574
+ repairCommand: jskitCommand(`session ${paths.sessionId} create_worktree`)
677
575
  }),
678
576
  precondition: createPrecondition({
679
577
  id: "worktree_exists",
@@ -711,8 +609,8 @@ async function assertPrUrlExists(paths) {
711
609
  }
712
610
 
713
611
  async function assertMainCheckoutSyncSatisfied(paths) {
714
- const receiptPath = path.join(paths.sessionRoot, "steps", "main_checkout_synced");
715
- if (await pathExists(receiptPath)) {
612
+ const recordPath = path.join(paths.sessionRoot, "steps", "main_checkout_synced");
613
+ if (await pathExists(recordPath)) {
716
614
  return {
717
615
  ok: true,
718
616
  precondition: createPrecondition({
@@ -742,21 +640,19 @@ export {
742
640
  assertAcceptedChangesCommitted,
743
641
  assertActiveCycleExists,
744
642
  assertActiveCycleUserCheckPassed,
643
+ assertUserCheckPassed,
745
644
  assertBlueprintUpdateSatisfied,
746
645
  assertDeepUiCheckSatisfied,
747
646
  assertDependenciesInstalled,
748
- assertFinalReportExists,
647
+ assertPullRequestFileExists,
749
648
  assertGhAuth,
750
649
  assertGitCurrentBranch,
751
650
  assertGitRepository,
752
651
  assertGithubOrigin,
753
- assertIssueMetadataExists,
754
652
  assertIssueTextExists,
755
653
  assertIssueUrlExists,
756
654
  assertAutomatedChecksPassed,
757
- assertIssueDetailsExists,
758
655
  assertMainCheckoutSyncSatisfied,
759
- assertPlanTextExists,
760
656
  assertPrUrlExists,
761
657
  assertReadyJskitApp,
762
658
  assertSessionExists,
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import {
3
- JSKIT_CLI_SHELL_RULE,
4
3
  PROMPT_DIRECTORY,
5
4
  SESSION_STATE_RELATIVE_PATH
6
5
  } from "./constants.js";
@@ -25,20 +24,9 @@ function renderTemplate(source, values = {}) {
25
24
  });
26
25
  }
27
26
 
28
- function withShellCommandRule(template) {
29
- const body = String(template || "").trim();
30
- if (!body) {
31
- return JSKIT_CLI_SHELL_RULE;
32
- }
33
- if (body.includes("When running JSKIT CLI commands from the shell")) {
34
- return body;
35
- }
36
- return `${JSKIT_CLI_SHELL_RULE}\n\n---\n\n${body}`;
37
- }
38
-
39
27
  async function renderPrompt(paths, templateName, values = {}) {
40
28
  const template = await readPromptTemplate(paths.targetRoot, templateName);
41
- return renderTemplate(withShellCommandRule(template), {
29
+ return renderTemplate(template, {
42
30
  branch: paths.branch,
43
31
  session_id: paths.sessionId,
44
32
  worktree: paths.worktree,
@@ -49,6 +37,5 @@ async function renderPrompt(paths, templateName, values = {}) {
49
37
  export {
50
38
  readPromptTemplate,
51
39
  renderPrompt,
52
- renderTemplate,
53
- withShellCommandRule
40
+ renderTemplate
54
41
  };
@@ -13,7 +13,7 @@ Before writing the blueprint, classify the app state if local files are availabl
13
13
  - partial_jskit_app
14
14
  - jskit_app
15
15
 
16
- Use these markers for a real JSKIT app when they exist:
16
+ Recognize these files as signs of a real JSKIT app when they exist:
17
17
 
18
18
  - package.json
19
19
  - config/public.js
@@ -44,9 +44,4 @@ Cover:
44
44
 
45
45
  If the brief is ambiguous, state the assumption in the blueprint instead of asking questions. Do not invent detailed feature behavior that the brief does not support.
46
46
 
47
- When the blueprint is ready, output only the final markdown surrounded by these exact markers:
48
-
49
- [app_blueprint]
50
- # App Blueprint
51
- ...
52
- [/app_blueprint]
47
+ When the blueprint is ready, present the final Markdown starting with `# App Blueprint`.
@@ -16,7 +16,7 @@ Rules:
16
16
  - Prefer JSKIT-owned helpers, generators, package seams, agent docs, package descriptors, and documented commands over local hacks.
17
17
  - If a failure involves JSKIT architecture, generator ownership, CRUD, surfaces, placements, client/server contracts, or UI verification, read the relevant docs under `node_modules/@jskit-ai/agent-docs/` or `packages/agent-docs/` before repairing it.
18
18
  - Use `npx --no-install jskit ...` for JSKIT CLI commands you run directly from the shell.
19
- - Keep fixes scoped to the current issue, issue details, and active plan.
19
+ - Keep fixes scoped to the current issue and worktree.
20
20
  - Do not create commits, branches, issues, pull requests, merges, or worktree cleanup. JSKIT session owns those steps.
21
21
 
22
22
  When finished, report:
@@ -25,19 +25,4 @@ When finished, report:
25
25
  - files changed
26
26
  - final check command and result
27
27
  - anything still unverified
28
-
29
- If the repair records a meaningful verification decision, tradeoff, missing coverage, or root-cause explanation future steps should know, include concise entries with reasons in this exact marker block:
30
-
31
- ```text
32
- [agent_decisions]
33
- <verification or repair decisions, or "No new decisions.">
34
- [/agent_decisions]
35
- ```
36
-
37
- At the very end, include this completion block so Studio knows the step is complete:
38
-
39
- [jskit_step_result]
40
- status: complete
41
- step: automated_checks_run
42
- summary: Short summary of the final check command, result, and any repairs.
43
- [/jskit_step_result]
28
+ - any meaningful verification decision, tradeoff, missing coverage, or root-cause note future steps should know
@@ -4,13 +4,10 @@ GitHub issue: {{issue_url}}
4
4
  Issue number: {{issue_number}}
5
5
  Issue title: {{issue_title}}
6
6
  Issue body file: {{issue_file}}
7
- Issue details file (`issue_details.md`): {{issue_details_file}}
8
- Plan file: {{plan_file}}
9
- Agent decisions file (`agent_decisions.md`): {{agent_decisions_file}}
10
7
  Current blueprint file (`.jskit/APP_BLUEPRINT.md`): {{app_blueprint_file}}
11
8
  Worktree: {{worktree}}
12
9
 
13
- Use the accepted issue work to update only durable app/product/architecture memory. Read the current blueprint when present, issue title/body, issue details, approved plan, agent decisions, helper map, package/app metadata, and changed files.
10
+ Use the accepted issue work to update only durable app/product/architecture memory. Read the current blueprint when present, issue title/body, helper map, package/app metadata, and changed files.
14
11
 
15
12
  Changed files since the session base:
16
13
 
@@ -29,10 +26,4 @@ Rules:
29
26
  - Do not edit files other than `.jskit/APP_BLUEPRINT.md`.
30
27
  - Do not commit, branch, push, create PRs, merge, or clean up worktrees.
31
28
 
32
- When finished, summarize the blueprint result normally, then end with this exact marker:
33
-
34
- [jskit_step_result]
35
- status: complete
36
- step: blueprint_updated
37
- summary: Short summary of blueprint changes, or why no blueprint update was needed.
38
- [/jskit_step_result]
29
+ When finished, summarize the blueprint changes, or why no blueprint update was needed.
@@ -5,9 +5,6 @@ GitHub issue: {{issue_url}}
5
5
  Issue number: {{issue_number}}
6
6
  Issue title: {{issue_title}}
7
7
  Issue body file: {{issue_file}}
8
- Issue details file (`issue_details.md`): {{issue_details_file}}
9
- Plan file: {{plan_file}}
10
- UI impact: {{ui_impact}}
11
8
  Worktree: {{worktree}}
12
9
 
13
10
  Changed files since the session base:
@@ -30,7 +27,7 @@ Check:
30
27
  - route and navigation coherence.
31
28
  - consistency with the existing app style.
32
29
 
33
- When clear scoped UI issues exist, fix them in the worktree. Keep fixes limited to the issue, confirmed issue details, and approved plan.
30
+ When clear scoped UI issues exist, fix them in the worktree. Keep fixes limited to the issue.
34
31
 
35
32
  Use Playwright for a meaningful route check when possible. If login is required, use a development-only auth bootstrap path. When possible, record UI verification with:
36
33
 
@@ -40,18 +37,4 @@ Important: `npx --no-install jskit app verify-ui` does not start the app server.
40
37
 
41
38
  Do not create commits, branches, issues, pull requests, merges, or worktree cleanup. JSKIT session owns those steps.
42
39
 
43
- If this pass makes UI fixes, intentionally skips UI work after inspection, changes a design direction, or leaves a meaningful UI verification gap, include concise decision entries with reasons in this exact marker block:
44
-
45
- ```text
46
- [agent_decisions]
47
- <Deep UI decisions or "No new decisions.">
48
- [/agent_decisions]
49
- ```
50
-
51
- At the very end, include this completion block so Studio knows the step is complete:
52
-
53
- [jskit_step_result]
54
- status: complete
55
- step: deep_ui_check_run
56
- summary: Short summary of UI findings, fixes, verification, or why no UI work applied.
57
- [/jskit_step_result]
40
+ When finished, summarize UI findings, fixes, verification, why no UI work applied, and any meaningful UI verification gaps.
@@ -0,0 +1,44 @@
1
+ You are preparing the pull request draft for JSKIT session {{session_id}}.
2
+
3
+ Write the pull request body to this exact file:
4
+
5
+ {{pull_request_file}}
6
+
7
+ Context:
8
+ - Worktree: {{worktree}}
9
+ - Issue: {{issue_url}}
10
+ - Issue title: {{issue_title}}
11
+ - Issue file: {{issue_file}}
12
+ - Base branch: {{base_branch}}
13
+
14
+ Files changed:
15
+ {{files_changed}}
16
+
17
+ Commits:
18
+ {{commits}}
19
+
20
+ Checks:
21
+ {{checks}}
22
+
23
+ UI checks:
24
+ {{ui_checks}}
25
+
26
+ Review passes:
27
+ {{review_passes}}
28
+
29
+ User check:
30
+ {{user_check}}
31
+
32
+ Blueprint:
33
+ {{blueprint_status}}
34
+
35
+ Command log:
36
+ {{command_log}}
37
+
38
+ Requirements:
39
+ - Write only `pull_request.md` at the path above.
40
+ - Do not create a GitHub pull request.
41
+ - Do not run `gh`, `git push`, `git commit`, merge, or clean up the worktree.
42
+ - Include any closing issue reference needed for GitHub to close the issue.
43
+ - Keep the body useful to a reviewer: summary, key changes, verification, and any known gaps.
44
+ - When done, briefly summarize that the file was written.
@@ -0,0 +1,26 @@
1
+ Create the canonical issue files from the scoped issue discussion in this Codex thread.
2
+
3
+ Canonical issue body file to write: {{issue_file}}
4
+ Canonical issue title file to write: {{issue_title_file}}
5
+
6
+ Use the issue definition and scoping conversation that just happened in this terminal. If something is still materially unclear, ask the user before writing the files.
7
+
8
+ Do not create a GitHub issue.
9
+ Do not implement the change.
10
+ Do not edit app code.
11
+ Do not run generators, tests, installs, `gh`, `git add`, `git commit`, `git push`, or JSKIT workflow mutation commands.
12
+
13
+ Write:
14
+
15
+ - A short issue title to `{{issue_title_file}}`.
16
+ - A concrete, implementation-ready issue body to `{{issue_file}}`.
17
+
18
+ The issue body should include:
19
+
20
+ - The requested change or bug clearly stated.
21
+ - The accepted scope.
22
+ - Important exclusions or non-goals.
23
+ - Relevant implementation boundaries.
24
+ - Acceptance criteria when useful.
25
+
26
+ After writing the files, show the title and body in the terminal for user review.
@@ -0,0 +1 @@
1
+ You are helping the user define this issue before implementation. Treat the request above as the starting point and keep returning to it when deciding scope, exclusions, and acceptance criteria. Your job is to turn the request into a clear, scoped, implementation-ready issue through conversation. Be helpful to the user. Be a good software engineer who understands both the app being developed and the JSKIT framework being used, and provide practical advice that improves the issue before implementation starts. Do not create files. Do not write `issue.md`. Do not write `issue_title`. Do not create a GitHub issue. Do not implement the change. Do not edit app code. Do not run generators, tests, installs, `gh`, `git add`, `git commit`, `git push`, or JSKIT workflow mutation commands. You may inspect the app read-only when it helps scope the issue: use commands such as `pwd`, `ls`, `find`, `rg`, `cat`, `sed`, and `git status`; read package.json, `.jskit/lock.json`, config, routes, packages, source files, `.jskit/APP_BLUEPRINT.md`, and `.jskit/helper-map.md` when available; use non-mutating JSKIT inspection commands when available and relevant, such as `npx --no-install jskit list`, `npx --no-install jskit show <package> --details`, and `npx --no-install jskit list-placements`; if `jskit` is not on PATH, or `npx --no-install jskit ...` fails because a linked/devlinked JSKIT CLI cannot resolve a package such as `@jskit-ai/kernel`, treat that as a local development environment limitation and continue with filesystem inspection instead of trying to repair PATH, reinstall packages, publish packages, edit devlinks, or advance the JSKIT session; prefer JSKIT agent docs over reverse-engineering framework architecture from source files, starting with `node_modules/@jskit-ai/agent-docs/DISTR_AGENT.md`, `node_modules/@jskit-ai/agent-docs/guide/agent/index.md`, and `node_modules/@jskit-ai/agent-docs/patterns/INDEX.md` when present, or `packages/agent-docs/...` when working inside the JSKIT monorepo or a devlinked sibling. Only run shell commands when inspecting the app. Do not run `printf`, `echo`, `cat`, heredocs, or similar commands merely to display your own summary or communicate with the user. Engage with the user meaningfully: restate what you think the user wants; identify ambiguities, hidden constraints, and likely ownership boundaries; ask focused questions only when the answer would materially change scope or implementation; suggest a practical scope if the request is too broad; call out what should be excluded from this issue; and when the issue is clear enough, respond normally in the Codex conversation with the agreed scope, acceptance criteria, and any important implementation boundaries. Stop there. The user will continue to the next JSKIT step when they are satisfied with the scoped issue.
@@ -1,45 +1,21 @@
1
1
  Create an implementation plan for JSKIT session {{session_id}}.
2
2
 
3
- Active cycle: {{active_cycle}}
4
- Plan source: {{plan_source}}
5
-
6
3
  GitHub issue: {{issue_url}}
7
4
  Issue number: {{issue_number}}
8
5
  Issue title: {{issue_title}}
9
6
  Issue body file: {{issue_file}}
10
7
  Issue title file: {{issue_title_file}}
11
- Issue details file (`issue_details.md`): {{issue_details_file}}
12
- Agent decisions file (`agent_decisions.md`): {{agent_decisions_file}}
13
8
  App blueprint file (`.jskit/APP_BLUEPRINT.md`): {{app_blueprint_file}}
14
- Plan file JSKIT will write after user approval: {{plan_file}}
15
9
  Worktree: {{worktree}}
16
10
 
17
- This planning step is read-only. Do not edit files, create session receipts, create or overwrite the plan file, create commits, create branches, create issues, create pull requests, merge, or clean worktrees. JSKIT will save the approved plan to the plan file after the user reviews it.
18
-
19
- If Plan source is `issue`, create the plan from the issue and confirmed issue details.
20
-
21
- If Plan source is `rework`, create a revised plan from the user's rework request for this cycle. Preserve the original issue constraints, but focus the plan on fixing the reported problem.
22
-
23
- Rework request file: {{rework_request_file}}
24
-
25
- Rework request:
26
-
27
- {{rework_request}}
11
+ This planning step is read-only for app code. Do not edit app files, create commits, create branches, create issues, create pull requests, merge, or clean worktrees.
28
12
 
29
- Read the issue, confirmed issue details, rework request when present, agent decisions, and local app before planning. Use the issue files, issue details file, package.json, .jskit metadata, config, packages, routes, generated references, package docs, any saved app blueprint, and `.jskit/helper-map.md` when available.
13
+ Create the plan from the issue and local app. Use the issue files, package.json, .jskit metadata, config, packages, routes, generated references, package docs, any saved app blueprint, and `.jskit/helper-map.md` when available.
30
14
 
31
15
  Before deriving JSKIT architecture from source files, read the package-owned agent docs that apply to this work. Start with `node_modules/@jskit-ai/agent-docs/DISTR_AGENT.md`, `node_modules/@jskit-ai/agent-docs/guide/agent/index.md`, and `node_modules/@jskit-ai/agent-docs/patterns/INDEX.md` when present. If the worktree is the JSKIT monorepo or a devlinked sibling, use the equivalent `packages/agent-docs/...` paths. Then read the specific pattern docs needed for the lane, such as `patterns/crud-scaffolding.md`, `patterns/crud-repository-mapping.md`, `patterns/page-scaffolding.md`, `patterns/placements.md`, `patterns/surfaces.md`, `patterns/client-requests.md`, `patterns/live-actions.md`, `patterns/generated-ui-contract-tracking.md`, or `patterns/ui-testing.md`.
32
16
 
33
17
  If these docs are unavailable, continue with app inspection and say that the agent docs were unavailable. Do not compensate by inventing framework rules from isolated source files.
34
18
 
35
- Confirmed issue details:
36
-
37
- {{issue_details_text}}
38
-
39
- Known decisions:
40
-
41
- {{agent_decisions_text}}
42
-
43
19
  Start by identifying the implementation lane:
44
20
 
45
21
  - package install
@@ -50,7 +26,7 @@ Start by identifying the implementation lane:
50
26
  Planning rules:
51
27
 
52
28
  - Keep the plan scoped to the issue. Avoid "while I am here" work.
53
- - Follow the confirmed issue details and preserve the issue category and UI impact in the plan. If details are insufficient, say exactly what is missing instead of inventing foundational details.
29
+ - If details are insufficient, say exactly what is missing instead of inventing foundational details.
54
30
  - Prefer vertical slices that produce visible or end-to-end progress.
55
31
  - If the work is too broad to review confidently, split it into clear chunks.
56
32
  - Make generator decisions concrete. Name the exact `npx --no-install jskit` commands to run when a generator or package install applies.
@@ -67,20 +43,15 @@ Planning rules:
67
43
  - For package-owned baseline workflows, plan to install and verify the baseline before inventing custom code around it.
68
44
  - For user-facing UI, include Material/Vuetify quality expectations and a Playwright verification path.
69
45
  - If login is required for UI verification, plan for a development-only auth bootstrap path instead of live external auth.
70
- - Do not create or update the old `.jskit/WORKBOARD.md` workflow. JSKIT session state, receipts, issue text, plan file, transcript, and commits are the tracker.
46
+ - Do not create or update the old `.jskit/WORKBOARD.md` workflow. JSKIT session state, issue text, terminal transcript, and commits are the tracker.
71
47
 
72
48
  If setup values are needed, ask plainly using exact env var or option names. For example: DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, AUTH_SUPABASE_URL, AUTH_SUPABASE_PUBLISHABLE_KEY, APP_PUBLIC_URL.
73
49
 
74
50
  If the issue is not clear enough to plan safely, ask the user concise follow-up questions first.
75
51
 
76
- When the plan is ready, output only the final plan for this cycle and any new decisions surrounded by these exact markers:
77
-
78
- [plan]
79
- <implementation plan in Markdown>
80
- [/plan]
52
+ When the plan is ready:
81
53
 
82
- [agent_decisions]
83
- <new planning decisions with reasons, or "No new decisions.">
84
- [/agent_decisions]
54
+ - Present the final plan and any new decisions clearly in the terminal for the user to review.
55
+ - Do not write a plan file.
85
56
 
86
- Keep the plan concrete and implementation-oriented. Include the issue category, UI impact, likely files or areas to touch, ordered steps, generator commands to consider, review expectations, and checks that should be run.
57
+ Keep the plan concrete and implementation-oriented. Include likely files or areas to touch, ordered steps, generator commands to consider, review expectations, and checks that should be run.