@nlaprell/shipit 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 (160) hide show
  1. package/.cursor/commands/create_intent_from_issue.md +28 -0
  2. package/.cursor/commands/create_pr.md +28 -0
  3. package/.cursor/commands/dashboard.md +39 -0
  4. package/.cursor/commands/deploy.md +152 -0
  5. package/.cursor/commands/drift_check.md +36 -0
  6. package/.cursor/commands/fix.md +39 -0
  7. package/.cursor/commands/generate_release_plan.md +31 -0
  8. package/.cursor/commands/generate_roadmap.md +38 -0
  9. package/.cursor/commands/help.md +37 -0
  10. package/.cursor/commands/init_project.md +26 -0
  11. package/.cursor/commands/kill.md +72 -0
  12. package/.cursor/commands/new_intent.md +68 -0
  13. package/.cursor/commands/pr.md +77 -0
  14. package/.cursor/commands/revert-plan.md +58 -0
  15. package/.cursor/commands/risk.md +64 -0
  16. package/.cursor/commands/rollback.md +43 -0
  17. package/.cursor/commands/scope_project.md +53 -0
  18. package/.cursor/commands/ship.md +345 -0
  19. package/.cursor/commands/status.md +71 -0
  20. package/.cursor/commands/suggest.md +44 -0
  21. package/.cursor/commands/test_shipit.md +197 -0
  22. package/.cursor/commands/verify.md +50 -0
  23. package/.cursor/rules/architect.mdc +84 -0
  24. package/.cursor/rules/assumption-extractor.mdc +95 -0
  25. package/.cursor/rules/docs.mdc +66 -0
  26. package/.cursor/rules/implementer.mdc +112 -0
  27. package/.cursor/rules/pm.mdc +136 -0
  28. package/.cursor/rules/qa.mdc +97 -0
  29. package/.cursor/rules/security.mdc +90 -0
  30. package/.cursor/rules/steward.mdc +99 -0
  31. package/.cursor/rules/test-runner.mdc +196 -0
  32. package/AGENTS.md +121 -0
  33. package/README.md +264 -0
  34. package/_system/architecture/CANON.md +159 -0
  35. package/_system/architecture/invariants.yml +87 -0
  36. package/_system/architecture/project-schema.json +98 -0
  37. package/_system/architecture/workflow-state-layout.md +68 -0
  38. package/_system/artifacts/SYSTEM_STATE.md +43 -0
  39. package/_system/artifacts/confidence-calibration.json +16 -0
  40. package/_system/artifacts/dependencies.md +46 -0
  41. package/_system/artifacts/framework-files-manifest.json +179 -0
  42. package/_system/artifacts/usage.json +1 -0
  43. package/_system/behaviors/DO_RELEASE.md +371 -0
  44. package/_system/behaviors/DO_RELEASE_AI.md +329 -0
  45. package/_system/behaviors/PREPARE_RELEASE.md +373 -0
  46. package/_system/behaviors/PREPARE_RELEASE_AI.md +234 -0
  47. package/_system/behaviors/WORK_ROOT_PLATFORM_ISSUES.md +140 -0
  48. package/_system/behaviors/WORK_TEST_PLAN_ISSUES.md +380 -0
  49. package/_system/do-not-repeat/abandoned-designs.md +18 -0
  50. package/_system/do-not-repeat/bad-patterns.md +19 -0
  51. package/_system/do-not-repeat/failed-experiments.md +18 -0
  52. package/_system/do-not-repeat/rejected-libraries.md +19 -0
  53. package/_system/drift/baselines.md +49 -0
  54. package/_system/drift/metrics.md +33 -0
  55. package/_system/golden-data/.gitkeep +0 -0
  56. package/_system/golden-data/README.md +47 -0
  57. package/_system/reports/mutation/mutation.html +492 -0
  58. package/_system/security/audit-allowlist.json +4 -0
  59. package/bin/create-shipit-app +29 -0
  60. package/bin/shipit +183 -0
  61. package/cli/src/commands/check.js +82 -0
  62. package/cli/src/commands/create.js +195 -0
  63. package/cli/src/commands/init.js +267 -0
  64. package/cli/src/commands/upgrade.js +196 -0
  65. package/cli/src/utils/config.js +27 -0
  66. package/cli/src/utils/file-copy.js +144 -0
  67. package/cli/src/utils/gitignore-merge.js +44 -0
  68. package/cli/src/utils/manifest.js +105 -0
  69. package/cli/src/utils/package-json-merge.js +163 -0
  70. package/cli/src/utils/project-json-merge.js +57 -0
  71. package/cli/src/utils/prompts.js +30 -0
  72. package/cli/src/utils/stack-detection.js +56 -0
  73. package/cli/src/utils/stack-files.js +364 -0
  74. package/cli/src/utils/upgrade-backup.js +159 -0
  75. package/cli/src/utils/version.js +64 -0
  76. package/dashboard-app/README.md +73 -0
  77. package/dashboard-app/eslint.config.js +23 -0
  78. package/dashboard-app/index.html +13 -0
  79. package/dashboard-app/package.json +30 -0
  80. package/dashboard-app/pnpm-lock.yaml +2721 -0
  81. package/dashboard-app/public/dashboard.json +66 -0
  82. package/dashboard-app/public/vite.svg +1 -0
  83. package/dashboard-app/src/App.css +141 -0
  84. package/dashboard-app/src/App.tsx +155 -0
  85. package/dashboard-app/src/assets/react.svg +1 -0
  86. package/dashboard-app/src/index.css +68 -0
  87. package/dashboard-app/src/main.tsx +10 -0
  88. package/dashboard-app/tsconfig.app.json +28 -0
  89. package/dashboard-app/tsconfig.json +4 -0
  90. package/dashboard-app/tsconfig.node.json +26 -0
  91. package/dashboard-app/vite.config.ts +7 -0
  92. package/package.json +116 -0
  93. package/scripts/README.md +70 -0
  94. package/scripts/audit-check.sh +125 -0
  95. package/scripts/calibration-report.sh +198 -0
  96. package/scripts/check-readiness.sh +155 -0
  97. package/scripts/collect-metrics.sh +116 -0
  98. package/scripts/command-manifest.yml +131 -0
  99. package/scripts/create-test-plan-issue.sh +110 -0
  100. package/scripts/dashboard-start.sh +16 -0
  101. package/scripts/deploy.sh +170 -0
  102. package/scripts/drift-check.sh +93 -0
  103. package/scripts/execute-rollback.sh +177 -0
  104. package/scripts/export-dashboard-json.js +208 -0
  105. package/scripts/fix-intents.sh +239 -0
  106. package/scripts/generate-dashboard.sh +136 -0
  107. package/scripts/generate-docs.sh +279 -0
  108. package/scripts/generate-project-context.sh +142 -0
  109. package/scripts/generate-release-plan.sh +443 -0
  110. package/scripts/generate-roadmap.sh +189 -0
  111. package/scripts/generate-system-state.sh +95 -0
  112. package/scripts/gh/create-intent-from-issue.sh +82 -0
  113. package/scripts/gh/create-issue-from-intent.sh +59 -0
  114. package/scripts/gh/create-pr.sh +41 -0
  115. package/scripts/gh/link-issue.sh +44 -0
  116. package/scripts/gh/on-ship-update-issue.sh +42 -0
  117. package/scripts/headless/README.md +8 -0
  118. package/scripts/headless/call-llm.js +109 -0
  119. package/scripts/headless/run-phase.sh +99 -0
  120. package/scripts/help.sh +271 -0
  121. package/scripts/init-project.sh +976 -0
  122. package/scripts/kill-intent.sh +125 -0
  123. package/scripts/lib/common.sh +29 -0
  124. package/scripts/lib/intent.sh +61 -0
  125. package/scripts/lib/progress.sh +57 -0
  126. package/scripts/lib/suggest-next.sh +131 -0
  127. package/scripts/lib/validate-intents.sh +240 -0
  128. package/scripts/lib/verify-outputs.sh +55 -0
  129. package/scripts/lib/workflow_state.sh +201 -0
  130. package/scripts/new-intent.sh +271 -0
  131. package/scripts/publish-npm.sh +28 -0
  132. package/scripts/scope-project.sh +380 -0
  133. package/scripts/setup-worktrees.sh +125 -0
  134. package/scripts/status.sh +278 -0
  135. package/scripts/suggest.sh +173 -0
  136. package/scripts/test-headless.sh +47 -0
  137. package/scripts/test-shipit.sh +52 -0
  138. package/scripts/test-workflow-state.sh +49 -0
  139. package/scripts/usage-report.sh +47 -0
  140. package/scripts/usage.sh +58 -0
  141. package/scripts/validate-cursor.sh +151 -0
  142. package/scripts/validate-project.sh +71 -0
  143. package/scripts/validate-vscode.sh +146 -0
  144. package/scripts/verify.sh +153 -0
  145. package/scripts/workflow-orchestrator.sh +97 -0
  146. package/scripts/workflow-templates/01_analysis.md.tpl +25 -0
  147. package/scripts/workflow-templates/02_plan.md.tpl +30 -0
  148. package/scripts/workflow-templates/03_implementation.md.tpl +25 -0
  149. package/scripts/workflow-templates/04_verification.md.tpl +29 -0
  150. package/scripts/workflow-templates/05_release_notes.md.tpl +16 -0
  151. package/scripts/workflow-templates/05_verification_legacy.md.tpl +6 -0
  152. package/scripts/workflow-templates/active.md.tpl +18 -0
  153. package/scripts/workflow-templates/phases.yml +39 -0
  154. package/stryker.conf.json +8 -0
  155. package/work/intent/templates/api-endpoint.md +124 -0
  156. package/work/intent/templates/bugfix.md +116 -0
  157. package/work/intent/templates/frontend-feature.md +115 -0
  158. package/work/intent/templates/generic.md +122 -0
  159. package/work/intent/templates/infra-change.md +121 -0
  160. package/work/intent/templates/refactor.md +116 -0
@@ -0,0 +1,58 @@
1
+ #!/bin/bash
2
+
3
+ # Record token-usage (or cost) for a phase/intent.
4
+ # Values are estimates unless source is "api" (e.g. from provider response).
5
+ # Usage: usage.sh <intent_id> <phase> <tokens_in> <tokens_out> [estimated_cost_usd] [source]
6
+ # Example: ./scripts/usage.sh F-001 analysis 1500 800
7
+ # Example: ./scripts/usage.sh F-001 plan 2000 1200 0.02 cursor_estimate
8
+
9
+ set -euo pipefail
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
13
+ cd "$REPO_ROOT"
14
+
15
+ # shellcheck source=scripts/lib/common.sh
16
+ . "$SCRIPT_DIR/lib/common.sh"
17
+
18
+ require_cmd jq
19
+
20
+ USAGE_FILE="_system/artifacts/usage.json"
21
+
22
+ if [ $# -lt 4 ]; then
23
+ echo "Usage: $0 <intent_id> <phase> <tokens_in> <tokens_out> [estimated_cost_usd] [source]" >&2
24
+ echo " source: cursor_estimate (default) | api" >&2
25
+ exit 1
26
+ fi
27
+
28
+ INTENT_ID="$1"
29
+ PHASE="$2"
30
+ TOKENS_IN="$3"
31
+ TOKENS_OUT="$4"
32
+ COST="${5:-null}"
33
+ SOURCE="${6:-cursor_estimate}"
34
+
35
+ if ! [[ "$TOKENS_IN" =~ ^[0-9]+$ ]] || ! [[ "$TOKENS_OUT" =~ ^[0-9]+$ ]]; then
36
+ error_exit "tokens_in and tokens_out must be non-negative integers" 1
37
+ fi
38
+
39
+ mkdir -p _system/artifacts
40
+
41
+ if [ ! -f "$USAGE_FILE" ]; then
42
+ echo '{"entries":[]}' > "$USAGE_FILE"
43
+ fi
44
+
45
+ TIMESTAMP_ISO="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
46
+ NEW_ENTRY=$(jq -n \
47
+ --arg intent_id "$INTENT_ID" \
48
+ --arg phase "$PHASE" \
49
+ --argjson tokens_in "$TOKENS_IN" \
50
+ --argjson tokens_out "$TOKENS_OUT" \
51
+ --argjson cost "$COST" \
52
+ --arg ts "$TIMESTAMP_ISO" \
53
+ --arg source "$SOURCE" \
54
+ '{ intent_id: $intent_id, phase: $phase, tokens_in: $tokens_in, tokens_out: $tokens_out, estimated_cost_usd: $cost, timestamp_iso: $ts, source: $source }')
55
+
56
+ jq --argjson entry "$NEW_ENTRY" '.entries += [$entry]' "$USAGE_FILE" > "$USAGE_FILE.nw" && mv "$USAGE_FILE.nw" "$USAGE_FILE"
57
+
58
+ echo "Recorded: $INTENT_ID $PHASE (in=$TOKENS_IN out=$TOKENS_OUT) source=$SOURCE"
@@ -0,0 +1,151 @@
1
+ #!/bin/bash
2
+
3
+ # Cursor Integration Validation Script
4
+ # Checks if Cursor recognizes .mdc files and slash commands
5
+
6
+ set -euo pipefail
7
+
8
+ error_exit() {
9
+ echo "ERROR: $1" >&2
10
+ exit "${2:-1}"
11
+ }
12
+
13
+ # Colors
14
+ GREEN='\033[0;32m'
15
+ YELLOW='\033[1;33m'
16
+ BLUE='\033[0;34m'
17
+ RED='\033[0;31m'
18
+ NC='\033[0m'
19
+
20
+ echo -e "${BLUE}Validating Cursor Integration...${NC}"
21
+ echo ""
22
+
23
+ PASSED=0
24
+ FAILED=0
25
+ WARNINGS=0
26
+
27
+ # Check 1: .mdc files exist
28
+ echo -e "${YELLOW}[1/6] Checking .mdc rule files...${NC}"
29
+ MDC_COUNT=$(find .cursor/rules -name "*.mdc" 2>/dev/null | wc -l | tr -d ' ')
30
+ if [ "$MDC_COUNT" -gt 0 ]; then
31
+ echo -e "${GREEN}✓ Found $MDC_COUNT .mdc rule files${NC}"
32
+ PASSED=$((PASSED + 1))
33
+ find .cursor/rules -name "*.mdc" | sed 's/^/ - /'
34
+ else
35
+ echo -e "${RED}✗ No .mdc rule files found${NC}"
36
+ FAILED=$((FAILED + 1))
37
+ fi
38
+ echo ""
39
+
40
+ # Check 2: Slash commands exist
41
+ echo -e "${YELLOW}[2/6] Checking slash command files...${NC}"
42
+ CMD_COUNT=$(find .cursor/commands -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
43
+ if [ "$CMD_COUNT" -gt 0 ]; then
44
+ echo -e "${GREEN}✓ Found $CMD_COUNT slash command files${NC}"
45
+ PASSED=$((PASSED + 1))
46
+ find .cursor/commands -name "*.md" | sed 's/^/ - /'
47
+ else
48
+ echo -e "${RED}✗ No slash command files found${NC}"
49
+ FAILED=$((FAILED + 1))
50
+ fi
51
+ echo ""
52
+
53
+ # Check 3: Required commands exist
54
+ echo -e "${YELLOW}[3/6] Checking required commands...${NC}"
55
+ REQUIRED_CMDS=("ship.md" "new_intent.md" "init_project.md" "scope_project.md" "deploy.md" "verify.md" "kill.md" "drift_check.md")
56
+ MISSING=0
57
+ for cmd in "${REQUIRED_CMDS[@]}"; do
58
+ if [ -f ".cursor/commands/$cmd" ]; then
59
+ echo -e " ${GREEN}✓${NC} $cmd"
60
+ else
61
+ echo -e " ${RED}✗${NC} $cmd (missing)"
62
+ MISSING=$((MISSING + 1))
63
+ fi
64
+ done
65
+ if [ $MISSING -eq 0 ]; then
66
+ PASSED=$((PASSED + 1))
67
+ else
68
+ FAILED=$((FAILED + 1))
69
+ fi
70
+ echo ""
71
+
72
+ # Check 4: Required rules exist
73
+ echo -e "${YELLOW}[4/6] Checking required rule files...${NC}"
74
+ REQUIRED_RULES=("steward.mdc" "pm.mdc" "architect.mdc" "implementer.mdc" "qa.mdc" "security.mdc" "docs.mdc")
75
+ MISSING=0
76
+ for rule in "${REQUIRED_RULES[@]}"; do
77
+ if [ -f ".cursor/rules/$rule" ]; then
78
+ echo -e " ${GREEN}✓${NC} $rule"
79
+ else
80
+ echo -e " ${RED}✗${NC} $rule (missing)"
81
+ MISSING=$((MISSING + 1))
82
+ fi
83
+ done
84
+ if [ $MISSING -eq 0 ]; then
85
+ PASSED=$((PASSED + 1))
86
+ else
87
+ FAILED=$((FAILED + 1))
88
+ fi
89
+ echo ""
90
+
91
+ # Check 5: Scripts are executable
92
+ echo -e "${YELLOW}[5/6] Checking script executability...${NC}"
93
+ SCRIPTS=("init-project.sh" "scope-project.sh" "deploy.sh" "workflow-orchestrator.sh")
94
+ MISSING=0
95
+ for script in "${SCRIPTS[@]}"; do
96
+ if [ -f "scripts/$script" ] && [ -x "scripts/$script" ]; then
97
+ echo -e " ${GREEN}✓${NC} $script"
98
+ else
99
+ echo -e " ${YELLOW}⚠${NC} $script (not executable or missing)"
100
+ MISSING=$((MISSING + 1))
101
+ WARNINGS=$((WARNINGS + 1))
102
+ fi
103
+ done
104
+ if [ $MISSING -eq 0 ]; then
105
+ PASSED=$((PASSED + 1))
106
+ else
107
+ WARNINGS=$((WARNINGS + 1))
108
+ fi
109
+ echo ""
110
+
111
+ # Check 6: Project structure
112
+ echo -e "${YELLOW}[6/6] Checking project structure...${NC}"
113
+ REQUIRED_DIRS=("intent" "workflow-state" "architecture" "scripts" ".cursor/rules" ".cursor/commands")
114
+ MISSING=0
115
+ for dir in "${REQUIRED_DIRS[@]}"; do
116
+ if [ -d "$dir" ]; then
117
+ echo -e " ${GREEN}✓${NC} $dir/"
118
+ else
119
+ echo -e " ${RED}✗${NC} $dir/ (missing)"
120
+ MISSING=$((MISSING + 1))
121
+ fi
122
+ done
123
+ if [ $MISSING -eq 0 ]; then
124
+ PASSED=$((PASSED + 1))
125
+ else
126
+ FAILED=$((FAILED + 1))
127
+ fi
128
+ echo ""
129
+
130
+ # Summary
131
+ echo -e "${BLUE}════════════════════════════════════════${NC}"
132
+ echo -e "${BLUE}Validation Summary${NC}"
133
+ echo -e "${BLUE}════════════════════════════════════════${NC}"
134
+ echo -e "${GREEN}Passed: $PASSED${NC}"
135
+ echo -e "${RED}Failed: $FAILED${NC}"
136
+ echo -e "${YELLOW}Warnings: $WARNINGS${NC}"
137
+ echo ""
138
+
139
+ if [ $FAILED -eq 0 ]; then
140
+ echo -e "${GREEN}✓ All checks passed!${NC}"
141
+ echo ""
142
+ echo -e "${YELLOW}Manual Validation Required:${NC}"
143
+ echo "1. Open Cursor and type '/' - verify commands appear"
144
+ echo "2. Try /ship F-001 - verify command works"
145
+ echo "3. Check if .mdc rules are recognized (Cursor may show them in settings)"
146
+ echo ""
147
+ exit 0
148
+ else
149
+ echo -e "${RED}✗ Some checks failed. Fix issues above.${NC}"
150
+ exit 1
151
+ fi
@@ -0,0 +1,71 @@
1
+ #!/bin/bash
2
+
3
+ # Validate project.json against schema
4
+
5
+ set -euo pipefail
6
+
7
+ error_exit() {
8
+ echo "ERROR: $1" >&2
9
+ exit "${2:-1}"
10
+ }
11
+
12
+ PROJECT_FILE="${1:-project.json}"
13
+
14
+ if [ ! -f "$PROJECT_FILE" ]; then
15
+ error_exit "Project file not found: $PROJECT_FILE" 1
16
+ fi
17
+
18
+ # Basic validation (check required fields)
19
+ echo "Validating $PROJECT_FILE..."
20
+
21
+ # Check if jq is available
22
+ if ! command -v jq >/dev/null 2>&1; then
23
+ echo "WARNING: jq not found, performing basic validation only"
24
+
25
+ # Basic checks
26
+ if ! grep -q '"name"' "$PROJECT_FILE"; then
27
+ error_exit "Missing required field: name" 1
28
+ fi
29
+
30
+ if ! grep -q '"version"' "$PROJECT_FILE"; then
31
+ error_exit "Missing required field: version" 1
32
+ fi
33
+
34
+ if ! grep -q '"techStack"' "$PROJECT_FILE"; then
35
+ error_exit "Missing required field: techStack" 1
36
+ fi
37
+
38
+ echo "✓ Basic validation passed"
39
+ exit 0
40
+ fi
41
+
42
+ # Advanced validation with jq
43
+ REQUIRED_FIELDS=("name" "version" "techStack" "created")
44
+
45
+ for field in "${REQUIRED_FIELDS[@]}"; do
46
+ if ! jq -e ".$field" "$PROJECT_FILE" >/dev/null 2>&1; then
47
+ error_exit "Missing required field: $field" 1
48
+ fi
49
+ done
50
+
51
+ # Validate techStack enum
52
+ TECH_STACK=$(jq -r '.techStack' "$PROJECT_FILE")
53
+ if [[ ! "$TECH_STACK" =~ ^(typescript-nodejs|python|other)$ ]]; then
54
+ error_exit "Invalid techStack: $TECH_STACK (must be typescript-nodejs, python, or other)" 1
55
+ fi
56
+
57
+ # Validate version format
58
+ VERSION=$(jq -r '.version' "$PROJECT_FILE")
59
+ if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
60
+ error_exit "Invalid version format: $VERSION (must be semantic version like 0.1.0)" 1
61
+ fi
62
+
63
+ # Validate settings if present
64
+ if jq -e '.settings' "$PROJECT_FILE" >/dev/null 2>&1; then
65
+ CONFIDENCE=$(jq -r '.settings.confidenceThreshold // 0.7' "$PROJECT_FILE")
66
+ if (( $(echo "$CONFIDENCE < 0 || $CONFIDENCE > 1" | bc -l) )); then
67
+ error_exit "Invalid confidenceThreshold: $CONFIDENCE (must be 0.0-1.0)" 1
68
+ fi
69
+ fi
70
+
71
+ echo "✓ Validation passed: $PROJECT_FILE"
@@ -0,0 +1,146 @@
1
+ #!/bin/bash
2
+
3
+ # VS Code + ShipIt Extension Validation Script
4
+ # Checks .cursor layout and project structure (same as Cursor). Run from repo root in VS Code.
5
+
6
+ set -euo pipefail
7
+
8
+ # Colors
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ RED='\033[0;31m'
13
+ NC='\033[0m'
14
+
15
+ echo -e "${BLUE}Validating VS Code / ShipIt integration...${NC}"
16
+ echo ""
17
+
18
+ PASSED=0
19
+ FAILED=0
20
+ WARNINGS=0
21
+
22
+ # Check 1: .mdc files exist
23
+ echo -e "${YELLOW}[1/6] Checking .mdc rule files...${NC}"
24
+ MDC_COUNT=$(find .cursor/rules -name "*.mdc" 2>/dev/null | wc -l | tr -d ' ')
25
+ if [ "$MDC_COUNT" -gt 0 ]; then
26
+ echo -e "${GREEN}✓ Found $MDC_COUNT .mdc rule files${NC}"
27
+ PASSED=$((PASSED + 1))
28
+ find .cursor/rules -name "*.mdc" | sed 's/^/ - /'
29
+ else
30
+ echo -e "${RED}✗ No .mdc rule files found${NC}"
31
+ FAILED=$((FAILED + 1))
32
+ fi
33
+ echo ""
34
+
35
+ # Check 2: Slash command files exist (extension reads these)
36
+ echo -e "${YELLOW}[2/6] Checking command files...${NC}"
37
+ CMD_COUNT=$(find .cursor/commands -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
38
+ if [ "$CMD_COUNT" -gt 0 ]; then
39
+ echo -e "${GREEN}✓ Found $CMD_COUNT command files${NC}"
40
+ PASSED=$((PASSED + 1))
41
+ find .cursor/commands -name "*.md" | sed 's/^/ - /'
42
+ else
43
+ echo -e "${RED}✗ No command files found${NC}"
44
+ FAILED=$((FAILED + 1))
45
+ fi
46
+ echo ""
47
+
48
+ # Check 3: Required commands exist
49
+ echo -e "${YELLOW}[3/6] Checking required commands...${NC}"
50
+ REQUIRED_CMDS=("ship.md" "new_intent.md" "init_project.md" "scope_project.md" "deploy.md" "verify.md" "kill.md" "drift_check.md")
51
+ MISSING=0
52
+ for cmd in "${REQUIRED_CMDS[@]}"; do
53
+ if [ -f ".cursor/commands/$cmd" ]; then
54
+ echo -e " ${GREEN}✓${NC} $cmd"
55
+ else
56
+ echo -e " ${RED}✗${NC} $cmd (missing)"
57
+ MISSING=$((MISSING + 1))
58
+ fi
59
+ done
60
+ if [ $MISSING -eq 0 ]; then
61
+ PASSED=$((PASSED + 1))
62
+ else
63
+ FAILED=$((FAILED + 1))
64
+ fi
65
+ echo ""
66
+
67
+ # Check 4: Required rules exist
68
+ echo -e "${YELLOW}[4/6] Checking required rule files...${NC}"
69
+ REQUIRED_RULES=("steward.mdc" "pm.mdc" "architect.mdc" "implementer.mdc" "qa.mdc" "security.mdc" "docs.mdc")
70
+ MISSING=0
71
+ for rule in "${REQUIRED_RULES[@]}"; do
72
+ if [ -f ".cursor/rules/$rule" ]; then
73
+ echo -e " ${GREEN}✓${NC} $rule"
74
+ else
75
+ echo -e " ${RED}✗${NC} $rule (missing)"
76
+ MISSING=$((MISSING + 1))
77
+ fi
78
+ done
79
+ if [ $MISSING -eq 0 ]; then
80
+ PASSED=$((PASSED + 1))
81
+ else
82
+ FAILED=$((FAILED + 1))
83
+ fi
84
+ echo ""
85
+
86
+ # Check 5: Scripts are executable
87
+ echo -e "${YELLOW}[5/6] Checking script executability...${NC}"
88
+ SCRIPTS=("init-project.sh" "scope-project.sh" "deploy.sh" "workflow-orchestrator.sh")
89
+ MISSING=0
90
+ for script in "${SCRIPTS[@]}"; do
91
+ if [ -f "scripts/$script" ] && [ -x "scripts/$script" ]; then
92
+ echo -e " ${GREEN}✓${NC} $script"
93
+ else
94
+ echo -e " ${YELLOW}⚠${NC} $script (not executable or missing)"
95
+ MISSING=$((MISSING + 1))
96
+ WARNINGS=$((WARNINGS + 1))
97
+ fi
98
+ done
99
+ if [ $MISSING -eq 0 ]; then
100
+ PASSED=$((PASSED + 1))
101
+ else
102
+ WARNINGS=$((WARNINGS + 1))
103
+ fi
104
+ echo ""
105
+
106
+ # Check 6: Project structure (work/ layout for ShipIt)
107
+ echo -e "${YELLOW}[6/6] Checking project structure...${NC}"
108
+ REQUIRED_DIRS=("work/intent" "work/workflow-state" "_system/architecture" "scripts" ".cursor/rules" ".cursor/commands")
109
+ MISSING=0
110
+ for dir in "${REQUIRED_DIRS[@]}"; do
111
+ if [ -d "$dir" ]; then
112
+ echo -e " ${GREEN}✓${NC} $dir/"
113
+ else
114
+ echo -e " ${RED}✗${NC} $dir/ (missing)"
115
+ MISSING=$((MISSING + 1))
116
+ fi
117
+ done
118
+ if [ $MISSING -eq 0 ]; then
119
+ PASSED=$((PASSED + 1))
120
+ else
121
+ FAILED=$((FAILED + 1))
122
+ fi
123
+ echo ""
124
+
125
+ # Summary
126
+ echo -e "${BLUE}════════════════════════════════════════${NC}"
127
+ echo -e "${BLUE}Validation Summary${NC}"
128
+ echo -e "${BLUE}════════════════════════════════════════${NC}"
129
+ echo -e "${GREEN}Passed: $PASSED${NC}"
130
+ echo -e "${RED}Failed: $FAILED${NC}"
131
+ echo -e "${YELLOW}Warnings: $WARNINGS${NC}"
132
+ echo ""
133
+
134
+ if [ $FAILED -eq 0 ]; then
135
+ echo -e "${GREEN}✓ All checks passed!${NC}"
136
+ echo ""
137
+ echo -e "${YELLOW}Manual validation (in VS Code):${NC}"
138
+ echo "1. Install the ShipIt extension (from vscode-extension/ or VSIX)."
139
+ echo "2. Open Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run e.g. \"ShipIt: Ship\"."
140
+ echo "3. Enter intent id when prompted; Copilot Chat should open with the same context as Cursor /ship."
141
+ echo ""
142
+ exit 0
143
+ else
144
+ echo -e "${RED}✗ Some checks failed. Fix issues above.${NC}"
145
+ exit 1
146
+ fi
@@ -0,0 +1,153 @@
1
+ #!/bin/bash
2
+
3
+ # Verification Script
4
+ # Runs verification checks and writes 04_verification.md (flat or per-intent per workflow-state-layout.md).
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ error_exit() {
10
+ echo "ERROR: $1" >&2
11
+ exit "${2:-1}"
12
+ }
13
+ # shellcheck source=lib/workflow_state.sh
14
+ [ -f "$SCRIPT_DIR/lib/workflow_state.sh" ] && source "$SCRIPT_DIR/lib/workflow_state.sh"
15
+
16
+ INTENT_ID="${1:-}"
17
+ if [ -z "$INTENT_ID" ]; then
18
+ error_exit "Usage: ./scripts/verify.sh <intent-id>" 1
19
+ fi
20
+
21
+ WORKFLOW_DIR="$(get_workflow_state_dir "$INTENT_ID")"
22
+ [ -n "$WORKFLOW_DIR" ] || error_exit "No workflow state dir for intent $INTENT_ID. Run /ship $INTENT_ID first." 1
23
+ mkdir -p "$WORKFLOW_DIR"
24
+
25
+ FAILED=0
26
+ TEST_STATUS="not run"
27
+ MUTATE_STATUS="not run"
28
+ AUDIT_STATUS="not run"
29
+
30
+ if command -v pnpm >/dev/null 2>&1; then
31
+ if pnpm test; then
32
+ TEST_STATUS="pass"
33
+ else
34
+ TEST_STATUS="fail"
35
+ FAILED=1
36
+ fi
37
+
38
+ if pnpm -s run test:mutate >/dev/null 2>&1; then
39
+ if pnpm test:mutate; then
40
+ MUTATE_STATUS="pass"
41
+ else
42
+ MUTATE_STATUS="fail"
43
+ FAILED=1
44
+ fi
45
+ else
46
+ MUTATE_STATUS="skipped (test:mutate not defined)"
47
+ fi
48
+
49
+ # Always run audit (no script gate). Use audit-level=high per verification requirements.
50
+ if [ -f "scripts/audit-check.sh" ]; then
51
+ if ./scripts/audit-check.sh high; then
52
+ AUDIT_STATUS="pass"
53
+ else
54
+ AUDIT_STATUS="fail (unlisted or expired advisories)"
55
+ FAILED=1
56
+ fi
57
+ else
58
+ if pnpm audit --audit-level=high; then
59
+ AUDIT_STATUS="pass"
60
+ else
61
+ AUDIT_STATUS="fail (high+ vulnerabilities)"
62
+ FAILED=1
63
+ fi
64
+ fi
65
+ else
66
+ error_exit "pnpm is required to run verification checks" 1
67
+ fi
68
+
69
+ cat > "$WORKFLOW_DIR/04_verification.md" << EOF
70
+ # Verification: $INTENT_ID
71
+
72
+ **Generated:** $(date -u +"%Y-%m-%dT%H:%M:%SZ")
73
+ **Intent:** $INTENT_ID
74
+
75
+ ## Test Results
76
+
77
+ - pnpm test: $TEST_STATUS
78
+ - pnpm test:mutate: $MUTATE_STATUS
79
+
80
+ ## Security Review
81
+
82
+ - pnpm audit --audit-level=high: $AUDIT_STATUS
83
+
84
+ ## Verification Status
85
+
86
+ $(if [ "$FAILED" -eq 0 ]; then echo "- [x] All checks pass"; else echo "- [ ] All checks pass"; fi)
87
+ - [ ] Ready for release
88
+ EOF
89
+
90
+ # Append to confidence-calibration.json if it exists
91
+ mkdir -p _system/artifacts
92
+ CALIBRATION_FILE="_system/artifacts/confidence-calibration.json"
93
+ if [ -f "$CALIBRATION_FILE" ] && command -v jq >/dev/null 2>&1; then
94
+ # Determine outcome
95
+ if [ "$FAILED" -eq 0 ]; then
96
+ OUTCOME="success"
97
+ else
98
+ OUTCOME="failure"
99
+ fi
100
+
101
+ # Generate next decision ID
102
+ LAST_ID=$(jq -r '.decisions[-1].id // "D-000"' "$CALIBRATION_FILE" 2>/dev/null || echo "D-000")
103
+ LAST_NUM=$(echo "$LAST_ID" | sed 's/D-//' | awk '{print int($1)}')
104
+ NEXT_NUM=$((LAST_NUM + 1))
105
+ NEXT_ID=$(printf "D-%03d" "$NEXT_NUM")
106
+
107
+ # Try to read stated_confidence from analysis file if available
108
+ STATED_CONFIDENCE="null"
109
+ ANALYSIS_FILE="$WORKFLOW_DIR/01_analysis.md"
110
+ if [ -f "$ANALYSIS_FILE" ]; then
111
+ # Try to extract confidence from analysis file (look for "Requirements clarity: X.XX" pattern)
112
+ CONF_LINE=$(grep -i "requirements clarity:" "$ANALYSIS_FILE" 2>/dev/null | head -1)
113
+ if [ -n "$CONF_LINE" ]; then
114
+ EXTRACTED_CONF=$(echo "$CONF_LINE" | grep -oE '[0-9]+\.[0-9]+' | head -1)
115
+ if [ -n "$EXTRACTED_CONF" ]; then
116
+ STATED_CONFIDENCE="$EXTRACTED_CONF"
117
+ fi
118
+ fi
119
+ fi
120
+
121
+ # Build notes
122
+ NOTES="Intent: $INTENT_ID. Tests: $TEST_STATUS, Mutation: $MUTATE_STATUS, Audit: $AUDIT_STATUS"
123
+
124
+ # Append new decision
125
+ if [ "$STATED_CONFIDENCE" != "null" ]; then
126
+ # Use --argjson when we have a numeric value
127
+ jq --arg id "$NEXT_ID" \
128
+ --argjson confidence "$STATED_CONFIDENCE" \
129
+ --arg outcome "$OUTCOME" \
130
+ --arg notes "$NOTES" \
131
+ '.decisions += [{
132
+ "id": $id,
133
+ "stated_confidence": $confidence,
134
+ "actual_outcome": $outcome,
135
+ "notes": $notes
136
+ }]' "$CALIBRATION_FILE" > "${CALIBRATION_FILE}.tmp" && \
137
+ mv "${CALIBRATION_FILE}.tmp" "$CALIBRATION_FILE" || true
138
+ else
139
+ # Use null explicitly when confidence is not available
140
+ jq --arg id "$NEXT_ID" \
141
+ --arg outcome "$OUTCOME" \
142
+ --arg notes "$NOTES" \
143
+ '.decisions += [{
144
+ "id": $id,
145
+ "stated_confidence": null,
146
+ "actual_outcome": $outcome,
147
+ "notes": $notes
148
+ }]' "$CALIBRATION_FILE" > "${CALIBRATION_FILE}.tmp" && \
149
+ mv "${CALIBRATION_FILE}.tmp" "$CALIBRATION_FILE" || true
150
+ fi
151
+ fi
152
+
153
+ exit "$FAILED"
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+
3
+ # Workflow Orchestrator Script
4
+ # Automates workflow state file generation from phase spec and templates.
5
+ # Phase list: scripts/workflow-templates/phases.yml. Add a phase there and a .tpl file.
6
+
7
+ set -euo pipefail
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ ORCHESTRATOR_DIR="$SCRIPT_DIR"
11
+ TEMPLATES_DIR="$SCRIPT_DIR/workflow-templates"
12
+ # shellcheck source=lib/intent.sh
13
+ [ -f "$SCRIPT_DIR/lib/intent.sh" ] && source "$SCRIPT_DIR/lib/intent.sh"
14
+ # shellcheck source=lib/workflow_state.sh (use ORCHESTRATOR_DIR so intent.sh doesn't overwrite SCRIPT_DIR)
15
+ [ -f "$ORCHESTRATOR_DIR/lib/workflow_state.sh" ] && source "$ORCHESTRATOR_DIR/lib/workflow_state.sh"
16
+
17
+ INTENT_ID="${1:-}"
18
+ if [ -z "$INTENT_ID" ]; then
19
+ error_exit "Usage: $0 <intent-id>" 1
20
+ fi
21
+
22
+ INTENT_FILE="$(require_intent_file "$INTENT_ID")"
23
+
24
+ # Resolve workflow dir: flat for single intent, per-intent for multiple (see workflow-state-layout.md).
25
+ WORKFLOW_DIR="$(ensure_workflow_state_dir "$INTENT_ID")"
26
+ [ -n "$WORKFLOW_DIR" ] || error_exit "Failed to resolve workflow state dir for $INTENT_ID" 1
27
+ mkdir -p "$WORKFLOW_DIR"
28
+
29
+ # Source progress library
30
+ if [ -f "$SCRIPT_DIR/lib/progress.sh" ]; then
31
+ source "$SCRIPT_DIR/lib/progress.sh"
32
+ fi
33
+
34
+ DATE_UTC="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
35
+ PHASE_COUNT=$(node -e "
36
+ const yaml = require('yaml');
37
+ const fs = require('fs');
38
+ const spec = yaml.parse(fs.readFileSync('$TEMPLATES_DIR/phases.yml', 'utf8'));
39
+ console.log(spec.phases.length);
40
+ ")
41
+
42
+ echo -e "${BLUE}Orchestrating workflow for $INTENT_ID...${NC}"
43
+ echo -e "${BLUE}Using intent file: ${INTENT_FILE}${NC}"
44
+ echo ""
45
+
46
+ phase_num=0
47
+ while IFS='|' read -r output_file template_file phase_name; do
48
+ [ -z "$output_file" ] && continue
49
+ phase_num=$((phase_num + 1))
50
+ if command -v show_phase_progress >/dev/null 2>&1; then
51
+ show_phase_progress "$phase_num" "$PHASE_COUNT" "$phase_name" "running"
52
+ else
53
+ echo -e "${YELLOW}[Phase $phase_num/$PHASE_COUNT] $phase_name... ⏳${NC}"
54
+ fi
55
+
56
+ template_path="$TEMPLATES_DIR/$template_file"
57
+ if [ ! -f "$template_path" ]; then
58
+ error_exit "Template not found: $template_path" 1
59
+ fi
60
+
61
+ # active.md lives at top level only; update it for this intent (multi-intent list).
62
+ if [ "$output_file" = "active.md" ]; then
63
+ append_or_set_active_intent "$INTENT_ID" "$phase_name" || true
64
+ if command -v show_phase_progress >/dev/null 2>&1; then
65
+ show_phase_progress "$phase_num" "$PHASE_COUNT" "$phase_name" "complete"
66
+ else
67
+ echo -e "${GREEN}✓ Updated $WS_BASE/active.md${NC}"
68
+ fi
69
+ else
70
+ sed -e "s/{{INTENT_ID}}/$INTENT_ID/g" -e "s/{{DATE_UTC}}/$DATE_UTC/g" "$template_path" > "$WORKFLOW_DIR/$output_file" \
71
+ || error_exit "Failed to create $WORKFLOW_DIR/$output_file" 1
72
+
73
+ if command -v show_phase_progress >/dev/null 2>&1; then
74
+ show_phase_progress "$phase_num" "$PHASE_COUNT" "$phase_name" "complete"
75
+ else
76
+ echo -e "${GREEN}✓ Created $WORKFLOW_DIR/$output_file${NC}"
77
+ fi
78
+ fi
79
+ done < <(node -e "
80
+ const yaml = require('yaml');
81
+ const fs = require('fs');
82
+ const spec = yaml.parse(fs.readFileSync('$TEMPLATES_DIR/phases.yml', 'utf8'));
83
+ spec.phases.forEach(p => console.log(p.output + '|' + p.template + '|' + (p.name || '')));
84
+ ")
85
+
86
+ echo ""
87
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
88
+ echo -e "${GREEN}✓ Workflow state files created${NC}"
89
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
90
+ echo ""
91
+ echo -e "${YELLOW}Next steps:${NC}"
92
+ echo "1. Fill in $WORKFLOW_DIR/01_analysis.md (PM role)"
93
+ echo "2. Fill in $WORKFLOW_DIR/02_plan.md (Architect role)"
94
+ echo "3. Fill in $WORKFLOW_DIR/03_implementation.md (Implementer role)"
95
+ echo "4. Fill in $WORKFLOW_DIR/04_verification.md (QA + Security roles)"
96
+ echo "5. Fill in $WORKFLOW_DIR/05_release_notes.md (Docs + Steward roles)"
97
+ echo ""