@brainervirus/workit-core 0.11.0 → 1.0.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 (150) hide show
  1. package/README.md +5 -3
  2. package/package.json +8 -3
  3. package/scripts/analyze-release-scope.ts +4 -1
  4. package/scripts/doctor-check.ts +3 -1
  5. package/scripts/install-codex-plugin.sh +28 -0
  6. package/scripts/install-cursor-plugin.sh +1 -0
  7. package/scripts/install-opencode-plugin.sh +1 -0
  8. package/scripts/install-pi-package.sh +56 -0
  9. package/scripts/rewrite-workspace-deps.ts +22 -5
  10. package/scripts/sync-release-manifests.ts +8 -5
  11. package/scripts/sync-runtime.sh +7 -3
  12. package/scripts/validate-cursor-marketplace.ts +16 -62
  13. package/skills/workit-babysit/SKILL.md +33 -0
  14. package/skills/workit-behavioral-tdd/SKILL.md +53 -0
  15. package/skills/workit-blast-radius/SKILL.md +31 -0
  16. package/skills/workit-challenge/SKILL.md +62 -0
  17. package/skills/workit-debug/SKILL.md +61 -0
  18. package/skills/workit-deslop/SKILL.md +36 -0
  19. package/skills/workit-diagram/SKILL.md +32 -0
  20. package/skills/workit-green-run/SKILL.md +29 -0
  21. package/skills/workit-handoff/SKILL.md +43 -0
  22. package/skills/workit-implement/SKILL.md +46 -0
  23. package/skills/workit-mockup/SKILL.md +28 -0
  24. package/skills/workit-plan/SKILL.md +66 -0
  25. package/skills/workit-review/SKILL.md +60 -0
  26. package/skills/workit-steer/SKILL.md +32 -0
  27. package/src/core/authority.ts +918 -0
  28. package/src/core/boundary.ts +29 -0
  29. package/src/core/branch.ts +26 -255
  30. package/src/core/changelog.ts +95 -18
  31. package/src/core/commit-flavors.ts +65 -0
  32. package/src/core/config-conversion.ts +183 -0
  33. package/src/core/config.ts +42 -0
  34. package/src/core/cutover.ts +721 -0
  35. package/src/core/detect-hosts.ts +107 -0
  36. package/src/core/doctor.ts +428 -18
  37. package/src/core/external-action-effects.ts +1171 -0
  38. package/src/core/external-action.ts +541 -0
  39. package/src/core/init.ts +83 -32
  40. package/src/core/methods.ts +125 -0
  41. package/src/core/policy-resolver.ts +523 -0
  42. package/src/core/pr-create.ts +7 -1
  43. package/src/core/registration.ts +69 -4
  44. package/src/core/repo-context.ts +59 -1
  45. package/src/core/setup.ts +28 -0
  46. package/src/core/skill-manifests.ts +40 -42
  47. package/src/core/support-matrix.ts +8 -3
  48. package/src/core/sync-runtime.ts +15 -3
  49. package/src/core/task-context.ts +179 -0
  50. package/src/core/task-contract.ts +1136 -0
  51. package/src/core/task-engine.ts +2562 -0
  52. package/src/core/task-evaluation.ts +679 -0
  53. package/src/core/task-store.ts +1071 -0
  54. package/src/core/tracker-issues.ts +237 -0
  55. package/src/core/uninstall.ts +67 -3
  56. package/src/core/vcs-config.ts +53 -22
  57. package/src/core/workers.ts +166 -0
  58. package/src/core/workspaces.ts +3 -1
  59. package/src/core/youtrack-tools.ts +2 -0
  60. package/src/core/youtrack.ts +145 -10
  61. package/src/core.ts +126 -0
  62. package/templates/execution-contract.md +17 -50
  63. package/templates/plan-template.md +3 -3
  64. package/templates/spec-template.md +15 -3
  65. package/templates/workit-contract.md +12 -0
  66. package/commands/wk-changelog.md +0 -2
  67. package/commands/wk-commit.md +0 -2
  68. package/commands/wk-docs-refresh.md +0 -2
  69. package/commands/wk-handoff.md +0 -2
  70. package/commands/wk-implement.md +0 -2
  71. package/commands/wk-init.md +0 -2
  72. package/commands/wk-issue-update.md +0 -2
  73. package/commands/wk-meetings.md +0 -2
  74. package/commands/wk-pr.md +0 -2
  75. package/commands/wk-release-notes.md +0 -2
  76. package/commands/wk-status.md +0 -2
  77. package/commands/wk-verify.md +0 -2
  78. package/scripts/update-superpowers.sh +0 -82
  79. package/scripts/vendor-assets.ts +0 -37
  80. package/skills/wk-changelog/SKILL.md +0 -15
  81. package/skills/wk-commit/SKILL.md +0 -16
  82. package/skills/wk-docs-refresh/SKILL.md +0 -15
  83. package/skills/wk-handoff/SKILL.md +0 -20
  84. package/skills/wk-implement/SKILL.md +0 -47
  85. package/skills/wk-init/SKILL.md +0 -31
  86. package/skills/wk-issue-update/SKILL.md +0 -27
  87. package/skills/wk-issue-update/references/youtrack-update-style.md +0 -81
  88. package/skills/wk-meetings/SKILL.md +0 -17
  89. package/skills/wk-pr/SKILL.md +0 -27
  90. package/skills/wk-release-notes/SKILL.md +0 -15
  91. package/skills/wk-status/SKILL.md +0 -16
  92. package/skills/wk-verify/SKILL.md +0 -16
  93. package/src/core/detector.ts +0 -239
  94. package/src/core/flow-state.ts +0 -3308
  95. package/src/core/handoff-context.ts +0 -136
  96. package/src/core/handoff-tools.ts +0 -133
  97. package/src/core/menu.ts +0 -70
  98. package/src/core/plan-tasks.ts +0 -43
  99. package/src/core/reminder.ts +0 -124
  100. package/src/core/sdd.ts +0 -353
  101. package/src/state.ts +0 -22
  102. package/templates/superpowers-doc-contract.md +0 -75
  103. package/vendor/superpowers/skills/brainstorming/SKILL.md +0 -159
  104. package/vendor/superpowers/skills/brainstorming/scripts/frame-template.html +0 -213
  105. package/vendor/superpowers/skills/brainstorming/scripts/helper.js +0 -167
  106. package/vendor/superpowers/skills/brainstorming/scripts/server.cjs +0 -723
  107. package/vendor/superpowers/skills/brainstorming/scripts/start-server.sh +0 -209
  108. package/vendor/superpowers/skills/brainstorming/scripts/stop-server.sh +0 -120
  109. package/vendor/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
  110. package/vendor/superpowers/skills/brainstorming/visual-companion.md +0 -291
  111. package/vendor/superpowers/skills/dispatching-parallel-agents/SKILL.md +0 -185
  112. package/vendor/superpowers/skills/executing-plans/SKILL.md +0 -70
  113. package/vendor/superpowers/skills/finishing-a-development-branch/SKILL.md +0 -241
  114. package/vendor/superpowers/skills/receiving-code-review/SKILL.md +0 -213
  115. package/vendor/superpowers/skills/requesting-code-review/SKILL.md +0 -103
  116. package/vendor/superpowers/skills/requesting-code-review/code-reviewer.md +0 -172
  117. package/vendor/superpowers/skills/subagent-driven-development/SKILL.md +0 -428
  118. package/vendor/superpowers/skills/subagent-driven-development/implementer-prompt.md +0 -139
  119. package/vendor/superpowers/skills/subagent-driven-development/scripts/review-package +0 -44
  120. package/vendor/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +0 -22
  121. package/vendor/superpowers/skills/subagent-driven-development/scripts/task-brief +0 -40
  122. package/vendor/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +0 -188
  123. package/vendor/superpowers/skills/systematic-debugging/CREATION-LOG.md +0 -119
  124. package/vendor/superpowers/skills/systematic-debugging/SKILL.md +0 -296
  125. package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +0 -158
  126. package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting.md +0 -115
  127. package/vendor/superpowers/skills/systematic-debugging/defense-in-depth.md +0 -122
  128. package/vendor/superpowers/skills/systematic-debugging/find-polluter.sh +0 -63
  129. package/vendor/superpowers/skills/systematic-debugging/root-cause-tracing.md +0 -169
  130. package/vendor/superpowers/skills/systematic-debugging/test-academic.md +0 -14
  131. package/vendor/superpowers/skills/systematic-debugging/test-pressure-1.md +0 -58
  132. package/vendor/superpowers/skills/systematic-debugging/test-pressure-2.md +0 -68
  133. package/vendor/superpowers/skills/systematic-debugging/test-pressure-3.md +0 -69
  134. package/vendor/superpowers/skills/test-driven-development/SKILL.md +0 -371
  135. package/vendor/superpowers/skills/test-driven-development/testing-anti-patterns.md +0 -299
  136. package/vendor/superpowers/skills/using-git-worktrees/SKILL.md +0 -202
  137. package/vendor/superpowers/skills/using-superpowers/SKILL.md +0 -62
  138. package/vendor/superpowers/skills/using-superpowers/references/antigravity-tools.md +0 -23
  139. package/vendor/superpowers/skills/using-superpowers/references/codex-tools.md +0 -39
  140. package/vendor/superpowers/skills/using-superpowers/references/pi-tools.md +0 -16
  141. package/vendor/superpowers/skills/verification-before-completion/SKILL.md +0 -139
  142. package/vendor/superpowers/skills/writing-plans/SKILL.md +0 -174
  143. package/vendor/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
  144. package/vendor/superpowers/skills/writing-skills/SKILL.md +0 -689
  145. package/vendor/superpowers/skills/writing-skills/anthropic-best-practices.md +0 -1150
  146. package/vendor/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  147. package/vendor/superpowers/skills/writing-skills/graphviz-conventions.dot +0 -172
  148. package/vendor/superpowers/skills/writing-skills/persuasion-principles.md +0 -187
  149. package/vendor/superpowers/skills/writing-skills/render-graphs.js +0 -168
  150. package/vendor/superpowers/skills/writing-skills/testing-skills-with-subagents.md +0 -384
@@ -1,239 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync } from "node:fs";
2
- import path from "node:path";
3
- import { CONFIG_GAP_MARKER } from "./config-guard";
4
- import { readEffectiveFlowState, type FlowReadResult } from "./flow-state";
5
-
6
- export type Detection = { choices: string[]; pattern: "alpha" | "numeric" } | null;
7
-
8
- export const detectConfigGapError = (text: string): boolean => text.includes(CONFIG_GAP_MARKER);
9
-
10
- // Enforcement-rail detectors: case-insensitive word-boundary heuristics.
11
- // Conservative bias (D-03): require 1+ signal word AND 0 evidence words;
12
- // when any evidence wording appears, do NOT fire.
13
-
14
- const COMPLETION_CLAIMS = /\b(?:done|fixed|passing|green|complete|all set)\b/i;
15
- const VERIFICATION_EVIDENCE =
16
- /\bbun run check\b|\bworkit_verify\b|\bbun test\b|\bchecks?\s+pass(?:es|ing)?\b|\btests?\s+pass(?:es|ing)?\b/i;
17
-
18
- // Claims completion without verification-command evidence in the same text.
19
- export const detectVerificationClaim = (text: string): boolean =>
20
- COMPLETION_CLAIMS.test(text) && !VERIFICATION_EVIDENCE.test(text);
21
-
22
- const IMPLEMENTATION_SIGNALS =
23
- /\b(?:changed|implemented|implementing|added|refactored|commit(?:ted|s)?|edited)\b/i;
24
- const FAILING_TEST_WORDS =
25
- /\b(?:failing test|test failed|watch it fail|red-green|tdd|test first)\b/i;
26
-
27
- // Implementation signal without a preceding failing-test mention.
28
- export const detectUntestedImplementation = (text: string): boolean =>
29
- IMPLEMENTATION_SIGNALS.test(text) && !FAILING_TEST_WORDS.test(text);
30
-
31
- const IMPLEMENTATION_ACTION =
32
- /\b(?:implement|add the feature|write the code|create the component|build (?:the )?(?:feature|component|module|command|screen|service))\b/i;
33
- const DESIGN_WORDS =
34
- /\b(?:design|spec|brainstorm|approved|plan|requested|instruction|as you asked|as you said)\b/i;
35
-
36
- // Implementation action without a presented/approved design.
37
- export const detectImplementationWithoutDesign = (text: string): boolean =>
38
- IMPLEMENTATION_ACTION.test(text) && !DESIGN_WORDS.test(text);
39
-
40
- const FIX_SIGNALS = /\b(?:fixed|fix|patch|solved)\b/i;
41
- const ROOT_CAUSE_WORDS =
42
- /\b(?:root cause|caused by|reproduced|stack trace|investigation|because)\b/i;
43
-
44
- // Fix proposal without root-cause evidence.
45
- export const detectFixWithoutRootCause = (text: string): boolean =>
46
- FIX_SIGNALS.test(text) && !ROOT_CAUSE_WORDS.test(text);
47
-
48
- const ACCEPTANCE_SIGNALS = /\b(?:agreed|makes sense|good point|will implement)\b/i;
49
- const REVIEW_VERIFICATION_WORDS =
50
- /\b(?:verif(?:y|ied)|check(?:ed|ing)?|reproduced|tested|confirmed)\b/i;
51
-
52
- // Review acceptance without verification wording.
53
- export const detectBlindReviewAcceptance = (text: string): boolean =>
54
- ACCEPTANCE_SIGNALS.test(text) && !REVIEW_VERIFICATION_WORDS.test(text);
55
-
56
- // Instruction-option detector: a clickable `question` option whose label is an
57
- // instruction to type free text. Clicking such an option returns the label
58
- // literal, not the typed value. Conservative: instruction verb + free-text noun.
59
- export const INSTRUCTION_OPTION_RE =
60
- /^(type|provide|paste|enter|write|give me)\b.*\b(url|id|issue|text|notes|number)\b/i;
61
-
62
- // Accepts the question tool-call input: an array of questions OR { questions: [...] }.
63
- export const detectInstructionOption = (questions: unknown): boolean => {
64
- const list = Array.isArray(questions)
65
- ? questions
66
- : (questions as { questions?: unknown } | null)?.questions;
67
- if (!Array.isArray(list)) return false;
68
- for (const q of list) {
69
- if (!q || typeof q !== "object") continue;
70
- const options = (q as { options?: unknown }).options;
71
- if (!Array.isArray(options)) continue;
72
- for (const opt of options) {
73
- if (!opt || typeof opt !== "object") continue;
74
- const label = (opt as { label?: unknown }).label;
75
- if (typeof label !== "string" || !label) continue;
76
- if (INSTRUCTION_OPTION_RE.test(label)) return true;
77
- }
78
- }
79
- return false;
80
- };
81
-
82
- // Raw delivery: an UNLABELED fenced block carrying doc markers — the agent pasted
83
- // the doc instead of rendering it. Rendered docs keep labeled fences (```mermaid)
84
- // and never match; reminders use angle-bracket blocks, so no false positives.
85
- // Labeled blocks are stripped first so their plain closing fence (```) can't match.
86
- export const detectRawDocDelivery = (text: string): boolean =>
87
- /^```\s*$/m.test(text.replace(/```\S[^\n]*\r?\n[\s\S]*?```/g, "")) &&
88
- (text.includes("# Spec") ||
89
- text.includes("# Plan") ||
90
- text.includes("**Spec:**") ||
91
- text.includes("**Branch:**"));
92
-
93
- // Interrogative gate: a literal question mark OR explicit interrogative phrases.
94
- // Plain "I want to confirm..." or "the script which runs" must NOT match.
95
- const INTERROGATIVE =
96
- /[?¿]|which\s+one|choose\s+(?:one|between|among)|do\s+you\s+(?:want|prefer)|want\s+me\s+to/i;
97
-
98
- export const detectProseChoices = (text: string): Detection => {
99
- if (!INTERROGATIVE.test(text)) return null;
100
-
101
- const lines = text
102
- .split("\n")
103
- .map((l) => l.trim())
104
- .filter(Boolean);
105
-
106
- const alphaAll = [...text.matchAll(/([a-dA-D])[.)]\s+([^\n]*?)(?=\s+[a-dA-D][.)]\s|$)/g)].map(
107
- (m) => ({ letter: m[1].toLowerCase(), choice: m[2].trim() }),
108
- );
109
- const alphaLines = lines
110
- .map((l) => /^([a-dA-D])[.)]\s+(.+)$/.exec(l))
111
- .filter((m): m is RegExpExecArray => Boolean(m))
112
- .map((m) => ({ letter: m[1].toLowerCase(), choice: m[2] }));
113
- const alpha = alphaAll.length >= alphaLines.length ? alphaAll : alphaLines;
114
-
115
- if (alpha.length >= 2) {
116
- const letters = alpha.map((a) => a.letter);
117
- const expected = ["a", "b", "c", "d"].slice(0, alpha.length);
118
- if (letters.every((l, i) => l === expected[i])) {
119
- return { choices: alpha.map((a) => a.choice), pattern: "alpha" };
120
- }
121
- }
122
-
123
- const numericAll = [...text.matchAll(/(\d+)[.)]\s+([^\n]*?)(?=\s+\d+[.)]\s|$)/g)].map((m) => ({
124
- num: Number(m[1]),
125
- choice: m[2].trim(),
126
- }));
127
- const numericLines = lines
128
- .map((l) => /^(\d+)[.)]\s+(.+)$/.exec(l))
129
- .filter((m): m is RegExpExecArray => Boolean(m))
130
- .map((m) => ({ num: Number(m[1]), choice: m[2] }));
131
- const numeric = numericAll.length >= numericLines.length ? numericAll : numericLines;
132
-
133
- if (numeric.length >= 2) {
134
- const nums = numeric.map((n) => n.num);
135
- if (nums.every((n, i) => n === i + 1)) {
136
- return { choices: numeric.map((n) => n.choice), pattern: "numeric" };
137
- }
138
- }
139
-
140
- return null;
141
- };
142
-
143
- const stripFences = (text: string): string => {
144
- const lines = text.split("\n");
145
- const out: string[] = [];
146
- let inFence = false;
147
- for (const line of lines) {
148
- if (line.startsWith("```")) {
149
- inFence = !inFence;
150
- continue;
151
- }
152
- if (!inFence) out.push(line);
153
- }
154
- return out.join("\n");
155
- };
156
-
157
- export const detectBacktickDocRefs = (text: string): string[] | null => {
158
- const body = stripFences(text);
159
- const refs = [...body.matchAll(/`docs\/[^`\s]+\.md`/g)].map((m) => m[0]);
160
- if (!refs.length) return null;
161
- if (/\[[^\]]+\]\(docs\//.test(body)) return null;
162
- return refs;
163
- };
164
-
165
- // The rail is active-plan detection (CA-11/CA-13): only a flow whose effective
166
- // execution is ACTIVE and subagent-driven is found. The effective read performs
167
- // the legacy compatibility migration (ledgerCompletion-derived, CA-16) and the
168
- // approval-digest reconciliation and PERSISTS any drift/migration reset, so a
169
- // drift-reset or pending/paused/completed flow is excluded after its state is
170
- // rewritten on read; only malformed/unreadable flow.json is excluded without
171
- // ever being rewritten (readFlowStrict rejects it before any write).
172
- export type ActivePlanScan = {
173
- slugs: string[];
174
- /**
175
- * Flows whose effective read FAILED with a transient lock/IO error
176
- * (flow_concurrent_conflict / flow_io_error) — a held lock or a filesystem
177
- * hiccup, NOT "not active". `findActiveSubagentDrivenPlans` still excludes
178
- * them (its `string[]` contract cannot express a read failure, so the
179
- * plugin rail stays fail-open by design); this signal lets a caller that
180
- * wants fail-closed behavior treat a non-empty list as "the plan state is
181
- * unknown". The coordinator's authoritative product gate
182
- * (assertProductGates) fails closed regardless, so legitimate interception
183
- * is never weakened.
184
- */
185
- read_errors: { slug: string; code: string; error: string }[];
186
- };
187
-
188
- export const scanActiveSubagentDrivenPlans = (root: string): ActivePlanScan => {
189
- const docsDir = path.join(root, "docs");
190
- if (!existsSync(docsDir)) return { slugs: [], read_errors: [] };
191
- const slugs: string[] = [];
192
- const readErrors: { slug: string; code: string; error: string }[] = [];
193
- // The full effective read (lock + digest hashing + possibly writing drift
194
- // resets) is the expensive path; it runs per slug on every message/tool call.
195
- const classify = (slug: string) => {
196
- let effective: FlowReadResult;
197
- try {
198
- effective = readEffectiveFlowState(root, slug);
199
- } catch {
200
- // an unexpected read error (e.g. a non-slug directory name) excludes the
201
- // entry without touching it
202
- return;
203
- }
204
- if (!effective.ok) {
205
- if (effective.code === "flow_concurrent_conflict" || effective.code === "flow_io_error") {
206
- readErrors.push({ slug, code: effective.code, error: effective.error });
207
- }
208
- return;
209
- }
210
- const exec = effective.state.execution;
211
- if (exec.status === "active" && exec.mode === "subagent-driven") slugs.push(slug);
212
- };
213
- for (const slug of readdirSync(docsDir)) {
214
- const file = path.join(docsDir, slug, "sdd", "flow.json");
215
- if (!existsSync(file)) continue;
216
- // Raw pre-filter (Task 2 advisory): a flow.json that cannot plausibly hold
217
- // an active subagent-driven execution is skipped with ONE cheap read.
218
- // Absence of the `subagent-driven` token makes an ACTIVE subagent-driven
219
- // execution impossible — an explicit execution requires mode
220
- // "subagent-driven" and legacy derivation (CA-16) requires menu.chosen
221
- // "subagent-driven", both embedding the literal token. The pre-filter can
222
- // only skip and never causes a false negative: an unreadable file or one
223
- // containing a backslash-u escape (hand-encoded, never produced by the
224
- // toolkit's own writers) is treated as in-doubt and runs the full read.
225
- let raw: string;
226
- try {
227
- raw = readFileSync(file, "utf8");
228
- } catch {
229
- classify(slug);
230
- continue;
231
- }
232
- if (!raw.includes("subagent-driven") && !raw.includes("\\u")) continue;
233
- classify(slug);
234
- }
235
- return { slugs, read_errors: readErrors };
236
- };
237
-
238
- export const findActiveSubagentDrivenPlans = (root: string): string[] =>
239
- scanActiveSubagentDrivenPlans(root).slugs;