xp-gate 0.5.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.
Files changed (90) hide show
  1. package/adapter-common.sh +192 -0
  2. package/adapters/cpp.sh +76 -0
  3. package/adapters/dart.sh +41 -0
  4. package/adapters/flutter.sh +41 -0
  5. package/adapters/go.sh +59 -0
  6. package/adapters/iac.sh +189 -0
  7. package/adapters/java.sh +191 -0
  8. package/adapters/kotlin.sh +77 -0
  9. package/adapters/objectivec.sh +38 -0
  10. package/adapters/powershell.sh +138 -0
  11. package/adapters/python.sh +104 -0
  12. package/adapters/shell.sh +55 -0
  13. package/adapters/swift.sh +44 -0
  14. package/adapters/typescript.sh +61 -0
  15. package/bin/xp-gate.js +157 -0
  16. package/hooks/adapter-common.sh +192 -0
  17. package/hooks/pre-commit +1667 -0
  18. package/hooks/pre-push +395 -0
  19. package/lib/__tests__/detect-deps.test.js +209 -0
  20. package/lib/__tests__/doctor.test.js +448 -0
  21. package/lib/__tests__/download-skill.test.js +281 -0
  22. package/lib/__tests__/init.test.js +327 -0
  23. package/lib/__tests__/install-skill.test.js +326 -0
  24. package/lib/__tests__/migrate.test.js +212 -0
  25. package/lib/__tests__/rollback.test.js +183 -0
  26. package/lib/__tests__/ui-detector.test.ts +200 -0
  27. package/lib/__tests__/uninstall-skill.test.js +189 -0
  28. package/lib/__tests__/uninstall.test.js +589 -0
  29. package/lib/__tests__/update-skill.test.js +276 -0
  30. package/lib/detect-deps.js +157 -0
  31. package/lib/doctor.js +370 -0
  32. package/lib/download-skill.js +96 -0
  33. package/lib/init.js +367 -0
  34. package/lib/install-skill.js +184 -0
  35. package/lib/migrate.js +120 -0
  36. package/lib/rollback.js +78 -0
  37. package/lib/ui-detector.ts +99 -0
  38. package/lib/uninstall-skill.js +69 -0
  39. package/lib/uninstall.js +401 -0
  40. package/lib/update-skill.js +90 -0
  41. package/package.json +39 -0
  42. package/plugins/claude-code/.claude-plugin/plugin.json +21 -0
  43. package/plugins/claude-code/bin/delphi-review-guard.sh +68 -0
  44. package/plugins/claude-code/bin/xp-gate-check +47 -0
  45. package/plugins/claude-code/hooks/hooks.json +37 -0
  46. package/skills/delphi-review/.delphi-config.json.example +45 -0
  47. package/skills/delphi-review/AGENTS.md +54 -0
  48. package/skills/delphi-review/INSTALL.md +152 -0
  49. package/skills/delphi-review/SKILL.md +371 -0
  50. package/skills/delphi-review/evals/evals.json +82 -0
  51. package/skills/delphi-review/opencode.json.delphi.example +56 -0
  52. package/skills/delphi-review/references/code-walkthrough.md +486 -0
  53. package/skills/ralph-loop/SKILL.md +330 -0
  54. package/skills/ralph-loop/evals/evals.json +311 -0
  55. package/skills/ralph-loop/evolution-history.json +59 -0
  56. package/skills/ralph-loop/evolution-log.md +16 -0
  57. package/skills/ralph-loop/references/components/memory.md +55 -0
  58. package/skills/ralph-loop/references/components/middleware.md +54 -0
  59. package/skills/ralph-loop/references/components/skill-invocations.md +39 -0
  60. package/skills/ralph-loop/references/components/system-prompt.md +24 -0
  61. package/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
  62. package/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
  63. package/skills/ralph-loop/templates/progress-log.md +36 -0
  64. package/skills/sprint-flow/SKILL.md +600 -0
  65. package/skills/sprint-flow/evals/evals.json +78 -0
  66. package/skills/sprint-flow/evolution-history.json +39 -0
  67. package/skills/sprint-flow/evolution-log.md +23 -0
  68. package/skills/sprint-flow/references/components/memory.md +87 -0
  69. package/skills/sprint-flow/references/components/middleware.md +72 -0
  70. package/skills/sprint-flow/references/components/skill-invocations.md +104 -0
  71. package/skills/sprint-flow/references/components/system-prompt.md +27 -0
  72. package/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
  73. package/skills/sprint-flow/references/phase-0-think.md +115 -0
  74. package/skills/sprint-flow/references/phase-1-plan.md +178 -0
  75. package/skills/sprint-flow/references/phase-2-build.md +198 -0
  76. package/skills/sprint-flow/references/phase-3-review.md +213 -0
  77. package/skills/sprint-flow/references/phase-4-uat.md +125 -0
  78. package/skills/sprint-flow/references/phase-5-feedback.md +100 -0
  79. package/skills/sprint-flow/references/phase-6-ship.md +193 -0
  80. package/skills/sprint-flow/references/phase-7-land.md +140 -0
  81. package/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
  82. package/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
  83. package/skills/sprint-flow/templates/pain-document-template.md +115 -0
  84. package/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
  85. package/skills/test-specification-alignment/AGENTS.md +59 -0
  86. package/skills/test-specification-alignment/SKILL.md +605 -0
  87. package/skills/test-specification-alignment/evals/evals.json +75 -0
  88. package/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
  89. package/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
  90. package/skills/test-specification-alignment/references/specification-format.md +348 -0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # TypeScript adapter for quality gates
4
+
5
+ run_static_analysis() {
6
+ if command -v npx >/dev/null 2>&1; then
7
+ echo "Running TypeScript static analysis..."
8
+ npx tsc --noEmit
9
+ return $?
10
+ else
11
+ echo "npx not available, skipping TypeScript static analysis"
12
+ return 0
13
+ fi
14
+ }
15
+
16
+ run_lint() {
17
+ if command -v npx >/dev/null 2>&1; then
18
+ echo "Running TypeScript linting..."
19
+ npx eslint . --ext .ts,.tsx
20
+ return $?
21
+ else
22
+ echo "npx not available, skipping TypeScript linting"
23
+ return 0
24
+ fi
25
+ }
26
+
27
+ run_tests() {
28
+ if command -v npx >/dev/null 2>&1; then
29
+ echo "Running TypeScript tests..."
30
+ if npx vitest --version >/dev/null 2>&1; then
31
+ npx vitest run
32
+ elif npx jest --version >/dev/null 2>&1; then
33
+ npx jest --passWithNoTests
34
+ else
35
+ echo "No test runner available (vitest or jest required)"
36
+ return 1
37
+ fi
38
+ return $?
39
+ else
40
+ echo "npx not available, skipping TypeScript tests"
41
+ return 0
42
+ fi
43
+ }
44
+
45
+ run_coverage() {
46
+ if command -v npx >/dev/null 2>&1; then
47
+ echo "Running TypeScript coverage..."
48
+ if npx vitest --version >/dev/null 2>&1; then
49
+ npx vitest run --coverage
50
+ elif npx jest --version >/dev/null 2>&1; then
51
+ npx jest --coverage
52
+ else
53
+ echo "No test runner available for coverage"
54
+ return 1
55
+ fi
56
+ return $?
57
+ else
58
+ echo "npx not available, skipping TypeScript coverage"
59
+ return 0
60
+ fi
61
+ }
package/bin/xp-gate.js ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+ const { init } = require('../lib/init.js');
3
+ const { installSkill } = require('../lib/install-skill.js');
4
+ const { updateSkill } = require('../lib/update-skill.js');
5
+ const { uninstallSkill } = require('../lib/uninstall-skill.js');
6
+ const { uninstall } = require('../lib/uninstall.js');
7
+ const { doctor } = require('../lib/doctor.js');
8
+ const { checkDeps } = require('../lib/detect-deps.js');
9
+ const { migrate } = require('../lib/migrate.js');
10
+
11
+ const COMMANDS = {
12
+ 'init': {
13
+ description: 'Initialize xp-gate (use --global for all projects)',
14
+ fn: init,
15
+ usage: 'xp-gate init [--global]'
16
+ },
17
+ 'setup-global': {
18
+ description: 'Set up xp-gate globally for all git projects',
19
+ fn: init,
20
+ usage: 'xp-gate setup-global'
21
+ },
22
+ 'install-skill': {
23
+ description: 'Install a xp-gate skill from GitHub',
24
+ fn: installSkill,
25
+ usage: 'xp-gate install-skill <name>[@<version>] [--offline] [--verbose] [--force]'
26
+ },
27
+ 'update-skill': {
28
+ description: 'Update installed skill(s)',
29
+ fn: updateSkill,
30
+ usage: 'xp-gate update-skill [<name>] [--all] [--check]'
31
+ },
32
+ 'uninstall-skill': {
33
+ description: 'Uninstall a xp-gate skill',
34
+ fn: uninstallSkill,
35
+ usage: 'xp-gate uninstall-skill <name> [--force]'
36
+ },
37
+ 'uninstall': {
38
+ description: 'Uninstall xp-gate (reverse of init)',
39
+ fn: uninstall,
40
+ usage: 'xp-gate uninstall [--dry-run] [--force] [--local|--global]'
41
+ },
42
+ 'migrate': {
43
+ description: 'Migrate from v0.4.x (GitHub Packages) to v0.5.x (public npm)',
44
+ fn: migrate,
45
+ usage: 'xp-gate migrate [--dry-run]'
46
+ },
47
+ 'doctor': {
48
+ description: 'Diagnose xp-gate installation health',
49
+ fn: doctor,
50
+ usage: 'xp-gate doctor [--fix]'
51
+ }
52
+ };
53
+
54
+ function printHelp() {
55
+ console.log('xp-gate - AI development workflow tool');
56
+ console.log('');
57
+ console.log('Usage: xp-gate <command> [options]');
58
+ console.log('');
59
+ console.log('Commands:');
60
+ for (const [name, cmd] of Object.entries(COMMANDS)) {
61
+ console.log(` ${name.padEnd(16)} ${cmd.description}`);
62
+ }
63
+ console.log('');
64
+ console.log('Options:');
65
+ console.log(' --version Show version');
66
+ console.log(' --help Show this help');
67
+ }
68
+
69
+ function main() {
70
+ const args = process.argv.slice(2);
71
+
72
+ if (args.includes('--version')) {
73
+ const pkg = require('../package.json');
74
+ console.log(`xp-gate v${pkg.version}`);
75
+ return;
76
+ }
77
+
78
+ if (args.includes('--help') || args.length === 0) {
79
+ printHelp();
80
+ return;
81
+ }
82
+
83
+ const command = args[0];
84
+ const subargs = args.slice(1);
85
+
86
+ if (command === 'init' || command === 'setup-global') {
87
+ const initArgs = command === 'setup-global' ? ['--global'] : subargs;
88
+ init(initArgs).then(code => process.exit(code));
89
+ return;
90
+ }
91
+
92
+ if (command === 'install-skill') {
93
+ const name = subargs[0];
94
+ if (!name) {
95
+ console.error('Error: Skill name required');
96
+ console.error('Usage: xp-gate install-skill <name>[@<version>]');
97
+ process.exit(1);
98
+ return;
99
+ }
100
+ const options = parseOptions(subargs.slice(1));
101
+ installSkill(name, options).then(code => process.exit(code));
102
+ return;
103
+ }
104
+
105
+ if (command === 'update-skill') {
106
+ const name = subargs[0];
107
+ const options = parseOptions(subargs.slice(1));
108
+ updateSkill(name, options).then(code => process.exit(code));
109
+ return;
110
+ }
111
+
112
+ if (command === 'uninstall-skill') {
113
+ const name = subargs[0];
114
+ if (!name) {
115
+ console.error('Error: Skill name required');
116
+ console.error('Usage: xp-gate uninstall-skill <name>');
117
+ process.exit(1);
118
+ return;
119
+ }
120
+ const options = parseOptions(subargs.slice(1));
121
+ uninstallSkill(name, options).then(code => process.exit(code));
122
+ return;
123
+ }
124
+
125
+ if (command === 'uninstall') {
126
+ uninstall(subargs).then(code => process.exit(code));
127
+ return;
128
+ }
129
+
130
+ if (command === 'migrate') {
131
+ migrate(subargs).then(code => process.exit(code));
132
+ return;
133
+ }
134
+
135
+ if (command === 'doctor') {
136
+ doctor(subargs).then(code => process.exit(code));
137
+ return;
138
+ }
139
+
140
+ console.error(`Unknown command: ${command}`);
141
+ printHelp();
142
+ process.exit(1);
143
+ }
144
+
145
+ function parseOptions(args) {
146
+ const options = { offline: false, verbose: false, force: false, all: false, check: false };
147
+ for (const arg of args) {
148
+ if (arg === '--offline') options.offline = true;
149
+ if (arg === '--verbose') options.verbose = true;
150
+ if (arg === '--force') options.force = true;
151
+ if (arg === '--all') options.all = true;
152
+ if (arg === '--check') options.check = true;
153
+ }
154
+ return options;
155
+ }
156
+
157
+ main();
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Common adapter functions for language detection and routing
4
+
5
+ detect_project_lang() {
6
+ if [[ -f "tsconfig.json" ]]; then
7
+ echo "typescript"
8
+ elif [[ -f "pyproject.toml" ]] || [[ -f "requirements.txt" ]] || [[ -f "setup.py" ]]; then
9
+ echo "python"
10
+ elif [[ -f "go.mod" ]]; then
11
+ echo "go"
12
+ elif [[ -f "build.gradle" ]] || [[ -f "build.gradle.kts" ]]; then
13
+ if [[ -n "$(find . -name "*.kt" -type f | head -n 1)" ]]; then
14
+ echo "kotlin"
15
+ else
16
+ echo "java"
17
+ fi
18
+ elif [[ -f "pom.xml" ]]; then
19
+ echo "java"
20
+ elif [[ -f "pubspec.yaml" ]]; then
21
+ if grep -q "flutter:" "pubspec.yaml" 2>/dev/null || [[ -f ".metadata" ]]; then
22
+ echo "flutter"
23
+ else
24
+ echo "dart"
25
+ fi
26
+ elif [[ -n "$(find . -name "*.ps1" -type f | head -n 1)" ]]; then
27
+ echo "powershell"
28
+ elif [[ -f "Package.swift" ]]; then
29
+ echo "swift"
30
+ elif [[ -f "CMakeLists.txt" ]] || [[ -n "$(find . -name "*.cpp" -o -name "*.cc" -type f | head -n 1)" ]]; then
31
+ echo "cpp"
32
+ elif [[ -n "$(find . -name "*.m" -o -name "*.mm" -type f | head -n 1)" ]]; then
33
+ echo "objectivec"
34
+ elif [[ -n "$(find . -name "*.sh" -type f | head -n 1)" ]] || [[ -n "$(find . -name "Dockerfile" -o -name "*.dockerfile" -type f | head -n 1)" ]]; then
35
+ echo "shell"
36
+ elif [[ -n "$(find . -name "*.ps1" -type f -not -path "./.git/*" | head -n 1)" ]]; then
37
+ echo "powershell"
38
+ else
39
+ if [[ -n "$(find . -name "*.ts" -o -name "*.tsx" -type f | head -n 1)" ]]; then
40
+ echo "typescript"
41
+ elif [[ -n "$(find . -name "*.py" -type f | head -n 1)" ]]; then
42
+ echo "python"
43
+ elif [[ -n "$(find . -name "*.go" -type f | head -n 1)" ]]; then
44
+ echo "go"
45
+ elif [[ -n "$(find . -name "*.kt" -type f | head -n 1)" ]]; then
46
+ echo "kotlin"
47
+ elif [[ -n "$(find . -name "*.java" -type f | head -n 1)" ]]; then
48
+ echo "java"
49
+ elif [[ -n "$(find . -name "*.dart" -type f | head -n 1)" ]]; then
50
+ if grep -q "flutter:" "pubspec.yaml" 2>/dev/null || [[ -f ".flutter" ]]; then
51
+ echo "flutter"
52
+ else
53
+ echo "dart"
54
+ fi
55
+ elif [[ -n "$(find . -name "*.swift" -type f | head -n 1)" ]]; then
56
+ echo "swift"
57
+ elif [[ -n "$(find . -name "*.cpp" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -type f | head -n 1)" ]]; then
58
+ echo "cpp"
59
+ elif [[ -n "$(find . -name "*.m" -o -name "*.mm" -type f | head -n 1)" ]]; then
60
+ echo "objectivec"
61
+ elif [[ -n "$(find . -name "*.sh" -type f | head -n 1)" ]]; then
62
+ echo "shell"
63
+ elif [[ -n "$(find . -name "*.ps1" -type f -not -path "./.git/*" | head -n 1)" ]]; then
64
+ echo "powershell"
65
+ else
66
+ echo "unknown"
67
+ fi
68
+ fi
69
+ }
70
+
71
+ route_to_adapter() {
72
+ local action="$1"
73
+ local lang
74
+ lang=$(detect_project_lang)
75
+
76
+ # Source the appropriate adapter
77
+ if [[ -f "githooks/adapters/${lang}.sh" ]]; then
78
+ # shellcheck source=githooks/adapters/"${lang}".sh
79
+ source "githooks/adapters/${lang}.sh"
80
+
81
+ # Execute the requested action
82
+ case "$action" in
83
+ "static_analysis") run_static_analysis ;;
84
+ "lint") run_lint ;;
85
+ "tests") run_tests ;;
86
+ "coverage") run_coverage ;;
87
+ *) return 1 ;;
88
+ esac
89
+ elif [[ -f "./githooks/adapters/${lang}.sh" ]]; then
90
+ # Alternative: source with ./ prefix
91
+ # shellcheck source=./githooks/adapters/"${lang}".sh
92
+ source "./githooks/adapters/${lang}.sh"
93
+
94
+ # Execute the requested action
95
+ case "$action" in
96
+ "static_analysis") run_static_analysis ;;
97
+ "lint") run_lint ;;
98
+ "tests") run_tests ;;
99
+ "coverage") run_coverage ;;
100
+ *) return 1 ;;
101
+ esac
102
+ else
103
+ echo "No adapter found for language: $lang"
104
+ return 1
105
+ fi
106
+ }
107
+
108
+ check_if_tool_available() {
109
+ local tool_name="$1"
110
+
111
+ # Check if command exists
112
+ if command -v "$tool_name" >/dev/null 2>&1; then
113
+ return 0
114
+ else
115
+ return 1
116
+ fi
117
+ }
118
+
119
+ require_tool() {
120
+ local tool_name="$1"
121
+ local gate_name="${2:-Gate}"
122
+ local install_hint="${3:-}"
123
+
124
+ if command -v "$tool_name" >/dev/null 2>&1; then
125
+ return 0
126
+ fi
127
+
128
+ if command -v npx >/dev/null 2>&1 && npx --no-install "$tool_name" --version >/dev/null 2>&1; then
129
+ return 0
130
+ fi
131
+
132
+ echo "❌ BLOCKED - Required tool '$tool_name' not available for $gate_name"
133
+ if [[ -n "$install_hint" ]]; then
134
+ echo " Install: $install_hint"
135
+ fi
136
+ echo " Per QUALITY-GATES-CODE-OF-CONDUCT.md: tool unavailable = BLOCK, not SKIP"
137
+ return 1
138
+ }
139
+
140
+ # Detect if project has IaC files (Terraform, Kubernetes, Docker)
141
+ detect_iac_project() {
142
+ local has_iac=false
143
+
144
+ # Check for Terraform files
145
+ if [[ -n "$(find . -maxdepth 2 -name "*.tf" -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
146
+ has_iac=true
147
+ fi
148
+
149
+ # Check for Kubernetes manifests (YAML with apiVersion/kind)
150
+ if [[ -n "$(find . -maxdepth 2 \( -name "*.yaml" -o -name "*.yml" \) -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
151
+ local yaml_file=$(find . -maxdepth 2 \( -name "*.yaml" -o -name "*.yml" \) -not -path "./.git/*" 2>/dev/null | head -1)
152
+ if grep -qE "^(apiVersion|kind):" "$yaml_file" 2>/dev/null; then
153
+ has_iac=true
154
+ fi
155
+ fi
156
+
157
+ # Check for Dockerfiles
158
+ if [[ -n "$(find . -maxdepth 2 -name "Dockerfile" -o -name "*.dockerfile" -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
159
+ has_iac=true
160
+ fi
161
+
162
+ if [ "$has_iac" = true ]; then
163
+ echo "iac"
164
+ else
165
+ echo ""
166
+ fi
167
+ }
168
+
169
+ # Stryker 9.x config files (new format, takes priority)
170
+ detect_mutation_testable() {
171
+ if [[ -f "stryker.config.mjs" ]] || [[ -f "stryker.config.js" ]] || \
172
+ [[ -f "stryker.config.cjs" ]] || [[ -f "stryker.config.json" ]]; then
173
+ if [[ -f "package.json" ]] && grep -qE '"@stryker-mutator[^"]*"' package.json 2>/dev/null; then
174
+ return 0
175
+ fi
176
+ if command -v npx >/dev/null 2>&1 && npx --no-install stryker --version >/dev/null 2>&1; then
177
+ return 0
178
+ fi
179
+ fi
180
+
181
+ # Legacy Stryker config files (backwards compatibility)
182
+ if [[ -f "stryker.conf.json" ]] || [[ -f "stryker.prepush.conf.json" ]]; then
183
+ if [[ -f "package.json" ]] && grep -qE '"@stryker-mutator[^"]*"' package.json 2>/dev/null; then
184
+ return 0
185
+ fi
186
+ if command -v npx >/dev/null 2>&1 && npx --no-install stryker --version >/dev/null 2>&1; then
187
+ return 0
188
+ fi
189
+ fi
190
+
191
+ return 1
192
+ }