@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,131 @@
1
+ # Command manifest: single source of truth for slash commands and pnpm scripts.
2
+ # help.sh builds the "Available commands" list from this file.
3
+ # Add a command by adding an entry; keep id, slash, pnpm, description, category.
4
+
5
+ commands:
6
+ # Project Management
7
+ - id: init-project
8
+ slash: /init-project
9
+ pnpm: init-project
10
+ description: Initialize a new ShipIt project
11
+ category: Project Management
12
+ - id: scope-project
13
+ slash: /scope-project
14
+ pnpm: scope-project
15
+ description: AI-assisted feature breakdown
16
+ category: Project Management
17
+
18
+ # Intent Management
19
+ - id: new-intent
20
+ slash: /new_intent
21
+ pnpm: new-intent
22
+ description: Create a new intent (interactive wizard)
23
+ category: Intent Management
24
+ - id: kill
25
+ slash: /kill
26
+ pnpm: kill-intent
27
+ description: Kill an intent with rationale
28
+ category: Intent Management
29
+
30
+ # Workflow
31
+ - id: ship
32
+ slash: /ship
33
+ pnpm: workflow-orchestrator
34
+ description: Run full SDLC workflow (6 phases)
35
+ category: Workflow
36
+ - id: verify
37
+ slash: /verify
38
+ pnpm: verify
39
+ description: Re-run verification phase
40
+ category: Workflow
41
+
42
+ # Planning
43
+ - id: generate-release-plan
44
+ slash: /generate-release-plan
45
+ pnpm: generate-release-plan
46
+ description: Build release plan from intents
47
+ category: Planning
48
+ - id: generate-roadmap
49
+ slash: /generate-roadmap
50
+ pnpm: generate-roadmap
51
+ description: Generate roadmap (now/next/later)
52
+ category: Planning
53
+
54
+ # Operations
55
+ - id: deploy
56
+ slash: /deploy
57
+ pnpm: deploy
58
+ description: Deploy with readiness checks
59
+ category: Operations
60
+ - id: drift-check
61
+ slash: /drift_check
62
+ pnpm: drift-check
63
+ description: Check for entropy/decay
64
+ category: Operations
65
+ - id: risk
66
+ slash: /risk
67
+ pnpm: null
68
+ description: Force security/threat skim
69
+ category: Operations
70
+
71
+ # Help & Status
72
+ - id: help
73
+ slash: /help
74
+ pnpm: help
75
+ description: Show help for a command
76
+ category: Help & Status
77
+ - id: status
78
+ slash: /status
79
+ pnpm: status
80
+ description: Show current project status
81
+ category: Help & Status
82
+ - id: suggest
83
+ slash: /suggest
84
+ pnpm: suggest
85
+ description: Get suggested next actions
86
+ category: Help & Status
87
+ - id: usage-record
88
+ slash: /usage-record
89
+ pnpm: usage-record
90
+ description: Record token/cost for a phase (intent_id phase tokens_in tokens_out [cost])
91
+ category: Help & Status
92
+ - id: usage-report
93
+ slash: /usage-report
94
+ pnpm: usage-report
95
+ description: Show token/cost usage table (optionally --last N)
96
+ category: Help & Status
97
+ - id: calibration-report
98
+ slash: /calibration-report
99
+ pnpm: calibration-report
100
+ description: Confidence calibration report (stated vs actual); --json for dashboard
101
+ category: Help & Status
102
+ - id: pr
103
+ slash: /pr
104
+ pnpm: null
105
+ description: Generate PR summary/checklist
106
+ category: Help & Status
107
+ - id: create-pr
108
+ slash: /create-pr
109
+ pnpm: gh-create-pr
110
+ description: Generate pr.md then create GitHub PR for intent
111
+ category: Help & Status
112
+ - id: create-intent-from-issue
113
+ slash: /create-intent-from-issue
114
+ pnpm: create-intent-from-issue
115
+ description: Create intent from GitHub issue
116
+ category: Intent Management
117
+ - id: revert-plan
118
+ slash: /revert-plan
119
+ pnpm: null
120
+ description: Write rollback plan
121
+ category: Help & Status
122
+ - id: rollback
123
+ slash: /rollback
124
+ pnpm: execute-rollback
125
+ description: Execute rollback in guided mode (reads plan from /revert-plan)
126
+ category: Workflow
127
+ - id: dashboard
128
+ slash: /dashboard
129
+ pnpm: dashboard
130
+ description: Start web dashboard (exports data first, then launches UI)
131
+ category: Help & Status
@@ -0,0 +1,110 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'EOF'
6
+ Usage:
7
+ ./scripts/create-test-plan-issue.sh \
8
+ --title "..." \
9
+ --severity low|medium|high \
10
+ --step "4-1" \
11
+ --expected "..." \
12
+ --actual "..." \
13
+ --error "..." \
14
+ --impl "Action item 1" \
15
+ [--impl "Action item 2"] \
16
+ [--repo owner/name]
17
+
18
+ Notes:
19
+ - If --repo is omitted, the script will try to resolve it via:
20
+ gh repo view --json nameWithOwner -q .nameWithOwner
21
+ - This script intentionally avoids literal '\n' sequences in the issue body.
22
+ EOF
23
+ }
24
+
25
+ TITLE=""
26
+ SEVERITY=""
27
+ STEP_ID=""
28
+ EXPECTED=""
29
+ ACTUAL=""
30
+ ERROR_TEXT=""
31
+ REPO=""
32
+ IMPL_ITEMS=()
33
+
34
+ while [ $# -gt 0 ]; do
35
+ case "$1" in
36
+ --title) TITLE="${2:-}"; shift 2 ;;
37
+ --severity) SEVERITY="${2:-}"; shift 2 ;;
38
+ --step) STEP_ID="${2:-}"; shift 2 ;;
39
+ --expected) EXPECTED="${2:-}"; shift 2 ;;
40
+ --actual) ACTUAL="${2:-}"; shift 2 ;;
41
+ --error) ERROR_TEXT="${2:-}"; shift 2 ;;
42
+ --impl) IMPL_ITEMS+=("${2:-}"); shift 2 ;;
43
+ --repo) REPO="${2:-}"; shift 2 ;;
44
+ -h|--help) usage; exit 0 ;;
45
+ *) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
46
+ esac
47
+ done
48
+
49
+ if [ -z "$TITLE" ] || [ -z "$SEVERITY" ] || [ -z "$STEP_ID" ] || [ -z "$EXPECTED" ] || [ -z "$ACTUAL" ] || [ -z "$ERROR_TEXT" ]; then
50
+ echo "Missing required arguments." >&2
51
+ usage
52
+ exit 2
53
+ fi
54
+
55
+ case "$SEVERITY" in
56
+ low|medium|high) ;;
57
+ *) echo "Invalid --severity: $SEVERITY (expected low|medium|high)" >&2; exit 2 ;;
58
+ esac
59
+
60
+ if ! command -v gh >/dev/null 2>&1; then
61
+ echo "gh is not installed (required)." >&2
62
+ exit 1
63
+ fi
64
+
65
+ gh auth status >/dev/null
66
+
67
+ if [ -z "$REPO" ]; then
68
+ REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || true)"
69
+ fi
70
+
71
+ if [ -z "$REPO" ]; then
72
+ echo "Could not resolve GitHub repo. Provide --repo owner/name." >&2
73
+ exit 1
74
+ fi
75
+
76
+ FIRST_SEEN="$(date +%F)"
77
+
78
+ BODY_FILE="$(mktemp)"
79
+ {
80
+ echo "**Severity:** $SEVERITY"
81
+ echo "**Step:** $STEP_ID"
82
+ echo "**First Seen:** $FIRST_SEEN"
83
+ echo
84
+ echo "## Expected"
85
+ echo
86
+ echo "$EXPECTED"
87
+ echo
88
+ echo "## Actual"
89
+ echo
90
+ echo "$ACTUAL"
91
+ echo
92
+ echo "## Error"
93
+ echo
94
+ echo "$ERROR_TEXT"
95
+ echo
96
+ echo "## Implementation"
97
+ echo
98
+ if [ "${#IMPL_ITEMS[@]}" -eq 0 ]; then
99
+ echo "- (none provided)"
100
+ else
101
+ for item in "${IMPL_ITEMS[@]}"; do
102
+ echo "- $item"
103
+ done
104
+ fi
105
+ } >"$BODY_FILE"
106
+
107
+ gh issue create --repo "$REPO" --title "$TITLE" --body-file "$BODY_FILE"
108
+
109
+ rm -f "$BODY_FILE"
110
+
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ # Start the ShipIt dashboard: export data first, then launch the dev server.
3
+ # Ensures fresh data whenever the dashboard is opened.
4
+ # Usage: ./scripts/dashboard-start.sh or pnpm dashboard
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
10
+ cd "$REPO_ROOT"
11
+
12
+ echo "Exporting dashboard data..."
13
+ node scripts/export-dashboard-json.js
14
+
15
+ echo "Starting dashboard dev server..."
16
+ cd dashboard-app && pnpm dev
@@ -0,0 +1,170 @@
1
+ #!/bin/bash
2
+
3
+ # Deployment Script
4
+ # Handles deployment to various platforms
5
+
6
+ set -euo pipefail
7
+
8
+ error_exit() {
9
+ echo "ERROR: $1" >&2
10
+ exit "${2:-1}"
11
+ }
12
+
13
+ warning() {
14
+ echo "WARNING: $1" >&2
15
+ }
16
+
17
+ # Colors
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ NC='\033[0m'
23
+
24
+ ENVIRONMENT="${1:-production}"
25
+ PLATFORM="${2:-}"
26
+
27
+ echo -e "${BLUE}Deploying to $ENVIRONMENT...${NC}"
28
+ echo ""
29
+
30
+ # Check prerequisites
31
+ if [ ! -f "project.json" ]; then
32
+ error_exit "project.json not found. Run /init-project first." 1
33
+ fi
34
+
35
+ # Run readiness checks
36
+ echo -e "${YELLOW}Running readiness checks...${NC}"
37
+ if [ -f "scripts/check-readiness.sh" ]; then
38
+ if ! ./scripts/check-readiness.sh "$ENVIRONMENT"; then
39
+ error_exit "Readiness checks failed. Fix issues before deploying." 1
40
+ fi
41
+ else
42
+ warning "check-readiness.sh not found, skipping checks"
43
+ fi
44
+ echo ""
45
+
46
+ # Determine platform
47
+ if [ -z "$PLATFORM" ]; then
48
+ if [ -f "vercel.json" ] || [ -f ".vercel/project.json" ]; then
49
+ PLATFORM="vercel"
50
+ elif [ -f "netlify.toml" ]; then
51
+ PLATFORM="netlify"
52
+ elif [ -f "Dockerfile" ]; then
53
+ PLATFORM="docker"
54
+ elif [ -d "infrastructure" ] && [ -f "infrastructure/cdk.json" ]; then
55
+ PLATFORM="aws-cdk"
56
+ else
57
+ echo -e "${YELLOW}Platform not detected. Available options:${NC}"
58
+ echo "1) Vercel"
59
+ echo "2) Netlify"
60
+ echo "3) Docker"
61
+ echo "4) AWS CDK"
62
+ echo "5) Manual (no automation)"
63
+ read -p "Select platform [1-5]: " platform_choice
64
+
65
+ case $platform_choice in
66
+ 1) PLATFORM="vercel" ;;
67
+ 2) PLATFORM="netlify" ;;
68
+ 3) PLATFORM="docker" ;;
69
+ 4) PLATFORM="aws-cdk" ;;
70
+ 5) PLATFORM="manual" ;;
71
+ *) PLATFORM="manual" ;;
72
+ esac
73
+ fi
74
+ fi
75
+
76
+ echo -e "${GREEN}Platform: $PLATFORM${NC}"
77
+ echo ""
78
+
79
+ # Create deployment history
80
+ DEPLOY_HISTORY="deployment-history.md"
81
+ if [ ! -f "$DEPLOY_HISTORY" ]; then
82
+ cat > "$DEPLOY_HISTORY" << EOF
83
+ # Deployment History
84
+
85
+ ## Deployments
86
+
87
+ EOF
88
+ fi
89
+
90
+ # Deploy based on platform
91
+ case $PLATFORM in
92
+ vercel)
93
+ echo -e "${YELLOW}Deploying to Vercel...${NC}"
94
+ if command -v vercel >/dev/null 2>&1; then
95
+ vercel --prod
96
+ else
97
+ error_exit "Vercel CLI not found. Install with: npm i -g vercel" 1
98
+ fi
99
+ ;;
100
+
101
+ netlify)
102
+ echo -e "${YELLOW}Deploying to Netlify...${NC}"
103
+ if command -v netlify >/dev/null 2>&1; then
104
+ netlify deploy --prod
105
+ else
106
+ error_exit "Netlify CLI not found. Install with: npm i -g netlify-cli" 1
107
+ fi
108
+ ;;
109
+
110
+ docker)
111
+ echo -e "${YELLOW}Building and deploying Docker image...${NC}"
112
+ if [ ! -f "Dockerfile" ]; then
113
+ error_exit "Dockerfile not found" 1
114
+ fi
115
+ IMAGE_NAME=$(jq -r '.name' project.json | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
116
+ docker build -t "$IMAGE_NAME:latest" .
117
+ echo -e "${GREEN}✓ Docker image built: $IMAGE_NAME:latest${NC}"
118
+ echo -e "${YELLOW}Note: Push and deploy manually or configure registry${NC}"
119
+ ;;
120
+
121
+ aws-cdk)
122
+ echo -e "${YELLOW}Deploying with AWS CDK...${NC}"
123
+ if [ ! -d "infrastructure" ]; then
124
+ error_exit "infrastructure directory not found" 1
125
+ fi
126
+ cd infrastructure || error_exit "Failed to enter infrastructure directory" 1
127
+ if command -v cdk >/dev/null 2>&1; then
128
+ cdk deploy --require-approval never
129
+ else
130
+ error_exit "AWS CDK CLI not found. Install with: npm i -g aws-cdk" 1
131
+ fi
132
+ cd ..
133
+ ;;
134
+
135
+ manual)
136
+ echo -e "${YELLOW}Manual deployment mode${NC}"
137
+ echo "Readiness checks passed. Deploy manually using your preferred method."
138
+ echo ""
139
+ echo "Suggested steps:"
140
+ echo "1. Build: pnpm build (or equivalent)"
141
+ echo "2. Test: pnpm test"
142
+ echo "3. Deploy using your platform's method"
143
+ ;;
144
+
145
+ *)
146
+ error_exit "Unknown platform: $PLATFORM" 1
147
+ ;;
148
+ esac
149
+
150
+ # Record deployment
151
+ DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
152
+ cat >> "$DEPLOY_HISTORY" << EOF
153
+ ### $DEPLOY_TIME - $ENVIRONMENT ($PLATFORM)
154
+ - Environment: $ENVIRONMENT
155
+ - Platform: $PLATFORM
156
+ - Status: deployed
157
+ - Readiness checks: passed
158
+
159
+ EOF
160
+
161
+ echo ""
162
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
163
+ echo -e "${GREEN}✓ Deployment complete${NC}"
164
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
165
+ echo ""
166
+ echo -e "${YELLOW}Next steps:${NC}"
167
+ echo "1. Verify deployment is healthy"
168
+ echo "2. Run smoke tests"
169
+ echo "3. Monitor logs and metrics"
170
+ echo ""
@@ -0,0 +1,93 @@
1
+ #!/bin/bash
2
+
3
+ # Drift Metrics Check Script
4
+ # Calculates entropy indicators to detect system drift
5
+
6
+ set -euo pipefail
7
+
8
+ # Error handling
9
+ error_exit() {
10
+ echo "ERROR: $1" >&2
11
+ exit "${2:-1}"
12
+ }
13
+
14
+ # Validate prerequisites
15
+ command -v git >/dev/null 2>&1 || error_exit "git is required but not installed"
16
+ command -v jq >/dev/null 2>&1 || error_exit "jq is required but not installed"
17
+ command -v bc >/dev/null 2>&1 || error_exit "bc is required but not installed"
18
+
19
+ DRIFT_DIR="_system/drift"
20
+ METRICS_FILE="$DRIFT_DIR/metrics.md"
21
+
22
+ # Create drift directory if it doesn't exist
23
+ mkdir -p "$DRIFT_DIR" || error_exit "Failed to create drift directory"
24
+
25
+ # Start metrics report
26
+ cat > "$METRICS_FILE" << EOF
27
+ # Drift Metrics Report
28
+
29
+ Generated: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
30
+
31
+ EOF
32
+
33
+ # 1. Average PR size (last 20 PRs)
34
+ echo "## PR Size Trend" >> "$METRICS_FILE" || error_exit "Failed to write to metrics file"
35
+ if git rev-parse --git-dir > /dev/null 2>&1; then
36
+ PR_SIZE=$(git log --oneline -20 --stat 2>/dev/null | grep "files changed" | \
37
+ awk '{sum+=$1; count++} END {if (count > 0) print "Avg files changed: " sum/count; else print "No PR data available"}' || echo "No PR data available")
38
+ echo "$PR_SIZE" >> "$METRICS_FILE" || error_exit "Failed to write PR size data"
39
+ else
40
+ echo "Not a git repository" >> "$METRICS_FILE" || error_exit "Failed to write git status"
41
+ fi
42
+ echo "" >> "$METRICS_FILE" || error_exit "Failed to write newline"
43
+
44
+ # 2. Test-to-code ratio (git-tracked only so node_modules/dist/build/reports are excluded)
45
+ echo "## Test-to-Code Ratio" >> "$METRICS_FILE"
46
+ if git rev-parse --git-dir > /dev/null 2>&1; then
47
+ TEST_FILES=$(git ls-files -- '*.test.ts' '*.spec.ts' 2>/dev/null | tr '\n' ' ')
48
+ CODE_FILES=$(git ls-files -- '*.ts' 2>/dev/null | grep -v -E '\.(test|spec)\.ts$' | tr '\n' ' ')
49
+ if [ -z "$TEST_FILES" ]; then TEST_LINES=0; else TEST_LINES=$(echo "$TEST_FILES" | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}' || echo "0"); fi
50
+ if [ -z "$CODE_FILES" ]; then CODE_LINES=0; else CODE_LINES=$(echo "$CODE_FILES" | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}' || echo "0"); fi
51
+ else
52
+ # Fallback: find with exclusions (no git or not a repo)
53
+ TEST_LINES=$(find . -type d \( -name node_modules -o -name dist -o -name build -o -name reports \) -prune -o -type f \( -name "*.test.ts" -o -name "*.spec.ts" \) -print 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}' || echo "0")
54
+ CODE_LINES=$(find . -type d \( -name node_modules -o -name dist -o -name build -o -name reports \) -prune -o -type f -name "*.ts" ! -name "*.test.ts" ! -name "*.spec.ts" -print 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}' || echo "0")
55
+ fi
56
+ if [ "${CODE_LINES:-0}" -gt 0 ]; then
57
+ RATIO=$(echo "scale=2; $TEST_LINES / $CODE_LINES" | bc 2>/dev/null || echo "N/A")
58
+ echo "Test lines: $TEST_LINES" >> "$METRICS_FILE"
59
+ echo "Code lines: $CODE_LINES" >> "$METRICS_FILE"
60
+ echo "Ratio: $RATIO" >> "$METRICS_FILE"
61
+ else
62
+ echo "No code found" >> "$METRICS_FILE"
63
+ fi
64
+ echo "" >> "$METRICS_FILE"
65
+
66
+ # 3. Dependency count
67
+ echo "## Dependency Growth" >> "$METRICS_FILE" || error_exit "Failed to write dependency section"
68
+ if [ -f "package.json" ]; then
69
+ DEPS=$(jq '.dependencies | length' package.json 2>/dev/null || echo "N/A")
70
+ DEV_DEPS=$(jq '.devDependencies | length' package.json 2>/dev/null || echo "N/A")
71
+ echo "Dependencies: $DEPS" >> "$METRICS_FILE" || error_exit "Failed to write dependencies"
72
+ echo "DevDependencies: $DEV_DEPS" >> "$METRICS_FILE" || error_exit "Failed to write devDependencies"
73
+ else
74
+ echo "No package.json found" >> "$METRICS_FILE" || error_exit "Failed to write package.json status"
75
+ fi
76
+ echo "" >> "$METRICS_FILE" || error_exit "Failed to write newline"
77
+
78
+ # 4. New files without intents
79
+ echo "## Untracked New Concepts" >> "$METRICS_FILE"
80
+ if git rev-parse --git-dir > /dev/null 2>&1; then
81
+ NEW_FILES=$(git diff --name-only HEAD~20 --diff-filter=A 2>/dev/null | grep -v "work/intent/" | head -10 || echo "No new files")
82
+ echo "$NEW_FILES" >> "$METRICS_FILE"
83
+ else
84
+ echo "Not a git repository" >> "$METRICS_FILE"
85
+ fi
86
+ echo "" >> "$METRICS_FILE"
87
+
88
+ # 5. CI Performance (placeholder)
89
+ echo "## CI Performance" >> "$METRICS_FILE"
90
+ echo "(Manually update from CI dashboard)" >> "$METRICS_FILE"
91
+ echo "" >> "$METRICS_FILE"
92
+
93
+ echo "Drift check complete. See $METRICS_FILE"
@@ -0,0 +1,177 @@
1
+ #!/bin/bash
2
+ # Execute rollback for an intent in guided mode.
3
+ # Reads rollback plan from work/workflow-state/ (flat or per-intent per workflow-state-layout).
4
+ # High-risk steps: display only. Safe steps: prompt [y/N], execute if confirmed.
5
+ # Audit log: work/workflow-state/rollback-log.md
6
+ # Usage: ./scripts/execute-rollback.sh <intent-id> [--dry-run]
7
+
8
+ set -euo pipefail
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+ cd "$REPO_ROOT"
13
+
14
+ # shellcheck source=scripts/lib/common.sh
15
+ . "$SCRIPT_DIR/lib/common.sh"
16
+
17
+ INTENT_ID=""
18
+ DRY_RUN=false
19
+
20
+ while [ $# -gt 0 ]; do
21
+ case "$1" in
22
+ --dry-run) DRY_RUN=true; shift ;;
23
+ -*)
24
+ error_exit "Unknown option: $1. Usage: $0 <intent-id> [--dry-run]" 1
25
+ ;;
26
+ *)
27
+ [ -z "$INTENT_ID" ] || error_exit "Multiple intent IDs given. Usage: $0 <intent-id> [--dry-run]" 1
28
+ INTENT_ID="$1"
29
+ shift
30
+ ;;
31
+ esac
32
+ done
33
+
34
+ [ -n "$INTENT_ID" ] || error_exit "Missing intent-id. Usage: $0 <intent-id> [--dry-run]" 1
35
+
36
+ WS="work/workflow-state"
37
+ LOG_FILE="$WS/rollback-log.md"
38
+
39
+ # Resolve rollback plan path per workflow-state-layout.md
40
+ resolve_rollback_plan() {
41
+ local per_intent="$WS/$INTENT_ID"
42
+ if [ -d "$per_intent" ]; then
43
+ if [ -f "$per_intent/rollback.md" ]; then
44
+ echo "$per_intent/rollback.md"
45
+ return 0
46
+ fi
47
+ if [ -f "$per_intent/02_plan.md" ]; then
48
+ echo "$per_intent/02_plan.md"
49
+ return 0
50
+ fi
51
+ fi
52
+ if [ -f "$WS/rollback.md" ]; then
53
+ echo "$WS/rollback.md"
54
+ return 0
55
+ fi
56
+ if [ -f "$WS/02_plan.md" ]; then
57
+ echo "$WS/02_plan.md"
58
+ return 0
59
+ fi
60
+ return 1
61
+ }
62
+
63
+ ROLLBACK_SOURCE="$(resolve_rollback_plan)" || error_exit "No rollback plan found. Run /revert-plan $INTENT_ID first." 1
64
+
65
+ # Extract rollback content: from rollback.md (full file) or from 02_plan.md (rollback section)
66
+ get_rollback_content() {
67
+ if [[ "$ROLLBACK_SOURCE" == *rollback.md ]]; then
68
+ cat "$ROLLBACK_SOURCE"
69
+ else
70
+ awk '/^#+[[:space:]]+[Rr]ollback|^#[[:space:]]+Rollback Plan/,/^## [^Rr]/ {print}' "$ROLLBACK_SOURCE" || cat "$ROLLBACK_SOURCE"
71
+ fi
72
+ }
73
+
74
+ # High-risk keywords: do NOT offer execution, display only
75
+ HIGH_RISK_PATTERNS="force|drop|delete|migration down|production|auth|secret|--force|-f |rm -r|rm -rf"
76
+
77
+ # Safe pattern: simple git revert (single sha, no force)
78
+ # Note: step is content AFTER the bullet "- ", so no leading dash
79
+ is_safe_git_revert() {
80
+ local step="$1"
81
+ [[ "$step" =~ ^git[[:space:]]+revert[[:space:]]+[a-fA-F0-9]+([[:space:]]*$|[[:space:]]+-m) ]] && \
82
+ ! echo "$step" | grep -qEi "$HIGH_RISK_PATTERNS"
83
+ }
84
+
85
+ is_high_risk() {
86
+ echo "$1" | grep -qEi "$HIGH_RISK_PATTERNS"
87
+ }
88
+
89
+ log_entry() {
90
+ local outcome="$1"
91
+ local step_preview="$2"
92
+ local truncated="${step_preview:0:100}"
93
+ local suffix=""
94
+ [ ${#step_preview} -gt 100 ] && suffix="..."
95
+ mkdir -p "$(dirname "$LOG_FILE")"
96
+ {
97
+ echo ""
98
+ echo "## $(date -u +"%Y-%m-%dT%H:%M:%SZ") - $INTENT_ID"
99
+ echo "- **Outcome:** $outcome"
100
+ echo "- **Step:** ${truncated}${suffix}"
101
+ echo ""
102
+ } >> "$LOG_FILE"
103
+ }
104
+
105
+ CONTENT="$(get_rollback_content)"
106
+
107
+ if [ -z "$CONTENT" ]; then
108
+ error_exit "Rollback plan is empty or has no rollback section." 1
109
+ fi
110
+
111
+ echo -e "${BLUE}Rollback Plan for $INTENT_ID${NC}"
112
+ echo -e "${BLUE}Source: $ROLLBACK_SOURCE${NC}"
113
+ echo ""
114
+
115
+ if [ "$DRY_RUN" = true ]; then
116
+ echo -e "${YELLOW}[DRY RUN] Would process the following steps:${NC}"
117
+ echo "$CONTENT" | grep -E '^[[:space:]]*- ' | sed 's/^/ /'
118
+ echo ""
119
+ echo "Run without --dry-run to execute (safe steps only, with confirmation)."
120
+ exit 0
121
+ fi
122
+
123
+ # Extract bullet steps (lines starting with - )
124
+ steps=()
125
+ while IFS= read -r line; do
126
+ if [[ "$line" =~ ^[[:space:]]*-[[:space:]]+(.+) ]]; then
127
+ steps+=("${BASH_REMATCH[1]}")
128
+ fi
129
+ done < <(echo "$CONTENT")
130
+
131
+ if [ ${#steps[@]} -eq 0 ]; then
132
+ echo "No bullet steps found in rollback plan. Displaying full plan:"
133
+ echo "$CONTENT"
134
+ exit 0
135
+ fi
136
+
137
+ echo "Before executing any step that touches production, infra, or data, ensure you have reviewed the rollback plan."
138
+ echo ""
139
+
140
+ for step in "${steps[@]}"; do
141
+ step_trimmed="${step#"${step%%[![:space:]]*}"}"
142
+ if [ -z "$step_trimmed" ]; then
143
+ continue
144
+ fi
145
+
146
+ if is_high_risk "$step_trimmed"; then
147
+ echo -e "${RED}[MANUAL]${NC} $step_trimmed"
148
+ echo " → Run this manually. Do not auto-execute."
149
+ log_entry "manual" "$step_trimmed"
150
+ continue
151
+ fi
152
+
153
+ if is_safe_git_revert "$step_trimmed"; then
154
+ echo -e "${YELLOW}[CONFIRM]${NC} $step_trimmed"
155
+ read -r -p "Run this? [y/N] " resp
156
+ if [[ "$resp" =~ ^[yY]$ ]]; then
157
+ sha="$(echo "$step_trimmed" | grep -oE '[a-fA-F0-9]{7,40}' | head -1)"
158
+ if [ -n "$sha" ] && git revert --no-edit "$sha"; then
159
+ echo -e "${GREEN}Done.${NC}"
160
+ log_entry "confirmed" "$step_trimmed"
161
+ else
162
+ echo -e "${RED}Failed. Run manually if needed.${NC}"
163
+ log_entry "failed" "$step_trimmed"
164
+ fi
165
+ else
166
+ echo "Skipped."
167
+ log_entry "skipped" "$step_trimmed"
168
+ fi
169
+ else
170
+ echo -e "${YELLOW}[MANUAL]${NC} $step_trimmed"
171
+ echo " → Not in safe allowlist. Run manually."
172
+ log_entry "manual" "$step_trimmed"
173
+ fi
174
+ echo ""
175
+ done
176
+
177
+ echo -e "${GREEN}Rollback flow complete. Log: $LOG_FILE${NC}"