@brainervirus/workit-core 0.4.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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/commands/wk-changelog.md +2 -0
  4. package/commands/wk-commit.md +2 -0
  5. package/commands/wk-docs-refresh.md +2 -0
  6. package/commands/wk-handoff.md +2 -0
  7. package/commands/wk-implement.md +2 -0
  8. package/commands/wk-init.md +2 -0
  9. package/commands/wk-issue-update.md +2 -0
  10. package/commands/wk-meetings.md +2 -0
  11. package/commands/wk-pr.md +2 -0
  12. package/commands/wk-release-notes.md +2 -0
  13. package/commands/wk-status.md +2 -0
  14. package/commands/wk-verify.md +2 -0
  15. package/package.json +43 -0
  16. package/scripts/_shared/common.sh +158 -0
  17. package/scripts/changelog-context.sh +42 -0
  18. package/scripts/docs-refresh-context.sh +40 -0
  19. package/scripts/fixtures/sample-plan.md +15 -0
  20. package/scripts/fixtures/sample-sdd/progress.md +2 -0
  21. package/scripts/init/apply.sh +5 -0
  22. package/scripts/init/status.sh +5 -0
  23. package/scripts/init/toolkit-status.sh +5 -0
  24. package/scripts/install-cursor-plugin.sh +83 -0
  25. package/scripts/install-opencode-plugin.sh +76 -0
  26. package/scripts/pr-create.sh +5 -0
  27. package/scripts/pr-ready-context.sh +88 -0
  28. package/scripts/present/ascii-wireframe.sh +5 -0
  29. package/scripts/present/flow-diagram.sh +5 -0
  30. package/scripts/release-notes-context.sh +40 -0
  31. package/scripts/rewrite-workspace-deps.ts +17 -0
  32. package/scripts/run-cursor-mcp.sh +10 -0
  33. package/scripts/sync-runtime.sh +96 -0
  34. package/scripts/update-superpowers.sh +56 -0
  35. package/scripts/vcs/config.sh +5 -0
  36. package/scripts/vcs/merged-style.sh +5 -0
  37. package/scripts/vcs/token-create-urls.sh +5 -0
  38. package/scripts/vcs/verify-token.sh +5 -0
  39. package/scripts/verify-project.sh +140 -0
  40. package/scripts/youtrack/api.sh +5 -0
  41. package/scripts/youtrack/config.sh +5 -0
  42. package/scripts/youtrack/greeting.sh +5 -0
  43. package/scripts/youtrack/parse-duration.sh +5 -0
  44. package/scripts/youtrack/token-create-url.sh +5 -0
  45. package/scripts/youtrack/verify-token.sh +5 -0
  46. package/scripts/youtrack/work-date-ms.sh +5 -0
  47. package/skills/wk-changelog/SKILL.md +15 -0
  48. package/skills/wk-commit/SKILL.md +16 -0
  49. package/skills/wk-docs-refresh/SKILL.md +15 -0
  50. package/skills/wk-handoff/SKILL.md +17 -0
  51. package/skills/wk-implement/SKILL.md +41 -0
  52. package/skills/wk-init/SKILL.md +31 -0
  53. package/skills/wk-issue-update/SKILL.md +27 -0
  54. package/skills/wk-issue-update/references/youtrack-update-style.md +81 -0
  55. package/skills/wk-meetings/SKILL.md +17 -0
  56. package/skills/wk-pr/SKILL.md +27 -0
  57. package/skills/wk-release-notes/SKILL.md +15 -0
  58. package/skills/wk-status/SKILL.md +16 -0
  59. package/skills/wk-verify/SKILL.md +16 -0
  60. package/src/core/branch.ts +246 -0
  61. package/src/core/changelog.ts +312 -0
  62. package/src/core/config-guard.ts +26 -0
  63. package/src/core/config.ts +73 -0
  64. package/src/core/detector.ts +207 -0
  65. package/src/core/doc-render.ts +14 -0
  66. package/src/core/docs-repo.ts +196 -0
  67. package/src/core/docs-validate.ts +255 -0
  68. package/src/core/flow-state.ts +225 -0
  69. package/src/core/git.ts +56 -0
  70. package/src/core/gitignore.ts +43 -0
  71. package/src/core/handoff-context.ts +115 -0
  72. package/src/core/hygiene.ts +77 -0
  73. package/src/core/init.ts +443 -0
  74. package/src/core/parse-sections.ts +24 -0
  75. package/src/core/plan-tasks.ts +33 -0
  76. package/src/core/ports/init-apply.ts +15 -0
  77. package/src/core/ports/init-status.ts +4 -0
  78. package/src/core/ports/init-toolkit-status.ts +4 -0
  79. package/src/core/ports/pr-create.ts +22 -0
  80. package/src/core/ports/present-ascii.ts +10 -0
  81. package/src/core/ports/present-flow.ts +10 -0
  82. package/src/core/ports/vcs-config.ts +14 -0
  83. package/src/core/ports/vcs-merged-style.ts +5 -0
  84. package/src/core/ports/vcs-token-create-urls.ts +4 -0
  85. package/src/core/ports/vcs-verify-token.ts +4 -0
  86. package/src/core/ports/youtrack-api.ts +17 -0
  87. package/src/core/ports/youtrack-config.ts +23 -0
  88. package/src/core/ports/youtrack-greeting.ts +10 -0
  89. package/src/core/ports/youtrack-parse-duration.ts +14 -0
  90. package/src/core/ports/youtrack-token-create-url.ts +4 -0
  91. package/src/core/ports/youtrack-verify-token.ts +12 -0
  92. package/src/core/ports/youtrack-work-date-ms.ts +10 -0
  93. package/src/core/pr-create.ts +212 -0
  94. package/src/core/present.ts +100 -0
  95. package/src/core/reminder.ts +82 -0
  96. package/src/core/repo-tool.ts +9 -0
  97. package/src/core/rules.ts +122 -0
  98. package/src/core/scripts.ts +42 -0
  99. package/src/core/sdd.ts +188 -0
  100. package/src/core/templates.ts +37 -0
  101. package/src/core/vcs-config.ts +252 -0
  102. package/src/core/verify-parse.ts +27 -0
  103. package/src/core/workspaces.ts +81 -0
  104. package/src/core/youtrack.ts +488 -0
  105. package/src/core.ts +62 -0
  106. package/src/state.ts +22 -0
  107. package/src/tools/docs-repo.ts +42 -0
  108. package/src/tools/flow.ts +88 -0
  109. package/src/tools/handoff.ts +160 -0
  110. package/src/tools/index.ts +22 -0
  111. package/src/tools/present.ts +45 -0
  112. package/src/tools/repo.ts +357 -0
  113. package/src/tools/rules.ts +30 -0
  114. package/src/tools/sdd.ts +189 -0
  115. package/src/tools/templates.ts +27 -0
  116. package/src/tools/youtrack.ts +356 -0
  117. package/templates/execution-contract.md +56 -0
  118. package/templates/greeting.md +1 -0
  119. package/templates/headers.md +3 -0
  120. package/templates/hygiene/.editorconfig +8 -0
  121. package/templates/hygiene/.gitattributes +3 -0
  122. package/templates/hygiene/CHANGELOG.md +14 -0
  123. package/templates/hygiene/CONTRIBUTING.md +3 -0
  124. package/templates/hygiene/LICENSE +21 -0
  125. package/templates/hygiene/README.md +3 -0
  126. package/templates/issue-update.md +6 -0
  127. package/templates/plan-template.md +25 -0
  128. package/templates/spec-template.md +51 -0
  129. package/templates/superpowers-doc-contract.md +69 -0
  130. package/vendor/superpowers/skills/brainstorming/SKILL.md +159 -0
  131. package/vendor/superpowers/skills/brainstorming/scripts/frame-template.html +213 -0
  132. package/vendor/superpowers/skills/brainstorming/scripts/helper.js +167 -0
  133. package/vendor/superpowers/skills/brainstorming/scripts/server.cjs +723 -0
  134. package/vendor/superpowers/skills/brainstorming/scripts/start-server.sh +209 -0
  135. package/vendor/superpowers/skills/brainstorming/scripts/stop-server.sh +120 -0
  136. package/vendor/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
  137. package/vendor/superpowers/skills/brainstorming/visual-companion.md +291 -0
  138. package/vendor/superpowers/skills/dispatching-parallel-agents/SKILL.md +185 -0
  139. package/vendor/superpowers/skills/executing-plans/SKILL.md +70 -0
  140. package/vendor/superpowers/skills/finishing-a-development-branch/SKILL.md +241 -0
  141. package/vendor/superpowers/skills/receiving-code-review/SKILL.md +213 -0
  142. package/vendor/superpowers/skills/requesting-code-review/SKILL.md +103 -0
  143. package/vendor/superpowers/skills/requesting-code-review/code-reviewer.md +172 -0
  144. package/vendor/superpowers/skills/subagent-driven-development/SKILL.md +418 -0
  145. package/vendor/superpowers/skills/subagent-driven-development/implementer-prompt.md +139 -0
  146. package/vendor/superpowers/skills/subagent-driven-development/scripts/review-package +44 -0
  147. package/vendor/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +22 -0
  148. package/vendor/superpowers/skills/subagent-driven-development/scripts/task-brief +40 -0
  149. package/vendor/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +188 -0
  150. package/vendor/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -0
  151. package/vendor/superpowers/skills/systematic-debugging/SKILL.md +296 -0
  152. package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  153. package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -0
  154. package/vendor/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -0
  155. package/vendor/superpowers/skills/systematic-debugging/find-polluter.sh +63 -0
  156. package/vendor/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -0
  157. package/vendor/superpowers/skills/systematic-debugging/test-academic.md +14 -0
  158. package/vendor/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -0
  159. package/vendor/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -0
  160. package/vendor/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -0
  161. package/vendor/superpowers/skills/test-driven-development/SKILL.md +371 -0
  162. package/vendor/superpowers/skills/test-driven-development/testing-anti-patterns.md +299 -0
  163. package/vendor/superpowers/skills/using-git-worktrees/SKILL.md +202 -0
  164. package/vendor/superpowers/skills/using-superpowers/SKILL.md +62 -0
  165. package/vendor/superpowers/skills/using-superpowers/references/antigravity-tools.md +23 -0
  166. package/vendor/superpowers/skills/using-superpowers/references/codex-tools.md +39 -0
  167. package/vendor/superpowers/skills/using-superpowers/references/pi-tools.md +16 -0
  168. package/vendor/superpowers/skills/verification-before-completion/SKILL.md +139 -0
  169. package/vendor/superpowers/skills/writing-plans/SKILL.md +174 -0
  170. package/vendor/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
  171. package/vendor/superpowers/skills/writing-skills/SKILL.md +689 -0
  172. package/vendor/superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -0
  173. package/vendor/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  174. package/vendor/superpowers/skills/writing-skills/graphviz-conventions.dot +172 -0
  175. package/vendor/superpowers/skills/writing-skills/persuasion-principles.md +187 -0
  176. package/vendor/superpowers/skills/writing-skills/render-graphs.js +168 -0
  177. package/vendor/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -0
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env bash
2
+ # Install OpenCode plugin: file:// pin to monorepo (or share clone) + native skill/command links.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
6
+ ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)"
7
+ SHARE="${HOME}/.local/share/workflow-toolkit"
8
+ DEV_DEFAULT="${HOME}/Documents/projects/personal/workflow-toolkit"
9
+ DEV="${WORKFLOW_TOOLKIT_DEV:-$DEV_DEFAULT}"
10
+ CONFIG="${HOME}/.config/opencode/opencode.json"
11
+
12
+ chmod +x "$ROOT/scripts/sync-runtime.sh"
13
+ WORKFLOW_TOOLKIT_DEV="$ROOT" "$ROOT/scripts/sync-runtime.sh"
14
+
15
+ # Prefer monorepo with .git. file:// pins skip opencode's bundled npm installer —
16
+ # git+file:// installs an EMPTY cache dir and fails silently, so the plugin never
17
+ # loads after restart. The pinned entry resolves via packages/workit-opencode/package.json main.
18
+ if [ -d "${DEV}/.git" ] && [ -f "${DEV}/packages/workit-opencode/src/plugin.ts" ]; then
19
+ PIN="file://${DEV}/packages/workit-opencode/src/plugin.ts"
20
+ elif [ -d "${SHARE}/.git" ] && [ -f "${SHARE}/packages/workit-opencode/src/plugin.ts" ]; then
21
+ PIN="file://${SHARE}/packages/workit-opencode/src/plugin.ts"
22
+ else
23
+ # Last resort: ensure share is a clone, then pin it
24
+ if [ ! -d "${SHARE}/.git" ]; then
25
+ TMP=$(mktemp -d)
26
+ git clone --depth 1 "git@github.com:${WORKFLOW_TOOLKIT_REPO:-BrainerVirus/workit}.git" "$TMP"
27
+ rsync -a --delete --exclude node_modules --exclude cursor/mcp/node_modules "$TMP/" "$SHARE/"
28
+ rm -rf "$TMP"
29
+ fi
30
+ PIN="file://${SHARE}/packages/workit-opencode/src/plugin.ts"
31
+ fi
32
+
33
+ mkdir -p "$(dirname "$CONFIG")"
34
+ [ -f "$CONFIG" ] || printf '%s\n' "{}" >"$CONFIG"
35
+
36
+ CONFIG_PATH="$CONFIG" PIN_PATH="$PIN" bun -e '
37
+ import fs from "node:fs";
38
+ const path = process.env.CONFIG_PATH!;
39
+ const pin = process.env.PIN_PATH!;
40
+ const data = JSON.parse(fs.readFileSync(path, "utf8"));
41
+ let plugins = data.plugin || [];
42
+ if (typeof plugins === "string") plugins = [plugins];
43
+ // Drop stale workflow-toolkit pins — the new file:// pin is written fresh.
44
+ data.plugin = plugins.filter((p) => !String(p).includes("workflow-toolkit"));
45
+ data.plugin.push(pin);
46
+ // Drop share skills.paths — native ~/.config/opencode/skills links avoid triple-load dups
47
+ const skills = data.skills;
48
+ if (skills && typeof skills === "object") {
49
+ skills.paths = (skills.paths || []).filter((p) => !String(p).includes("workflow-toolkit"));
50
+ data.skills = skills;
51
+ }
52
+ fs.writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
53
+ console.log("Pinned:", pin);
54
+ console.log("Native skills/commands via ~/.config/opencode/{skills,commands}");
55
+ '
56
+
57
+ # file:// pin already ships skills + registers /wk-* via plugin config.
58
+ # Remove leftover native links so OpenCode does not warn about duplicate skill names.
59
+ find "${HOME}/.config/opencode/skills" -maxdepth 1 -name 'wf-*' -exec rm -f {} + 2>/dev/null || true
60
+ find "${HOME}/.config/opencode/skill" -maxdepth 1 -name 'wf-*' -exec rm -f {} + 2>/dev/null || true
61
+ find "${HOME}/.config/opencode/commands" -maxdepth 1 -name 'wf-*.md' -exec rm -f {} + 2>/dev/null || true
62
+ find "${HOME}/.config/opencode/command" -maxdepth 1 -name 'wf-*.md' -exec rm -f {} + 2>/dev/null || true
63
+ rm -f "${HOME}/.config/opencode/plugins/workflow-toolkit.ts"
64
+ rm -rf "${HOME}/.cache/opencode/packages/workflow-toolkit-opencode@"* 2>/dev/null || true
65
+
66
+ # Post-install verification: file:// pins skip the installer, so a missing/empty
67
+ # pinned entry is a silent no-op. Fail loudly instead of pretending it worked.
68
+ PLUGIN_ENTRY="${PIN#file://}"
69
+ if [ ! -s "$PLUGIN_ENTRY" ]; then
70
+ echo "FATAL: pinned plugin entry missing or empty: $PLUGIN_ENTRY" >&2
71
+ echo "The file:// pin written to $CONFIG will not load after restart." >&2
72
+ echo "Restore the monorepo (or fix WORKFLOW_TOOLKIT_DEV) and re-run this script." >&2
73
+ exit 1
74
+ fi
75
+
76
+ echo "OpenCode install done. Fully quit all opencode processes, then restart."
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/pr-create.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../src/core/ports/pr-create.ts" "$@"
@@ -0,0 +1,88 @@
1
+ #!/bin/sh
2
+
3
+ set -u
4
+
5
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
6
+ . "$SCRIPT_DIR/_shared/common.sh"
7
+
8
+ cd "$(repo_root)" || exit 1
9
+
10
+ auto_range=false
11
+ if [ "${1:-}" != "" ]; then
12
+ range=$1
13
+ else
14
+ auto_range=true
15
+ if ! resolve_pr_branch_context; then
16
+ exit 1
17
+ fi
18
+ range=$PR_RANGE
19
+ fi
20
+
21
+ print_section "Repository"
22
+ printf 'root: %s\n' "$(pwd)"
23
+ printf 'branch: %s\n' "$(current_branch)"
24
+ printf 'range: %s\n' "$range"
25
+ if [ "$auto_range" = true ]; then
26
+ printf 'base_ref: %s\n' "$PR_BASE_REF"
27
+ printf 'merge_base: %s\n' "$PR_MERGE_BASE"
28
+ printf 'diff_range: %s\n' "$PR_DIFF_RANGE"
29
+ printf 'range_mode: branch-exclusive\n'
30
+ if [ "${PR_SYNC_NOTES:-}" != "" ]; then
31
+ printf 'git_sync: %s\n' "$PR_SYNC_NOTES"
32
+ fi
33
+ fi
34
+
35
+ print_section "Working Tree"
36
+ git status --short 2>&1 || true
37
+
38
+ print_section "Commits"
39
+ commit_log_for_range "$range"
40
+
41
+ diff_range=$range
42
+ if [ "$auto_range" = true ]; then
43
+ diff_range=$PR_DIFF_RANGE
44
+ fi
45
+
46
+ print_section "Diff Stat"
47
+ diff_stat_for_range "$diff_range"
48
+
49
+ print_section "Changed Files"
50
+ changed_files_for_range "$diff_range"
51
+
52
+ print_section "PR Template"
53
+ template=$(find_pr_template || true)
54
+ if [ "$template" != "" ]; then
55
+ printf 'template_path: %s\n\n' "$template"
56
+ sed -n '1,220p' "$template"
57
+ else
58
+ printf 'template_path: none\n\n'
59
+ fallback_pr_template
60
+ fi
61
+
62
+ print_section "Recent Validation Signals"
63
+ if [ -f package.json ]; then
64
+ printf 'package.json detected. Common scripts:\n'
65
+ node -e "const p=require('./package.json'); for (const k of ['lint','format:check','test','build']) if (p.scripts&&p.scripts[k]) console.log(k+': '+p.scripts[k])" 2>/dev/null || true
66
+ fi
67
+ if [ -f Cargo.toml ] || [ -f src-tauri/Cargo.toml ]; then
68
+ printf 'Rust project detected.\n'
69
+ fi
70
+
71
+ print_section "VCS Config"
72
+ RES=$(bash "$SCRIPT_DIR/vcs/config.sh" resolve 2>/dev/null || true)
73
+ if [ -n "$RES" ]; then
74
+ printf '%s\n' "$RES" | bun -e 'const r = JSON.parse(await Bun.stdin.text()); console.log("workspace: " + String(r.workspace_name || "none")); console.log("provider: " + String(r.provider || "gitlab"))'
75
+ fi
76
+ if bash "$SCRIPT_DIR/vcs/config.sh" summary 2>/dev/null; then
77
+ :
78
+ else
79
+ printf 'vcs: not configured — run /wk-init action vcs_scaffold\n'
80
+ fi
81
+
82
+ print_section "Merged PR Style"
83
+ STYLE=$(bash "$SCRIPT_DIR/vcs/merged-style.sh" 6 2>/dev/null || true)
84
+ if [ -n "$STYLE" ]; then
85
+ printf '%s\n' "$STYLE"
86
+ else
87
+ printf 'style_hints: Configure VCS token to load your recent merged MR/PR examples\n'
88
+ fi
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/present-ascii.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/present-ascii.ts"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/present-flow.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/present-flow.ts"
@@ -0,0 +1,40 @@
1
+ #!/bin/sh
2
+
3
+ set -u
4
+
5
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
6
+ . "$SCRIPT_DIR/_shared/common.sh"
7
+
8
+ cd "$(repo_root)" || exit 1
9
+
10
+ requested="${1:-}"
11
+ if [ -z "$requested" ]; then
12
+ printf 'ERROR: release tag or range required\n' >&2
13
+ exit 1
14
+ fi
15
+ range=$(range_arg_or_default "$requested")
16
+
17
+ print_section "Repository"
18
+ printf 'root: %s\n' "$(pwd)"
19
+ printf 'branch: %s\n' "$(current_branch)"
20
+ printf 'requested: %s\n' "${requested:-none}"
21
+ printf 'range: %s\n' "$range"
22
+
23
+ print_section "Tags"
24
+ git tag --sort=-creatordate 2>/dev/null | sed -n '1,20p' || true
25
+
26
+ print_section "Commits"
27
+ commit_log_for_range "$range"
28
+
29
+ print_section "Diff Stat"
30
+ diff_stat_for_range "$range"
31
+
32
+ print_section "Changed Files"
33
+ changed_files_for_range "$range"
34
+
35
+ print_section "Existing Release Files"
36
+ for path in CHANGELOG.md RELEASE_NOTES.md .github/releases.md; do
37
+ if [ -f "$path" ]; then
38
+ printf '%s\n' "$path"
39
+ fi
40
+ done
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bun
2
+ // Rewrite workspace:* core deps to ^<released version> in the platform packages
3
+ // before publish: neither npm nor bun rewrites the protocol, so a packed tarball
4
+ // with workspace:* silently drops the core dependency. Runs as semantic-release
5
+ // prepareCmd (after the version bumps, before the npm publish phase).
6
+ import { readFileSync, writeFileSync } from "node:fs";
7
+ import { resolve } from "node:path";
8
+
9
+ const root = process.argv[2] ? resolve(process.argv[2]) : resolve(import.meta.dir, "..", "..", "..");
10
+ const core = JSON.parse(readFileSync(resolve(root, "packages/workit-core/package.json"), "utf8"));
11
+ for (const pkg of ["workit-opencode", "workit-cursor", "workit-cli"]) {
12
+ const file = resolve(root, `packages/${pkg}/package.json`);
13
+ const data = JSON.parse(readFileSync(file, "utf8"));
14
+ if (data.dependencies?.["@brainervirus/workit-core"] !== "workspace:*") continue;
15
+ data.dependencies["@brainervirus/workit-core"] = `^${core.version}`;
16
+ writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`);
17
+ }
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ # Stable entrypoint for Cursor MCP deeplink / ~/.cursor/mcp.json
3
+ # Prefer the installed plugin copy (has node_modules); fall back to share.
4
+ set -euo pipefail
5
+ PLUGIN_MCP="${HOME}/.cursor/plugins/local/workflow-toolkit/mcp/run-server.sh"
6
+ SHARE_MCP="${HOME}/.local/share/workflow-toolkit/packages/workit-cursor/mcp/run-server.sh"
7
+ if [ -x "$PLUGIN_MCP" ]; then
8
+ exec "$PLUGIN_MCP" "$@"
9
+ fi
10
+ exec "$SHARE_MCP" "$@"
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env bash
2
+ # Sync workit runtime for Cursor + OpenCode.
3
+ # Prefer local monorepo (dev) when present; otherwise git-pull the share clone.
4
+ set -euo pipefail
5
+
6
+ SHARE="${HOME}/.local/share/workflow-toolkit"
7
+ PLUGIN_DIR="${HOME}/.cursor/plugins/local/workflow-toolkit"
8
+ OPENCODE_PLUGINS="${HOME}/.config/opencode/plugins"
9
+ DEV_DEFAULT="${HOME}/Documents/projects/personal/workflow-toolkit"
10
+ DEV="${WORKFLOW_TOOLKIT_DEV:-$DEV_DEFAULT}"
11
+ REPO_SLUG="${WORKFLOW_TOOLKIT_REPO:-BrainerVirus/workit}"
12
+ LOCK="${XDG_RUNTIME_DIR:-/tmp}/workflow-toolkit-sync.lock"
13
+
14
+ exec 9>"$LOCK"
15
+ if ! flock -n 9; then
16
+ exit 0
17
+ fi
18
+
19
+ SRC=""
20
+ if [ -f "${DEV}/packages/workit-opencode/src/plugin.ts" ] && [ -d "${DEV}/packages/workit-cursor/.cursor-plugin" ]; then
21
+ SRC="$DEV"
22
+ elif [ -d "${SHARE}/.git" ]; then
23
+ git -C "$SHARE" fetch --quiet origin 2>/dev/null || true
24
+ git -C "$SHARE" pull --ff-only --quiet origin main 2>/dev/null || true
25
+ SRC="$SHARE"
26
+ elif [ ! -d "${SHARE}/packages/workit-core/src" ]; then
27
+ mkdir -p "$(dirname "$SHARE")"
28
+ git clone --depth 1 "git@github.com:${REPO_SLUG}.git" "$SHARE" 2>/dev/null || exit 0
29
+ SRC="$SHARE"
30
+ else
31
+ SRC="$SHARE"
32
+ fi
33
+
34
+ if [ "$SRC" != "$SHARE" ]; then
35
+ mkdir -p "$SHARE"
36
+ # Keep .git if share is a clone; never wipe it when syncing from the monorepo
37
+ rsync -a --delete \
38
+ --exclude '.git' \
39
+ --exclude 'node_modules' \
40
+ --exclude 'cursor/mcp/node_modules' \
41
+ --exclude '.cache' \
42
+ "$SRC/" "$SHARE/"
43
+ fi
44
+
45
+ # Cursor IDE package (real directory)
46
+ mkdir -p "${HOME}/.cursor/plugins/local"
47
+ mkdir -p "$PLUGIN_DIR"
48
+ rsync -a --delete \
49
+ --exclude 'mcp/node_modules' \
50
+ "$SHARE/packages/workit-cursor/" "$PLUGIN_DIR/"
51
+ # Vendored skills for Cursor (same folder layout as OpenCode registration)
52
+ mkdir -p "$PLUGIN_DIR/vendor/superpowers"
53
+ if [ -d "$SHARE/packages/workit-core/vendor/superpowers/skills" ]; then
54
+ rsync -a --delete "$SHARE/packages/workit-core/vendor/superpowers/skills" "$PLUGIN_DIR/vendor/superpowers/"
55
+ fi
56
+ # Canonical user rules -> Cursor .mdc (compiled by the shared core)
57
+ CONFIG_RULES_DIR="${HOME}/.config/workflow-toolkit/rules"
58
+ if [ -d "$CONFIG_RULES_DIR" ]; then
59
+ "$HOME/.bun/bin/bun" -e "
60
+ import('${SHARE}/packages/workit-core/src/core/rules.ts').then(async ({ writeCompiledCursorRules }) => {
61
+ writeCompiledCursorRules('${PLUGIN_DIR}/rules');
62
+ });
63
+ " >/dev/null 2>&1 || true
64
+ fi
65
+ printf '%s\n' "$SHARE/packages/workit-core" >"$PLUGIN_DIR/.workflow-toolkit-root"
66
+ chmod +x "$PLUGIN_DIR/hooks/session-start" "$PLUGIN_DIR/mcp/run-server.sh" 2>/dev/null || true
67
+
68
+ if [ ! -d "$PLUGIN_DIR/mcp/node_modules" ]; then
69
+ (cd "$PLUGIN_DIR/mcp" && npm install --silent) || true
70
+ fi
71
+
72
+ # Share MCP also needs deps when launched via run-cursor-mcp fallback
73
+ if [ ! -d "$SHARE/packages/workit-cursor/mcp/node_modules" ]; then
74
+ (cd "$SHARE/packages/workit-cursor/mcp" && npm install --silent) || true
75
+ fi
76
+
77
+ # Remove broken TLA live-loader if present (OpenCode ignored it; /wk-* vanished)
78
+ rm -f "${OPENCODE_PLUGINS}/workflow-toolkit.ts"
79
+
80
+ # Ensure OpenCode has plugin peer dep
81
+ PKG="${HOME}/.config/opencode/package.json"
82
+ if [ -f "$PKG" ]; then
83
+ PKG_PATH="$PKG" bun -e '
84
+ import fs from "node:fs";
85
+ const path = process.env.PKG_PATH!;
86
+ const data = JSON.parse(fs.readFileSync(path, "utf8"));
87
+ data.dependencies = data.dependencies ?? {};
88
+ data.dependencies["@opencode-ai/plugin"] = data.dependencies["@opencode-ai/plugin"] ?? "1.17.7";
89
+ fs.writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
90
+ ' || true
91
+ fi
92
+
93
+ # Drop bun package cache so old github/file installs cannot shadow file:// plugin.ts
94
+ rm -rf "${HOME}/.cache/opencode/packages/workflow-toolkit-opencode@"* 2>/dev/null || true
95
+
96
+ exit 0
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+ # Re-sync vendored Superpowers skills from upstream. Never pushes or commits.
3
+ set -euo pipefail
4
+
5
+ REPO="https://github.com/obra/superpowers.git"
6
+ VENDOR="vendor/superpowers"
7
+ PIN=""
8
+ for arg in "$@"; do
9
+ case "$arg" in
10
+ --https) REPO="https://github.com/obra/superpowers.git" ;;
11
+ --ssh) REPO="git@github.com:obra/superpowers.git" ;;
12
+ --pin=*) PIN="${arg#--pin=}" ;;
13
+ *) if [ -z "$PIN" ]; then PIN="$arg"; fi ;;
14
+ esac
15
+ done
16
+
17
+ ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
18
+ STAGE="$(mktemp -d)"
19
+ trap 'rm -rf "$STAGE"' EXIT
20
+
21
+ echo "Cloning upstream..."
22
+ git clone --quiet --depth 1 "$REPO" "$STAGE/sp"
23
+ cd "$STAGE/sp"
24
+ if [ -n "$PIN" ]; then
25
+ git fetch --quiet --depth 1 origin "refs/tags/$PIN" 2>/dev/null || {
26
+ echo "ERROR: pin $PIN not found upstream" >&2
27
+ exit 1
28
+ }
29
+ git checkout --quiet "$PIN"
30
+ fi
31
+ VERSION="$(grep -m1 '"version"' package.json | sed -E 's/.*"version": "([^"]+)".*/\1/')"
32
+
33
+ cd "$ROOT"
34
+ rm -rf "$VENDOR/skills"
35
+ mkdir -p "$VENDOR"
36
+ cp -R "$STAGE/sp/skills" "$VENDOR/skills"
37
+
38
+ # Patch vendored skills to the toolkit's docs layout and contract rules.
39
+ # The upstream skills teach docs/superpowers/... and the forbidden
40
+ # "Two execution options" menu — both overridden by our contract.
41
+ find "$VENDOR/skills" -type f \( -name '*.md' -o -name '*.ts' \) -print0 | while IFS= read -r -d '' f; do
42
+ sed -i \
43
+ -e 's|docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md|docs/<slug>/plan.md|g' \
44
+ -e 's|docs/superpowers/plans/<filename>.md|docs/<slug>/plan.md|g' \
45
+ -e 's|docs/superpowers/plans/feature-plan.md|docs/<slug>/plan.md|g' \
46
+ -e 's|docs/superpowers/plans/deployment-plan.md|docs/deployment-plan/plan.md|g' \
47
+ -e 's|docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md|docs/<slug>/spec.md|g' \
48
+ -e 's|docs/superpowers/specs/|docs/<slug>/|g' \
49
+ -e 's|docs/superpowers/plans/|docs/<slug>/|g' \
50
+ -e 's|"Plan complete and saved to `docs/<slug>/plan.md`. Two execution options:\*\*|"Plan complete and saved to `docs/<slug>/plan.md`.**|g' \
51
+ "$f"
52
+ done
53
+
54
+ printf '%s\n' "$VERSION" > "$VENDOR/VERSION"
55
+ echo "Vendored superpowers $VERSION -> $VENDOR (patched to docs/<slug>/ layout)"
56
+ echo "Review with: git status && git diff --stat"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/vcs-config.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/vcs-config.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/vcs-merged-style.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/vcs-merged-style.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/vcs-token-create-urls.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/vcs-token-create-urls.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/vcs-verify-token.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/vcs-verify-token.ts" "$@"
@@ -0,0 +1,140 @@
1
+ #!/bin/sh
2
+
3
+ set -u
4
+
5
+ root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
6
+ cd "$root" || exit 1
7
+
8
+ dry_run=false
9
+ case " ${*:-} " in
10
+ *" --dry-run "*) dry_run=true ;;
11
+ *" dry-run "*) dry_run=true ;;
12
+ esac
13
+
14
+ passed=0
15
+ failed=0
16
+ skipped=0
17
+
18
+ run_check() {
19
+ label=$1
20
+ shift
21
+ printf '\n## %s\n\n' "$label"
22
+ printf 'command: %s\n\n' "$*"
23
+ if [ "$dry_run" = true ]; then
24
+ printf 'status: skipped (dry run)\n'
25
+ skipped=$((skipped + 1))
26
+ return 0
27
+ fi
28
+ "$@"
29
+ code=$?
30
+ if [ "$code" -eq 0 ]; then
31
+ printf '\nstatus: pass\n'
32
+ passed=$((passed + 1))
33
+ else
34
+ printf '\nstatus: fail (exit %s)\n' "$code"
35
+ failed=$((failed + 1))
36
+ fi
37
+ return 0
38
+ }
39
+
40
+ skip_check() {
41
+ label=$1
42
+ reason=$2
43
+ printf '\n## %s\n\nstatus: skipped (%s)\n' "$label" "$reason"
44
+ skipped=$((skipped + 1))
45
+ }
46
+
47
+ has_script() {
48
+ name=$1
49
+ [ -f package.json ] || return 1
50
+ node -e "const p=require('./package.json'); process.exit(p.scripts && p.scripts['$name'] ? 0 : 1)" >/dev/null 2>&1
51
+ }
52
+
53
+ package_runner() {
54
+ if [ -f pnpm-lock.yaml ] || grep -q '"packageManager"[[:space:]]*:[[:space:]]*"pnpm' package.json 2>/dev/null; then
55
+ printf 'pnpm'
56
+ elif [ -f yarn.lock ]; then
57
+ printf 'yarn'
58
+ elif [ -f package-lock.json ]; then
59
+ printf 'npm'
60
+ else
61
+ printf 'npm'
62
+ fi
63
+ }
64
+
65
+ printf '# Verification Context\n'
66
+ printf '\nroot: %s\n' "$root"
67
+ printf 'dry_run: %s\n' "$dry_run"
68
+
69
+ if [ -f package.json ]; then
70
+ runner=$(package_runner)
71
+ for script in lint format:check test build; do
72
+ if has_script "$script"; then
73
+ if [ "$runner" = "npm" ]; then
74
+ run_check "$script" npm run "$script"
75
+ else
76
+ run_check "$script" "$runner" "$script"
77
+ fi
78
+ else
79
+ skip_check "$script" "package.json has no $script script"
80
+ fi
81
+ done
82
+ else
83
+ skip_check "javascript" "package.json not found"
84
+ fi
85
+
86
+ cargo_manifest=""
87
+ if [ -f Cargo.toml ]; then
88
+ cargo_manifest="Cargo.toml"
89
+ elif [ -f src-tauri/Cargo.toml ]; then
90
+ cargo_manifest="src-tauri/Cargo.toml"
91
+ fi
92
+
93
+ if [ "$cargo_manifest" != "" ]; then
94
+ run_check "cargo fmt" cargo fmt --manifest-path "$cargo_manifest" -- --check
95
+ run_check "cargo clippy" cargo clippy --manifest-path "$cargo_manifest" --all-targets -- -D warnings
96
+ run_check "cargo test" cargo test --manifest-path "$cargo_manifest" --all-targets
97
+ else
98
+ skip_check "rust" "Cargo.toml not found"
99
+ fi
100
+
101
+ if [ -f pyproject.toml ] || [ -f pytest.ini ] || [ -d tests ]; then
102
+ if command -v pytest >/dev/null 2>&1; then
103
+ run_check "pytest" pytest
104
+ else
105
+ skip_check "pytest" "pytest not available"
106
+ fi
107
+ if command -v ruff >/dev/null 2>&1; then
108
+ run_check "ruff check" ruff check .
109
+ else
110
+ skip_check "ruff check" "ruff not available"
111
+ fi
112
+ fi
113
+
114
+ printf '\n## CHANGELOG.md format\n\n'
115
+ printf 'command: grep -qi "## [Unreleased]" CHANGELOG.md\n\n'
116
+
117
+ if [ "$dry_run" = true ]; then
118
+ printf 'status: skipped (dry run)\n'
119
+ skipped=$((skipped + 1))
120
+ elif [ -f CHANGELOG.md ]; then
121
+ if grep -qi '## \[Unreleased\]' CHANGELOG.md; then
122
+ printf 'status: pass\n'
123
+ passed=$((passed + 1))
124
+ else
125
+ printf 'status: fail (missing ## [Unreleased])\n'
126
+ failed=$((failed + 1))
127
+ fi
128
+ else
129
+ printf 'status: fail (missing CHANGELOG.md)\n'
130
+ failed=$((failed + 1))
131
+ fi
132
+
133
+ printf '\n# Summary\n\n'
134
+ printf 'passed: %s\n' "$passed"
135
+ printf 'failed: %s\n' "$failed"
136
+ printf 'skipped: %s\n' "$skipped"
137
+
138
+ if [ "$failed" -gt 0 ]; then
139
+ exit 1
140
+ fi
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-api.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-api.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-config.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-config.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-greeting.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-greeting.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-parse-duration.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-parse-duration.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-token-create-url.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-token-create-url.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-verify-token.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-verify-token.ts" "$@"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Ported to TS — CLI contract kept: execs bun <core>/ports/youtrack-work-date-ms.ts
3
+ set -euo pipefail
4
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
5
+ exec bun "$SCRIPT_DIR/../../src/core/ports/youtrack-work-date-ms.ts" "$@"
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: wk-changelog
3
+ description: Preview and apply a Keep a Changelog update.
4
+ ---
5
+
6
+ # Changelog
7
+
8
+ 1. Load this skill explicitly through OpenCode's `skill` tool.
9
+ 2. Call the read-only `workflow_changelog_context` context tool; its result is ground truth.
10
+ 3. Draft the exact insertion preview, including target heading, categories, and bullets.
11
+ 4. Use native `question` with concise choices and allow a custom answer before changing the file.
12
+ 5. Call `workflow_changelog_apply` only after approval with `confirmed: true`.
13
+ 6. Report the structured success, failure stage, or partial result; never infer success.
14
+
15
+ Target `## [Unreleased]` unless the user requests a release. Use only Added, Changed, Deprecated, Removed, Fixed, or Security; group user-visible behavior and skip internal-only work. The apply tool must merge into existing category headings, preserve all unrelated lines, and skip duplicate bullets. If normalization is needed, include it in the same preview and approval. Do not hand-edit the changelog, version packages, tag, or commit. `todowrite` and `task` are unnecessary here.