@ktpartners/dgs-platform 2.7.0 → 2.7.1

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.
@@ -517,6 +517,56 @@ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs({phase
517
517
  Separate from per-task commits — captures execution results only.
518
518
  </final_commit>
519
519
 
520
+ <codereview_gate>
521
+ Check if code review is enabled:
522
+
523
+ ```bash
524
+ CODEREVIEW=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" config-get workflow.codereview 2>/dev/null || echo "false")
525
+ ```
526
+
527
+ If `CODEREVIEW` is `true`:
528
+
529
+ Display:
530
+ ```
531
+ ------------------------------------------------------------
532
+ DGS > SPAWNING CODE REVIEW
533
+ ------------------------------------------------------------
534
+
535
+ Reviewing {phase}-{plan} changes across 3 passes...
536
+ ```
537
+
538
+ Compute diff reference for the plan's task commits:
539
+
540
+ ```bash
541
+ FIRST_TASK_COMMIT=$(git log --oneline --grep="feat(${PHASE}-${PLAN}):" --grep="fix(${PHASE}-${PLAN}):" --grep="test(${PHASE}-${PLAN}):" --grep="refactor(${PHASE}-${PLAN}):" --reverse | head -1 | cut -d' ' -f1)
542
+ ```
543
+
544
+ If FIRST_TASK_COMMIT is empty (no task commits found), skip codereview with message: "No task commits found for {phase}-{plan}, skipping code review."
545
+
546
+ Otherwise, invoke the codereview workflow:
547
+
548
+ ```
549
+ @~/.claude/deliver-great-systems/workflows/codereview.md
550
+ ```
551
+
552
+ With inputs:
553
+ - PHASE: ${PHASE}
554
+ - PLAN: ${PLAN}
555
+ - PLAN_PATH: ${phase_dir}/{phase}-{plan}-PLAN.md
556
+ - PHASE_DIR: ${phase_dir}
557
+ - DIFF_REF: ${FIRST_TASK_COMMIT}^..HEAD
558
+
559
+ After codereview completes:
560
+ - If auto-fixes were committed, the fix commit hash is noted in the codereview output
561
+ - The SUMMARY.md already has codereview findings appended and CODEREVIEW.md has been created with the full report (both done by codereview workflow)
562
+ - If the codereview workflow committed auto-fixes, amend the metadata commit to include the updated SUMMARY.md and CODEREVIEW.md:
563
+ ```bash
564
+ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "" --files ${phase_dir}/{phase}-{plan}-SUMMARY.md ${phase_dir}/{phase}-{plan}-CODEREVIEW.md --amend
565
+ ```
566
+
567
+ If `CODEREVIEW` is `false` or absent: skip silently (no output).
568
+ </codereview_gate>
569
+
520
570
  <completion_format>
521
571
  ```markdown
522
572
  ## PLAN COMPLETE
@@ -546,5 +596,6 @@ Plan execution complete when:
546
596
  - [ ] STATE.md updated (position, decisions, issues, session)
547
597
  - [ ] ROADMAP.md updated with plan progress (via `roadmap update-plan-progress`)
548
598
  - [ ] Final metadata commit made (includes SUMMARY.md, STATE.md, ROADMAP.md)
599
+ - [ ] Codereview gate checked (if enabled: codereview invoked, if auto-fixes committed: metadata commit amended)
549
600
  - [ ] Completion format returned to orchestrator
550
601
  </success_criteria>
@@ -505,12 +505,12 @@ describe('v2 mode with project: init todos', () => {
505
505
  fixture.cleanup();
506
506
  });
507
507
 
508
- it('returns project-qualified pending_dir', () => {
509
- assert.equal(result.pending_dir, path.join('.planning', 'projects', 'test-project', 'todos', 'pending'));
508
+ it('returns product-level pending_dir', () => {
509
+ assert.equal(result.pending_dir, path.join('.planning', 'todos', 'pending'));
510
510
  });
511
511
 
512
- it('returns project-qualified completed_dir', () => {
513
- assert.equal(result.completed_dir, path.join('.planning', 'projects', 'test-project', 'todos', 'completed'));
512
+ it('returns product-level completed_dir', () => {
513
+ assert.equal(result.completed_dir, path.join('.planning', 'todos', 'completed'));
514
514
  });
515
515
 
516
516
  it('returns dgs_mode v2', () => {
@@ -138,7 +138,7 @@ function createBackupTag(cwd) {
138
138
  // ─── Migration Planning ─────────────────────────────────────────────────────
139
139
 
140
140
  // Directories to move (project-level, order: directories first)
141
- const DIRS_TO_MOVE = ['phases', 'research', 'todos', 'quick', 'debug'];
141
+ const DIRS_TO_MOVE = ['phases', 'research', 'quick', 'debug'];
142
142
 
143
143
  // Files to move (project-level)
144
144
  const FILES_TO_MOVE = ['PROJECT.md', 'REQUIREMENTS.md', 'ROADMAP.md', 'STATE.md'];
@@ -327,13 +327,13 @@ describe('migrateV1ToV2', () => {
327
327
  assert.ok(log.includes('rename'));
328
328
  });
329
329
 
330
- it('moves todos/ directory if it exists', () => {
330
+ it('preserves todos/ at product level (not moved to project)', () => {
331
331
  writeFile(tmpDir, '.planning/todos/pending/task1.md', '# Todo 1\n');
332
332
  createV1Install(tmpDir, 'Test App');
333
333
  migrateV1ToV2(tmpDir, 'test-app');
334
334
 
335
- assert.ok(fs.existsSync(path.join(tmpDir, '.planning', 'projects', 'test-app', 'todos', 'pending', 'task1.md')));
336
- assert.ok(!fs.existsSync(path.join(tmpDir, '.planning', 'todos')));
335
+ assert.ok(fs.existsSync(path.join(tmpDir, '.planning', 'todos', 'pending', 'task1.md')));
336
+ assert.ok(!fs.existsSync(path.join(tmpDir, '.planning', 'projects', 'test-app', 'todos')));
337
337
  });
338
338
 
339
339
  it('moves quick/ directory if it exists', () => {
@@ -407,18 +407,15 @@ describe('collectMigrationMoves', () => {
407
407
  writeFile(tmpDir, '.planning/PROJECT.md', '# Project: Test\n');
408
408
  writeFile(tmpDir, '.planning/phases/01-setup/01-01-PLAN.md', '---\n---\n');
409
409
  writeFile(tmpDir, '.planning/research/notes.md', '# Notes\n');
410
- writeFile(tmpDir, '.planning/todos/pending/task.md', '# Todo\n');
411
410
 
412
411
  const { moves } = collectMigrationMoves(tmpDir, 'test');
413
412
 
414
413
  const phasesMove = moves.find(m => m.relSource.endsWith('phases'));
415
414
  const researchMove = moves.find(m => m.relSource.endsWith('research'));
416
- const todosMove = moves.find(m => m.relSource.endsWith('todos'));
417
415
  const projectMove = moves.find(m => m.relSource.endsWith('PROJECT.md'));
418
416
 
419
417
  assert.strictEqual(phasesMove.isDir, true);
420
418
  assert.strictEqual(researchMove.isDir, true);
421
- assert.strictEqual(todosMove.isDir, true);
422
419
  assert.strictEqual(projectMove.isDir, false);
423
420
  });
424
421
  });
@@ -41,7 +41,7 @@ const COMPREHENSIVE_PATTERN = /\.planning\//;
41
41
  * multi-project install because they resolve to the root instead of
42
42
  * .planning/<project>/<path>.
43
43
  */
44
- const PROJECT_SCOPED_PATTERN = /\.planning\/(?:STATE|ROADMAP|PROJECT(?!S\.md)|REQUIREMENTS|phases|archive|quick|todos|debug|research)/;
44
+ const PROJECT_SCOPED_PATTERN = /\.planning\/(?:STATE|ROADMAP|PROJECT(?!S\.md)|REQUIREMENTS|phases|archive|quick|debug|research)/;
45
45
 
46
46
  /**
47
47
  * Workflow files allowlisted from comprehensive .planning/ scanning.
@@ -14,7 +14,7 @@ const { getPlanningRoot } = require('./paths.cjs');
14
14
 
15
15
  // ─── Constants ──────────────────────────────────────────────────────────────
16
16
 
17
- const STANDARD_DIRS = ['phases', 'research', 'todos', 'quick', 'debug'];
17
+ const STANDARD_DIRS = ['phases', 'research', 'quick', 'debug'];
18
18
 
19
19
  // ─── Project Subfolder Creation ─────────────────────────────────────────────
20
20
 
@@ -64,7 +64,7 @@ describe('createProjectSubfolder', () => {
64
64
 
65
65
  it('creates all required subdirectories', () => {
66
66
  createProjectSubfolder(tmpDir, 'auth-overhaul', 'Auth Overhaul');
67
- const expectedDirs = ['phases', 'research', 'todos', 'quick', 'debug'];
67
+ const expectedDirs = ['phases', 'research', 'quick', 'debug'];
68
68
  for (const dir of expectedDirs) {
69
69
  assert.ok(
70
70
  fs.existsSync(path.join(tmpDir, '.planning', 'projects', 'auth-overhaul', dir)),
@@ -571,7 +571,7 @@ function cmdStateSnapshot(cwd, raw) {
571
571
  function getMilestonePhaseFilter(cwd) {
572
572
  const milestonePhaseNums = new Set();
573
573
  try {
574
- const roadmap = fs.readFileSync(path.join(cwd, '.planning', 'ROADMAP.md'), 'utf-8');
574
+ const roadmap = fs.readFileSync(path.join(getPlanningRoot(cwd), 'ROADMAP.md'), 'utf-8');
575
575
  const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
576
576
  let m;
577
577
  while ((m = phasePattern.exec(roadmap)) !== null) {
@@ -632,7 +632,7 @@ function buildStateFrontmatter(bodyContent, cwd) {
632
632
 
633
633
  if (cwd) {
634
634
  try {
635
- const phasesDir = path.join(cwd, '.planning', 'phases');
635
+ const phasesDir = path.join(getPlanningRoot(cwd), 'phases');
636
636
  if (fs.existsSync(phasesDir)) {
637
637
  const isDirInMilestone = getMilestonePhaseFilter(cwd);
638
638
  const phaseDirs = fs.readdirSync(phasesDir, { withFileTypes: true })
@@ -228,8 +228,8 @@ function createTempProject(options) {
228
228
  }
229
229
 
230
230
  if (withTodos) {
231
- fs.mkdirSync(path.join(cwd, '.planning', PROJECTS_DIR, project, 'todos', 'pending'), { recursive: true });
232
- fs.mkdirSync(path.join(cwd, '.planning', PROJECTS_DIR, project, 'todos', 'completed'), { recursive: true });
231
+ fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'pending'), { recursive: true });
232
+ fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'completed'), { recursive: true });
233
233
  }
234
234
 
235
235
  if (withResearch) {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "bugs": {
5
5
  "url": "https://github.com/KT-Partners-Ltd/dgs-platform-docs/issues"
6
6
  },
7
- "version": "2.7.0",
7
+ "version": "2.7.1",
8
8
  "description": "Deliver Great Systems Platform — A meta-prompting, context engineering and spec-driven development system for Claude Code and Gemini by KT Partners.",
9
9
  "bin": {
10
10
  "dgs": "bin/install.js"