@erclx/canon 5.70.0 → 5.72.0

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 (36) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
  4. package/claude/skills/canon-feedback/SKILL.md +27 -2
  5. package/claude/skills/canon-feedback/references/template.md +22 -0
  6. package/claude/skills/git-pr/references/task-number.md +13 -0
  7. package/claude/skills/markdown-craft/references/markdown.md +1 -0
  8. package/claude/skills/plan-intake-answer/REQUIREMENT.md +4 -3
  9. package/claude/skills/plan-intake-answer/SKILL.md +35 -2
  10. package/claude/skills/review-ui/SKILL.md +1 -1
  11. package/claude/skills/review-ui/references/tick.md +17 -5
  12. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +1 -0
  13. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +6 -20
  14. package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +10 -0
  15. package/claude/skills/role-orchestrator/references/orchestrator-talk-launch.md +30 -0
  16. package/claude/skills/role-orchestrator/scripts/poll.ts +1 -1
  17. package/claude/skills/role-reviewer/SKILL.md +4 -0
  18. package/claude/skills/task-board/references/tasks-record-lines.md +40 -0
  19. package/claude/skills/task-board/references/tasks.md +4 -8
  20. package/claude/skills/ui-film/references/pr-clip.md +26 -2
  21. package/package.json +1 -1
  22. package/src/commands/feedback.ts +83 -3
  23. package/src/commands/markdown.ts +6 -1
  24. package/src/commands/pr.ts +66 -21
  25. package/src/commands/tasks.ts +133 -0
  26. package/src/feedback/body.ts +50 -0
  27. package/src/feedback/github-format.ts +77 -0
  28. package/src/feedback/github.ts +51 -12
  29. package/src/markdown/colons.ts +102 -16
  30. package/src/pr/carry.ts +64 -0
  31. package/src/pr/evidence.ts +1 -1
  32. package/src/pr/lift.ts +29 -12
  33. package/src/pr/review-state.ts +2 -0
  34. package/src/tasks/archive.ts +54 -1
  35. package/src/tasks/record.ts +118 -0
  36. package/src/tasks/validate.ts +37 -0
@@ -10,7 +10,9 @@ import {
10
10
  readPendingBranches,
11
11
  readPlanTargets,
12
12
  readPullRequest,
13
+ readSessions,
13
14
  resolveLivePlan,
15
+ SESSIONS_PREFIX,
14
16
  tasksDir,
15
17
  } from '@/tasks/archive'
16
18
  import {
@@ -66,6 +68,7 @@ export const FINDING_KINDS = [
66
68
  'blocker-settled',
67
69
  'blocker-unresolved',
68
70
  'blocker-declined',
71
+ 'sessions-misshapen',
69
72
  ] as const
70
73
 
71
74
  export type FindingKind = (typeof FINDING_KINDS)[number]
@@ -841,6 +844,39 @@ async function planDisagreement(
841
844
  }
842
845
  }
843
846
 
847
+ /**
848
+ * Reports a `Sessions:` line that does not parse as name and id pairs, since
849
+ * the reader takes such a line as naming nobody and a retro would find the
850
+ * sessions gone. A row whose task file is gone is left to `task-unresolved`.
851
+ */
852
+ async function checkSessions(
853
+ rows: readonly BoardRow[],
854
+ dir: string,
855
+ ): Promise<Finding[]> {
856
+ const found = await Promise.all(
857
+ rows.map(async (row): Promise<Finding | undefined> => {
858
+ if (!row.stem) return undefined
859
+ const file = join(dir, `${row.stem}.md`)
860
+ if (!existsSync(file)) return undefined
861
+
862
+ const text = await readFile(file, 'utf8')
863
+ const line = text
864
+ .split('\n')
865
+ .find((entry) => entry.startsWith(SESSIONS_PREFIX))
866
+ if (line === undefined || readSessions(text).length > 0) return undefined
867
+
868
+ return {
869
+ kind: 'sessions-misshapen',
870
+ group: row.group,
871
+ subject: row.stem,
872
+ message: `carries "${line}", which does not read as name (sessionId) pairs, so no session it names can be recovered. Rewrite it through canon tasks session.`,
873
+ }
874
+ }),
875
+ )
876
+
877
+ return found.filter((finding): finding is Finding => finding !== undefined)
878
+ }
879
+
844
880
  /**
845
881
  * Tests the claim a group name makes about a plan. `## Needs a plan` says none
846
882
  * is live and `## Up next` says one is written, and neither group has a `Plan`
@@ -1638,6 +1674,7 @@ export async function validateBoard(
1638
1674
  ...checkMapping(rows, backlog, dir),
1639
1675
  ...(await groupRuleFindings(rows, root)),
1640
1676
  ...(await checkPlanAgreement(rows, dir, root)),
1677
+ ...(await checkSessions(rows, dir)),
1641
1678
  ...(await checkStaleTouches(rows, root)),
1642
1679
  ...checkCellWidth(rows),
1643
1680
  ...checkOrdering(rows),