@brainervirus/workit-core 0.10.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 -3048
  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 -426
  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
@@ -0,0 +1,183 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { isConfigObject, mergePreset, type BranchPreset, type ToolkitConfig } from "./config";
5
+
6
+ export type ConversionInput = {
7
+ configDir: string;
8
+ };
9
+
10
+ export type ConversionMapping = {
11
+ key: string;
12
+ from: unknown;
13
+ to: unknown;
14
+ note?: string;
15
+ };
16
+
17
+ export type ConversionUnresolved = {
18
+ key: string;
19
+ reason: string;
20
+ };
21
+
22
+ export type ConversionPreview = {
23
+ mappings: ConversionMapping[];
24
+ preserved: string[];
25
+ unresolved: ConversionUnresolved[];
26
+ };
27
+
28
+ const REDACT_KEYS = /token|secret|password|credential/i;
29
+
30
+ const readJsonObject = (file: string): Record<string, unknown> | null => {
31
+ if (!existsSync(file)) return null;
32
+ try {
33
+ const parsed = JSON.parse(readFileSync(file, "utf8"));
34
+ return isConfigObject(parsed) ? parsed : null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ };
39
+
40
+ const redactValue = (key: string, value: unknown): unknown => {
41
+ if (REDACT_KEYS.test(key)) return "[redacted]";
42
+ if (typeof value === "string" && value.length > 8 && !value.includes(" ")) return "[redacted]";
43
+ return value;
44
+ };
45
+
46
+ export const redactConversionPreview = (preview: ConversionPreview): ConversionPreview => ({
47
+ mappings: preview.mappings.map((m) => ({
48
+ ...m,
49
+ from: redactValue(m.key, m.from),
50
+ to: redactValue(m.key, m.to),
51
+ })),
52
+ preserved: preview.preserved,
53
+ unresolved: preview.unresolved,
54
+ });
55
+
56
+ export function previewConversion(input: ConversionInput): ConversionPreview {
57
+ const configFile = path.join(input.configDir, "config.json");
58
+ const config = readJsonObject(configFile);
59
+ const mappings: ConversionMapping[] = [];
60
+ const unresolved: ConversionUnresolved[] = [];
61
+ const preserved: string[] = [];
62
+
63
+ if (config) {
64
+ if (config.locale !== undefined) {
65
+ mappings.push({ key: "locale", from: config.locale, to: config.locale });
66
+ }
67
+ if (config.timezone !== undefined) {
68
+ mappings.push({ key: "timezone", from: config.timezone, to: config.timezone });
69
+ }
70
+ if (config.branchPolicy !== undefined && isConfigObject(config.branchPolicy)) {
71
+ const bp = config.branchPolicy as ToolkitConfig["branchPolicy"] & {
72
+ allowed?: string[];
73
+ protected?: string[];
74
+ };
75
+ const preset = (bp.preset ?? "gitflow") as BranchPreset;
76
+ const merged = mergePreset(
77
+ preset,
78
+ {
79
+ allowed: Array.isArray(bp.allowed) ? bp.allowed : undefined,
80
+ protectedNames: Array.isArray(bp.protected) ? bp.protected : undefined,
81
+ },
82
+ { branchPolicy: bp },
83
+ );
84
+ mappings.push({
85
+ key: "branchPolicy",
86
+ from: config.branchPolicy,
87
+ to: merged,
88
+ note: "preset-derived allowed/protected reset through mergePreset",
89
+ });
90
+ if (preset === "custom" && Array.isArray(bp.allowed)) {
91
+ if (bp.allowed.includes("*")) {
92
+ unresolved.push({
93
+ key: "branchPolicy.allowed",
94
+ reason: 'unsupported permissive value "*" requires an explicit v1 choice',
95
+ });
96
+ }
97
+ }
98
+ }
99
+ if (config.workflowMode !== undefined) {
100
+ unresolved.push({
101
+ key: "legacyWorkflowMode",
102
+ reason: "0.x workflow mode has no automatic v1 equivalent; choose how to continue",
103
+ });
104
+ }
105
+ }
106
+
107
+ for (const name of ["youtrack.json", "vcs.json", "workspaces.json"]) {
108
+ const file = path.join(input.configDir, name);
109
+ if (!existsSync(file)) continue;
110
+ const parsed = readJsonObject(file);
111
+ if (parsed)
112
+ mappings.push({ key: name, from: parsed, to: parsed, note: "carry forward unchanged" });
113
+ }
114
+
115
+ for (const token of ["youtrack.token", "gitlab.token", "github.token"]) {
116
+ const file = path.join(input.configDir, token);
117
+ if (existsSync(file)) preserved.push(file);
118
+ }
119
+
120
+ return { mappings, preserved, unresolved };
121
+ }
122
+
123
+ export const conversionDigest = (preview: ConversionPreview): string =>
124
+ createHash("sha256")
125
+ .update(JSON.stringify(redactConversionPreview(preview)))
126
+ .digest("hex");
127
+
128
+ export type ConversionApplyResult = {
129
+ configPath: string;
130
+ choicesPath: string;
131
+ };
132
+
133
+ /** Apply approved conversion mappings and record explicit resolution choices. */
134
+ export function applyConversionConfig(
135
+ configDir: string,
136
+ preview: ConversionPreview,
137
+ resolutions: Record<string, string>,
138
+ ): ConversionApplyResult {
139
+ const configFile = path.join(configDir, "config.json");
140
+ const raw = readJsonObject(configFile) ?? {};
141
+ const next: Record<string, unknown> = { ...raw };
142
+
143
+ for (const mapping of preview.mappings) {
144
+ if (mapping.key === "locale" || mapping.key === "timezone") {
145
+ next[mapping.key] = mapping.to;
146
+ }
147
+ if (mapping.key === "branchPolicy" && !resolutions["branchPolicy.allowed"]) {
148
+ next.branchPolicy = mapping.to;
149
+ }
150
+ }
151
+
152
+ if (resolutions["branchPolicy.allowed"]) {
153
+ const bp = isConfigObject(next.branchPolicy)
154
+ ? (next.branchPolicy as ToolkitConfig["branchPolicy"])
155
+ : { preset: "custom" as BranchPreset, allowed: [], protected: [] };
156
+ const preset = bp.preset ?? "custom";
157
+ next.branchPolicy = mergePreset(
158
+ preset,
159
+ {
160
+ allowed: resolutions["branchPolicy.allowed"]
161
+ .split(",")
162
+ .map((s) => s.trim())
163
+ .filter(Boolean),
164
+ },
165
+ { branchPolicy: bp },
166
+ );
167
+ }
168
+
169
+ if (resolutions["legacyWorkflowMode"]) {
170
+ delete next.workflowMode;
171
+ }
172
+
173
+ mkdirSync(configDir, { recursive: true });
174
+ writeFileSync(configFile, JSON.stringify(next, null, 2) + "\n");
175
+
176
+ const choicesPath = path.join(configDir, "cutover-choices.json");
177
+ writeFileSync(
178
+ choicesPath,
179
+ JSON.stringify({ resolutions, applied_at: new Date().toISOString() }, null, 2) + "\n",
180
+ );
181
+
182
+ return { configPath: configFile, choicesPath };
183
+ }
@@ -11,6 +11,7 @@ import os from "node:os";
11
11
  import path from "node:path";
12
12
  import type { Logger } from "./logger";
13
13
  import { EVENT, errorDetail } from "./boundary";
14
+ import type { CommitFlavorPreset } from "./commit-flavors";
14
15
 
15
16
  // Optional diagnostic seam: adapters install their host logger so config
16
17
  // migration and provenance events land in the same sanitized log stream.
@@ -27,6 +28,7 @@ export type ToolkitConfig = {
27
28
  localeOptions: string[];
28
29
  timezone: string;
29
30
  branchPolicy: { preset: BranchPreset; allowed: string[]; protected: string[] };
31
+ commitPolicy: { preset: CommitFlavorPreset; pattern?: string };
30
32
  };
31
33
 
32
34
  export const PRESETS: Record<BranchPreset, { allowed: string[]; protected: string[] }> = {
@@ -135,6 +137,7 @@ const DEFAULTS: ToolkitConfig = {
135
137
  allowed: [...PRESETS.gitflow.allowed],
136
138
  protected: [...PRESETS.gitflow.protected],
137
139
  },
140
+ commitPolicy: { preset: "conventional" },
138
141
  };
139
142
 
140
143
  const readSafe = (p: string): string | null => {
@@ -183,6 +186,11 @@ const parseConfigResult = (raw: string | null, file: string): ReaderResult<Toolk
183
186
  ? input.branchPolicy?.preset
184
187
  : "gitflow"
185
188
  ) as BranchPreset;
189
+ const commitPreset = (
190
+ COMMIT_PRESETS.includes(String(input.commitPolicy?.preset ?? ""))
191
+ ? input.commitPolicy?.preset
192
+ : "conventional"
193
+ ) as CommitFlavorPreset;
186
194
  return {
187
195
  status: "valid",
188
196
  path: file,
@@ -206,6 +214,12 @@ const parseConfigResult = (raw: string | null, file: string): ReaderResult<Toolk
206
214
  },
207
215
  DEFAULTS,
208
216
  ),
217
+ commitPolicy: {
218
+ preset: commitPreset,
219
+ ...(typeof input.commitPolicy?.pattern === "string"
220
+ ? { pattern: input.commitPolicy.pattern }
221
+ : {}),
222
+ },
209
223
  },
210
224
  };
211
225
  };
@@ -236,6 +250,7 @@ export type ConfigInput = {
236
250
  preset?: BranchPreset;
237
251
  allowed?: string[];
238
252
  protectedNames?: string[];
253
+ commitPolicy?: ToolkitConfig["commitPolicy"];
239
254
  };
240
255
 
241
256
  // RL-02: the single authoritative ToolkitConfig merge. CLI, OpenCode, and Cursor
@@ -246,6 +261,7 @@ export const mergeConfigValues = (input: ConfigInput, current: ToolkitConfig): T
246
261
  localeOptions: input.localeOptions ?? current.localeOptions,
247
262
  timezone: input.timezone ?? current.timezone,
248
263
  branchPolicy: mergePreset(input.preset ?? current.branchPolicy.preset, input, current),
264
+ commitPolicy: input.commitPolicy ?? current.commitPolicy,
249
265
  });
250
266
 
251
267
  export const writeConfig = (config: ToolkitConfig): void => {
@@ -315,3 +331,29 @@ export const resolveBranchPolicy = (
315
331
  preset === "github-flow" ? "main" : preset === "trunk-based" ? "master" : "develop",
316
332
  };
317
333
  };
334
+
335
+ const COMMIT_PRESETS: readonly string[] = [
336
+ "conventional",
337
+ "gitmoji",
338
+ "ticket-prefix",
339
+ "freeform",
340
+ "custom",
341
+ "auto",
342
+ ];
343
+
344
+ /** Workspace commitPolicy override wins, else global — mirrors
345
+ * resolveBranchPolicy's workspace > global order, including the invalid-preset
346
+ * fallback instead of a crash. */
347
+ export const resolveCommitPolicy = (
348
+ config: ToolkitConfig,
349
+ workspace?: { commitPolicy?: Record<string, any> } | null,
350
+ ): { preset: CommitFlavorPreset; pattern?: string } => {
351
+ const wp = (workspace?.commitPolicy ?? {}) as Record<string, any>;
352
+ if (COMMIT_PRESETS.includes(String(wp.preset ?? ""))) {
353
+ return {
354
+ preset: wp.preset as CommitFlavorPreset,
355
+ ...(typeof wp.pattern === "string" ? { pattern: wp.pattern } : {}),
356
+ };
357
+ }
358
+ return config.commitPolicy ?? ({ preset: "conventional" } as ToolkitConfig["commitPolicy"]);
359
+ };