jettypod 4.1.2 → 4.1.4
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.
- package/.nvmrc +1 -0
- package/docs/COMPLETE-TESTING-STRATEGY.md +970 -0
- package/docs/DECISIONS.md +10 -12
- package/docs/NODE_VERSION.md +83 -0
- package/docs/TDD-INFRASTRUCTURE-STRATEGY.md +1374 -0
- package/docs/TESTING-FOR-NON-ENGINEERS.md +1588 -0
- package/docs/TESTING-STRATEGY-AUDIT.md +698 -0
- package/hooks/post-checkout +17 -0
- package/hooks/post-merge +17 -0
- package/hooks/pre-commit +30 -0
- package/jettypod.js +259 -120
- package/lib/coverage-tracker.js +218 -0
- package/lib/database.js +2 -0
- package/lib/db-export.js +192 -0
- package/lib/db-import.js +193 -0
- package/lib/external-transition-handler.js +32 -0
- package/lib/git-hook-helpers.js +174 -0
- package/lib/git-root.js +90 -0
- package/lib/infrastructure-chore-generator.js +45 -0
- package/lib/install-hooks.js +52 -0
- package/lib/jettypod-backup.js +238 -0
- package/lib/merge-lock.js +193 -0
- package/lib/migrations/012-add-worktree-path.js +38 -0
- package/lib/migrations/013-worktrees-table.js +86 -0
- package/lib/migrations/014-migrate-worktree-data.js +161 -0
- package/lib/migrations/015-merge-locks-table.js +67 -0
- package/lib/pattern-finder.js +152 -0
- package/lib/process-manager.js +140 -0
- package/lib/production-standards-reader.js +13 -2
- package/lib/production-standards-writer.js +85 -0
- package/lib/skills/feature-planning/dry-run-validator.js +135 -0
- package/lib/skills/feature-planning/validation-formatter.js +160 -0
- package/lib/smart-conflict-detection.js +168 -0
- package/lib/smart-fetch-rebase.js +614 -0
- package/lib/step-definition-parser.js +76 -0
- package/lib/unit-test-generator.js +232 -0
- package/lib/verification-command-generator.js +66 -0
- package/lib/worktree-diagnostics.js +413 -0
- package/lib/worktree-facade.js +174 -0
- package/lib/worktree-manager.js +636 -0
- package/lib/worktree-reconciler.js +429 -0
- package/package.json +30 -3
- package/skills-templates/external-transition/SKILL.md +34 -3
- package/skills-templates/feature-planning/SKILL.md +190 -24
- package/skills-templates/production-mode/SKILL.md +127 -9
- package/skills-templates/speed-mode/SKILL.md +454 -51
- package/skills-templates/stable-mode/SKILL.md +285 -76
- package/.claude/PROTECT_SKILLS.md +0 -28
- package/.claude/settings.json +0 -24
- package/.claude/settings.local.json +0 -16
- package/.claude/skills/epic-planning/SKILL.md +0 -297
- package/.claude/skills/external-transition/SKILL.md +0 -384
- package/.claude/skills/feature-planning/SKILL.md +0 -464
- package/.claude/skills/production-mode/SKILL.md +0 -369
- package/.claude/skills/speed-mode/SKILL.md +0 -481
- package/.claude/skills/stable-mode/SKILL.md +0 -713
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T16-15-10-070Z/epic-discover/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/stable-mode/SKILL.md +0 -673
- package/.devpod/current-work.json +0 -10
- package/.devpod/work.db +0 -0
- package/.github/workflows/test-safety.yml +0 -85
- package/.jettypod/config.json +0 -5
- package/.jettypod/current-work.json +0 -10
- package/.jettypod/hooks/README.md +0 -77
- package/.jettypod/hooks/protect-claude-md.js +0 -338
- package/.jettypod/test-work.db +0 -0
- package/.jettypod/work.db +0 -0
- package/CLAUDE.md +0 -49
- package/SPEED-STABLE-AUDIT.md +0 -853
- package/SYSTEM-BEHAVIOR.md +0 -2199
- package/TEST_SAFETY_AUDIT.md +0 -314
- package/TEST_SAFETY_IMPLEMENTATION.md +0 -97
- package/cucumber-report.html +0 -45
- package/dist/devpod-linux +0 -0
- package/dist/devpod-macos +0 -0
- package/dist/devpod-win.exe +0 -0
- package/docs/features/jettypod-standards-explained.md +0 -543
- package/docs/features/standards-inventory.md +0 -257
- package/features/auto-generate-production-chores.feature +0 -13
- package/features/backlog-command.feature +0 -26
- package/features/backlog-filtering-production.feature +0 -10
- package/features/claude-md-protection/steps.js +0 -498
- package/features/decisions/index.js +0 -490
- package/features/decisions/index.test.js +0 -208
- package/features/fix-text-wrapping.feature +0 -42
- package/features/git-hooks/git-hooks.feature +0 -30
- package/features/git-hooks/index.js +0 -93
- package/features/git-hooks/index.test.js +0 -137
- package/features/git-hooks/post-commit +0 -56
- package/features/git-hooks/post-merge +0 -47
- package/features/git-hooks/pre-commit +0 -28
- package/features/git-hooks/simple-steps.js +0 -53
- package/features/git-hooks/simple-test.feature +0 -10
- package/features/git-hooks/steps.js +0 -196
- package/features/jettypod-update-command.feature +0 -46
- package/features/mode-prompts/index.js +0 -95
- package/features/mode-prompts/simple-steps.js +0 -44
- package/features/mode-prompts/simple-test.feature +0 -9
- package/features/mode-prompts/validation.test.js +0 -120
- package/features/multiple-claude-instances.feature +0 -121
- package/features/production-mode-skill.feature +0 -121
- package/features/refactor-mode/steps.js +0 -217
- package/features/refactor-mode.feature +0 -49
- package/features/simplify-external-transition.feature +0 -166
- package/features/skills-update/index.test.js +0 -216
- package/features/step_definitions/backlog-command.steps.js +0 -37
- package/features/step_definitions/fix-text-wrapping.steps.js +0 -271
- package/features/step_definitions/multiple-claude-instances.steps.js +0 -621
- package/features/step_definitions/production-mode-skill.steps.js +0 -862
- package/features/step_definitions/simplify-external-transition.steps.js +0 -370
- package/features/step_definitions/terminal-logo.steps.js +0 -145
- package/features/step_definitions/update-command.steps.js +0 -183
- package/features/support/hooks.js +0 -9
- package/features/terminal-logo/index.js +0 -39
- package/features/terminal-logo/terminal-logo.feature +0 -30
- package/features/update-command/index.js +0 -181
- package/features/update-command/index.test.js +0 -225
- package/features/work-commands/bug-workflow-display.feature +0 -22
- package/features/work-commands/index.js +0 -498
- package/features/work-commands/simple-steps.js +0 -69
- package/features/work-commands/stable-tests.feature +0 -57
- package/features/work-commands/steps.js +0 -1174
- package/features/work-commands/validation.test.js +0 -88
- package/features/work-commands/work-commands.feature +0 -13
- package/features/work-tracking/discovery-validation.test.js +0 -228
- package/features/work-tracking/index.js +0 -1921
- package/features/work-tracking/mode-required.feature +0 -112
- package/features/work-tracking/phase-tracking.test.js +0 -482
- package/features/work-tracking/prototype-tracking.test.js +0 -485
- package/features/work-tracking/tree-view.test.js +0 -310
- package/features/work-tracking/work-set-mode.feature +0 -71
- package/features/work-tracking/work-start-mode.feature +0 -88
- package/full-test.txt +0 -0
- package/lib/bug-workflow.test.js +0 -177
- package/lib/claudemd.test.js +0 -195
- package/lib/config.test.js +0 -511
- package/lib/constants.test.js +0 -164
- package/lib/current-work.test.js +0 -146
- package/lib/database-project-config.test.js +0 -111
- package/lib/database.test.js +0 -106
- package/lib/decisions-generator.test.js +0 -457
- package/lib/decisions-helpers.test.js +0 -310
- package/lib/git-coordinator.js +0 -167
- package/lib/git.test.js +0 -145
- package/lib/migrations/002-default-work-item-modes.test.js +0 -351
- package/lib/production-chore-generator.test.js +0 -432
- package/lib/production-context-detector.test.js +0 -277
- package/lib/production-scenario-appender.test.js +0 -235
- package/lib/production-scenario-validator.test.js +0 -246
- package/lib/production-standards-reader.test.js +0 -270
- package/lib/project-state.test.js +0 -92
- package/lib/push-queue.js +0 -417
- package/lib/queue-processor.js +0 -74
- package/lib/test-helpers.js +0 -202
- package/lib/test-helpers.test.js +0 -255
- package/prototypes/2025-01-11-production-mode-autonomous.js +0 -119
- package/prototypes/2025-01-11-production-mode-collaborative.js +0 -166
- package/prototypes/2025-01-11-production-mode-guided.js +0 -217
- package/prototypes/2025-01-11-production-mode-smart-context.js +0 -347
- package/prototypes/2025-01-11-production-standards-example.md +0 -204
- package/prototypes/2025-11-10-backlog-filtering-tree-aware.js +0 -242
- package/prototypes/test/index.html +0 -1
- package/setup-dist-repo.sh +0 -68
- package/test-production-standards-engine.js +0 -130
- package/test-results.json +0 -2195
- package/test-safety-check.sh +0 -80
- package/work-item-tracking-plan.md +0 -199
- /package/{.jettypod/devpod.db → jettypod.db} +0 -0
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
# Production Standards (Example Output)
|
|
2
|
-
|
|
3
|
-
**Generated by:** `external-transition` skill
|
|
4
|
-
**Date:** 2025-01-11
|
|
5
|
-
**Project State:** external
|
|
6
|
-
**For:** JettyPod
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Overview
|
|
11
|
-
|
|
12
|
-
This project has transitioned to **external** state. All features in production mode must meet these standards before deployment.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Security Standards
|
|
17
|
-
|
|
18
|
-
### Authentication & Authorization
|
|
19
|
-
- ✅ **Required:** All state-changing operations must log user/actor
|
|
20
|
-
- ✅ **Required:** Permission validation before sensitive operations
|
|
21
|
-
- ⚠️ **Recommended:** Rate limiting on public endpoints
|
|
22
|
-
- Pattern: Use `lib/audit-logger.js` for authentication events
|
|
23
|
-
|
|
24
|
-
### Data Protection
|
|
25
|
-
- ✅ **Required:** PII must be sanitized in logs
|
|
26
|
-
- ✅ **Required:** Sensitive data (tokens, keys) must be masked
|
|
27
|
-
- ✅ **Required:** Data at rest encryption for user data
|
|
28
|
-
- Pattern: Use `sanitizeData()` helper from `lib/data-protection.js`
|
|
29
|
-
|
|
30
|
-
### Audit Trail
|
|
31
|
-
- ✅ **Required:** All state transitions must be logged
|
|
32
|
-
- ✅ **Required:** Logs must be tamper-proof (append-only)
|
|
33
|
-
- ✅ **Required:** Include: timestamp, user, action, result
|
|
34
|
-
- Pattern: Use `lib/state-transitions.js` for immutable records
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Performance & Scale Standards
|
|
39
|
-
|
|
40
|
-
### Performance Benchmarks
|
|
41
|
-
- ✅ **Required:** Operations complete in < 5 seconds (p95)
|
|
42
|
-
- ✅ **Required:** Memory usage stays under 100MB per process
|
|
43
|
-
- ⚠️ **Recommended:** Support 1000+ concurrent users
|
|
44
|
-
- Tool: Use `features/performance/*.bench.js` for benchmarks
|
|
45
|
-
|
|
46
|
-
### Concurrency
|
|
47
|
-
- ✅ **Required:** Prevent race conditions on state changes
|
|
48
|
-
- ✅ **Required:** Lock mechanisms for critical sections
|
|
49
|
-
- Pattern: Use `lib/lock-manager.js` for file-based locks
|
|
50
|
-
|
|
51
|
-
### Storage & Cleanup
|
|
52
|
-
- ✅ **Required:** Log rotation (max 10MB per file, keep 5)
|
|
53
|
-
- ✅ **Required:** Automatic cleanup of old data
|
|
54
|
-
- ⚠️ **Recommended:** Database connection pooling
|
|
55
|
-
- Pattern: Check existing rotation in `lib/audit-logger.js`
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Compliance Standards
|
|
60
|
-
|
|
61
|
-
### Data Retention
|
|
62
|
-
- ✅ **Required:** Audit logs retained for 90 days minimum
|
|
63
|
-
- ✅ **Required:** User data deletion on request (GDPR)
|
|
64
|
-
- ✅ **Required:** Export data in machine-readable format (JSON/CSV)
|
|
65
|
-
|
|
66
|
-
### Monitoring & Observability
|
|
67
|
-
- ✅ **Required:** Error tracking for production issues
|
|
68
|
-
- ⚠️ **Recommended:** Performance monitoring (APM)
|
|
69
|
-
- ⚠️ **Recommended:** Health check endpoints
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Infrastructure Standards
|
|
74
|
-
|
|
75
|
-
Based on Infrastructure Readiness epic (#[epic-id]):
|
|
76
|
-
|
|
77
|
-
### Deployment
|
|
78
|
-
- ✅ **Required:** Zero-downtime deployments
|
|
79
|
-
- ✅ **Required:** Rollback capability
|
|
80
|
-
- Pattern: Blue-green or canary deployments
|
|
81
|
-
|
|
82
|
-
### Monitoring
|
|
83
|
-
- ✅ **Required:** Application metrics (requests, errors, latency)
|
|
84
|
-
- ✅ **Required:** Resource metrics (CPU, memory, disk)
|
|
85
|
-
- ✅ **Required:** Alert thresholds configured
|
|
86
|
-
|
|
87
|
-
### Security
|
|
88
|
-
- ✅ **Required:** TLS/HTTPS for all endpoints
|
|
89
|
-
- ✅ **Required:** Secrets management (not in code)
|
|
90
|
-
- ✅ **Required:** Regular security scans
|
|
91
|
-
|
|
92
|
-
### Compliance
|
|
93
|
-
- ✅ **Required:** Data backup and recovery tested
|
|
94
|
-
- ✅ **Required:** Incident response plan documented
|
|
95
|
-
- ✅ **Required:** Access control and audit logging
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Production Mode Checklist
|
|
100
|
-
|
|
101
|
-
When implementing production chores, verify each feature has:
|
|
102
|
-
|
|
103
|
-
**Security:**
|
|
104
|
-
- [ ] Audit logging for all state changes
|
|
105
|
-
- [ ] Data sanitization in logs
|
|
106
|
-
- [ ] Authentication/authorization validation
|
|
107
|
-
- [ ] Tamper-proof audit trail
|
|
108
|
-
|
|
109
|
-
**Performance:**
|
|
110
|
-
- [ ] Performance benchmarks (< 5s, < 100MB)
|
|
111
|
-
- [ ] Concurrency controls for critical sections
|
|
112
|
-
- [ ] Log rotation and cleanup
|
|
113
|
-
|
|
114
|
-
**Scale:**
|
|
115
|
-
- [ ] Handles expected load (1000+ items/users)
|
|
116
|
-
- [ ] Idempotent operations
|
|
117
|
-
- [ ] Graceful degradation under stress
|
|
118
|
-
|
|
119
|
-
**Compliance:**
|
|
120
|
-
- [ ] Data retention policies implemented
|
|
121
|
-
- [ ] Export functionality for user data
|
|
122
|
-
- [ ] Error tracking and monitoring
|
|
123
|
-
|
|
124
|
-
**Infrastructure:**
|
|
125
|
-
- [ ] Deployment automation ready
|
|
126
|
-
- [ ] Monitoring and alerts configured
|
|
127
|
-
- [ ] Security hardening complete
|
|
128
|
-
- [ ] Backup/recovery tested
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## How Production Mode Skill Uses This
|
|
133
|
-
|
|
134
|
-
### Scenario 1: Fresh from Stable Mode (Hot Context)
|
|
135
|
-
```
|
|
136
|
-
✓ Production scenarios already proposed
|
|
137
|
-
✓ Production chores already created
|
|
138
|
-
→ Validate scenarios against these standards
|
|
139
|
-
→ Implement chores following patterns listed above
|
|
140
|
-
→ Reference checklist for completeness
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Scenario 2: Gap in Time (Cold Context)
|
|
144
|
-
```
|
|
145
|
-
✓ Production scenarios exist but might be outdated
|
|
146
|
-
→ Re-validate scenarios against current standards
|
|
147
|
-
→ Check if project_state changed (internal→external)
|
|
148
|
-
→ Add missing scenarios based on new requirements
|
|
149
|
-
→ Update chores to match current infrastructure
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Scenario 3: Post External-Transition (New Requirements)
|
|
153
|
-
```
|
|
154
|
-
✗ Production scenarios don't exist yet
|
|
155
|
-
→ Generate scenarios from these standards
|
|
156
|
-
→ Focus on infrastructure-related requirements
|
|
157
|
-
→ Create chores that address external deployment needs
|
|
158
|
-
→ Reference Infrastructure Readiness epic decisions
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Pattern References
|
|
164
|
-
|
|
165
|
-
This project uses these patterns for production code:
|
|
166
|
-
|
|
167
|
-
**Audit Logging:**
|
|
168
|
-
```javascript
|
|
169
|
-
const { logTransition } = require('./lib/audit-logger');
|
|
170
|
-
await logTransition(user, 'project_external', { epicId, timestamp });
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Data Sanitization:**
|
|
174
|
-
```javascript
|
|
175
|
-
const { sanitizeData } = require('./lib/data-protection');
|
|
176
|
-
const safeData = sanitizeData({ userId, projectName, apiKey });
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Lock Management:**
|
|
180
|
-
```javascript
|
|
181
|
-
const { acquireLock, releaseLock } = require('./lib/lock-manager');
|
|
182
|
-
const lockAcquired = await acquireLock('external-transition');
|
|
183
|
-
if (!lockAcquired) throw new Error('Operation in progress');
|
|
184
|
-
try {
|
|
185
|
-
// Critical section
|
|
186
|
-
} finally {
|
|
187
|
-
await releaseLock('external-transition');
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**State Transitions:**
|
|
192
|
-
```javascript
|
|
193
|
-
const { recordTransition } = require('./lib/state-transitions');
|
|
194
|
-
await recordTransition('internal', 'external', { timestamp, user });
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Notes
|
|
200
|
-
|
|
201
|
-
- Standards marked ✅ **Required** must be implemented for all production features
|
|
202
|
-
- Standards marked ⚠️ **Recommended** are optional but encouraged
|
|
203
|
-
- Update this document when infrastructure decisions change
|
|
204
|
-
- Reference Infrastructure Readiness epic for deployment-specific requirements
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
// Prototype: Backlog Filtering for Production Items - Tree-aware filtering
|
|
2
|
-
// Created: 2025-11-10
|
|
3
|
-
// Purpose: Smart filtering that maintains tree integrity while hiding production items in internal projects
|
|
4
|
-
// Decision: [to be filled after testing]
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Prototype demonstrates:
|
|
8
|
-
* 1. Reads project_state from config
|
|
9
|
-
* 2. Filters production mode features when project_state='internal'
|
|
10
|
-
* 3. Recursively filters children of production features (chores)
|
|
11
|
-
* 4. Maintains tree integrity - doesn't break parent/child relationships
|
|
12
|
-
* 5. --all flag bypasses filtering
|
|
13
|
-
*
|
|
14
|
-
* CRITICAL: Filtering ONLY applies to the BACKLOG section.
|
|
15
|
-
* "Active Work" and "Recently Completed" sections show ALL items regardless of mode.
|
|
16
|
-
* This makes sense: you care about what you're working on NOW and what you JUST completed,
|
|
17
|
-
* even if it's production mode. Filtering is about hiding future work that's not relevant yet.
|
|
18
|
-
*
|
|
19
|
-
* Architecture principle: Only features have modes. Epics are containers, chores inherit context.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const { getDb } = require('../lib/database');
|
|
23
|
-
const config = require('../lib/config');
|
|
24
|
-
const { TYPE_EMOJIS } = require('../lib/constants');
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get filtered tree of work items
|
|
28
|
-
* @param {boolean} includeCompleted - Include completed items
|
|
29
|
-
* @param {boolean} showAll - Show all items including production (bypasses internal/external filtering)
|
|
30
|
-
* @returns {Promise<Array>} Tree of work items
|
|
31
|
-
*/
|
|
32
|
-
function getFilteredTree(includeCompleted = false, showAll = false) {
|
|
33
|
-
return new Promise((resolve, reject) => {
|
|
34
|
-
const db = getDb();
|
|
35
|
-
const projectConfig = config.read();
|
|
36
|
-
const isInternal = projectConfig.project_state === 'internal';
|
|
37
|
-
|
|
38
|
-
// Build WHERE clause for completion filter
|
|
39
|
-
const whereClause = includeCompleted ? '' : "WHERE status NOT IN ('done', 'cancelled')";
|
|
40
|
-
|
|
41
|
-
db.all(`SELECT * FROM work_items ${whereClause} ORDER BY parent_id, id`, [], (err, rows) => {
|
|
42
|
-
if (err) {
|
|
43
|
-
return reject(new Error(`Failed to fetch work items: ${err.message}`));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!rows || rows.length === 0) {
|
|
47
|
-
return resolve([]);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
// Build lookup
|
|
52
|
-
const itemsById = {};
|
|
53
|
-
rows.forEach(item => {
|
|
54
|
-
itemsById[item.id] = item;
|
|
55
|
-
item.children = [];
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Build tree
|
|
59
|
-
rows.forEach(item => {
|
|
60
|
-
if (item.parent_id && itemsById[item.parent_id]) {
|
|
61
|
-
itemsById[item.parent_id].children.push(item);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Get root items
|
|
66
|
-
let rootItems = rows.filter(item => !item.parent_id);
|
|
67
|
-
|
|
68
|
-
// Apply production filtering if internal project and not showing all
|
|
69
|
-
if (isInternal && !showAll) {
|
|
70
|
-
rootItems = filterProductionItems(rootItems, itemsById);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
resolve(rootItems);
|
|
74
|
-
} catch (err) {
|
|
75
|
-
reject(new Error(`Failed to build filtered tree: ${err.message}`));
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Recursively filter out production mode features and their children
|
|
83
|
-
* Smart filtering: only removes items if they're production mode features
|
|
84
|
-
* Maintains tree integrity: removes entire branches when feature is production
|
|
85
|
-
*
|
|
86
|
-
* @param {Array} items - Items to filter
|
|
87
|
-
* @param {Object} itemsById - Lookup map of all items
|
|
88
|
-
* @returns {Array} Filtered items
|
|
89
|
-
*/
|
|
90
|
-
function filterProductionItems(items, itemsById) {
|
|
91
|
-
return items.filter(item => {
|
|
92
|
-
// Check if this item should be hidden
|
|
93
|
-
const shouldHide = isProductionModeItem(item);
|
|
94
|
-
|
|
95
|
-
if (shouldHide) {
|
|
96
|
-
return false; // Hide this item and all its children
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Item is not production - keep it and recursively filter its children
|
|
100
|
-
if (item.children && item.children.length > 0) {
|
|
101
|
-
item.children = filterProductionItems(item.children, itemsById);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return true;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Determine if an item should be hidden in internal projects
|
|
110
|
-
* Rules:
|
|
111
|
-
* - Features with mode='production' are hidden
|
|
112
|
-
* - Chores whose parent feature has mode='production' are hidden (handled by tree filtering)
|
|
113
|
-
* - Epics are never hidden (they're containers)
|
|
114
|
-
*
|
|
115
|
-
* @param {Object} item - Work item to check
|
|
116
|
-
* @returns {boolean} True if item should be hidden
|
|
117
|
-
*/
|
|
118
|
-
function isProductionModeItem(item) {
|
|
119
|
-
// Only features can have production mode
|
|
120
|
-
if (item.type === 'feature' && item.mode === 'production') {
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Epics are containers - never hide them
|
|
125
|
-
// Chores don't have modes - their visibility is determined by their parent
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Print tree with visual indicators
|
|
131
|
-
*/
|
|
132
|
-
function printTree(items, prefix = '', isRootLevel = true) {
|
|
133
|
-
if (!Array.isArray(items)) {
|
|
134
|
-
throw new Error('Items must be an array');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
items.forEach((item, index) => {
|
|
138
|
-
const isLast = index === items.length - 1;
|
|
139
|
-
const emoji = TYPE_EMOJIS[item.type] || '📋';
|
|
140
|
-
const connector = isLast ? '└─' : '├─';
|
|
141
|
-
|
|
142
|
-
// Build mode indicator
|
|
143
|
-
let modeIndicator = '';
|
|
144
|
-
if (item.type === 'feature') {
|
|
145
|
-
if (item.phase === 'discovery') {
|
|
146
|
-
modeIndicator = ' [🔍 discovery]';
|
|
147
|
-
} else if (item.mode) {
|
|
148
|
-
modeIndicator = ` [${item.mode}]`;
|
|
149
|
-
}
|
|
150
|
-
} else if (item.mode) {
|
|
151
|
-
modeIndicator = ` [${item.mode}]`;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const line = isRootLevel
|
|
155
|
-
? `${emoji} [#${item.id}] ${item.title}${modeIndicator}`
|
|
156
|
-
: `${prefix}${connector} ${emoji} [#${item.id}] ${item.title}${modeIndicator}`;
|
|
157
|
-
|
|
158
|
-
console.log(line);
|
|
159
|
-
|
|
160
|
-
// Print children
|
|
161
|
-
if (item.children && item.children.length > 0) {
|
|
162
|
-
const childPrefix = isRootLevel
|
|
163
|
-
? ' '
|
|
164
|
-
: prefix + (isLast ? ' ' : '│ ');
|
|
165
|
-
printTree(item.children, childPrefix, false);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Demo
|
|
171
|
-
async function demo() {
|
|
172
|
-
console.log('═══════════════════════════════════════════════════');
|
|
173
|
-
console.log('Prototype: Tree-aware Production Filtering');
|
|
174
|
-
console.log('═══════════════════════════════════════════════════');
|
|
175
|
-
console.log('');
|
|
176
|
-
|
|
177
|
-
const projectConfig = config.read();
|
|
178
|
-
console.log(`Current project_state: ${projectConfig.project_state}`);
|
|
179
|
-
console.log('');
|
|
180
|
-
|
|
181
|
-
// Show default backlog (filtered if internal)
|
|
182
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
183
|
-
console.log('📋 DEFAULT BACKLOG (jettypod backlog)');
|
|
184
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
185
|
-
if (projectConfig.project_state === 'internal') {
|
|
186
|
-
console.log('Note: Production mode features hidden (internal project)');
|
|
187
|
-
}
|
|
188
|
-
console.log('');
|
|
189
|
-
|
|
190
|
-
const defaultTree = await getFilteredTree(false, false);
|
|
191
|
-
if (defaultTree.length === 0) {
|
|
192
|
-
console.log('No items found.');
|
|
193
|
-
} else {
|
|
194
|
-
printTree(defaultTree);
|
|
195
|
-
}
|
|
196
|
-
console.log('');
|
|
197
|
-
|
|
198
|
-
// Show all items
|
|
199
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
200
|
-
console.log('📋 ALL ITEMS (jettypod backlog --all)');
|
|
201
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
202
|
-
console.log('Note: Shows everything including production mode');
|
|
203
|
-
console.log('');
|
|
204
|
-
|
|
205
|
-
const allTree = await getFilteredTree(false, true);
|
|
206
|
-
if (allTree.length === 0) {
|
|
207
|
-
console.log('No items found.');
|
|
208
|
-
} else {
|
|
209
|
-
printTree(allTree);
|
|
210
|
-
}
|
|
211
|
-
console.log('');
|
|
212
|
-
|
|
213
|
-
console.log('═══════════════════════════════════════════════════');
|
|
214
|
-
console.log('Key behaviors demonstrated:');
|
|
215
|
-
console.log('');
|
|
216
|
-
console.log('✅ Features with mode=production are hidden in BACKLOG section');
|
|
217
|
-
console.log('✅ Their chores are also hidden (tree branch filtering)');
|
|
218
|
-
console.log('✅ Epics always visible (they\'re containers, no mode)');
|
|
219
|
-
console.log('✅ --all flag shows everything');
|
|
220
|
-
console.log('✅ Tree integrity maintained (no orphaned items)');
|
|
221
|
-
console.log('');
|
|
222
|
-
console.log('🔍 IMPORTANT: Filtering ONLY applies to BACKLOG section');
|
|
223
|
-
console.log(' "Active Work" shows current item (even if production mode)');
|
|
224
|
-
console.log(' "Recently Completed" shows last 3 done (even if production mode)');
|
|
225
|
-
console.log(' "Backlog" section filters out production items in internal projects');
|
|
226
|
-
console.log('');
|
|
227
|
-
console.log('Architecture: Only features have modes.');
|
|
228
|
-
console.log('Epics = containers (no mode), Chores = inherit from parent (no mode)');
|
|
229
|
-
console.log('═══════════════════════════════════════════════════');
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Run demo if executed directly
|
|
233
|
-
if (require.main === module) {
|
|
234
|
-
demo()
|
|
235
|
-
.then(() => process.exit(0))
|
|
236
|
-
.catch(err => {
|
|
237
|
-
console.error('Error:', err.message);
|
|
238
|
-
process.exit(1);
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
module.exports = { getFilteredTree, filterProductionItems, isProductionModeItem };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
test
|
package/setup-dist-repo.sh
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
echo "=========================================="
|
|
5
|
-
echo " DevPod Distribution Repo Setup"
|
|
6
|
-
echo "=========================================="
|
|
7
|
-
echo ""
|
|
8
|
-
|
|
9
|
-
# Get the directory where this script is located (main repo)
|
|
10
|
-
MAIN_REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
-
echo "Main repo: $MAIN_REPO"
|
|
12
|
-
|
|
13
|
-
# Check if devpod-dist already exists
|
|
14
|
-
if [ -d "$HOME/projects/devpod-dist" ]; then
|
|
15
|
-
echo "⚠️ devpod-dist directory already exists at $HOME/projects/devpod-dist"
|
|
16
|
-
read -p "Delete and re-clone? (y/N): " -n 1 -r
|
|
17
|
-
echo
|
|
18
|
-
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
19
|
-
rm -rf "$HOME/projects/devpod-dist"
|
|
20
|
-
else
|
|
21
|
-
echo "Aborting."
|
|
22
|
-
exit 1
|
|
23
|
-
fi
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
|
-
# Clone the distribution repository
|
|
27
|
-
echo ""
|
|
28
|
-
echo "📦 Cloning devpod-dist repository..."
|
|
29
|
-
cd ~/projects
|
|
30
|
-
git clone https://github.com/spangbaryn/devpod-dist.git
|
|
31
|
-
cd devpod-dist
|
|
32
|
-
|
|
33
|
-
# Copy files from main repository
|
|
34
|
-
echo ""
|
|
35
|
-
echo "📋 Copying files..."
|
|
36
|
-
cp "$MAIN_REPO/install.sh" .
|
|
37
|
-
cp "$MAIN_REPO/install.ps1" .
|
|
38
|
-
cp "$MAIN_REPO/dist-repo/README.md" .
|
|
39
|
-
|
|
40
|
-
# Show what we have
|
|
41
|
-
echo ""
|
|
42
|
-
echo "📁 Files in distribution repo:"
|
|
43
|
-
ls -la
|
|
44
|
-
|
|
45
|
-
# Commit and push
|
|
46
|
-
echo ""
|
|
47
|
-
echo "💾 Committing and pushing..."
|
|
48
|
-
git add .
|
|
49
|
-
git commit -m "Initial distribution repository setup
|
|
50
|
-
|
|
51
|
-
Install scripts and documentation for DevPod public distribution.
|
|
52
|
-
|
|
53
|
-
- install.sh: Unix (macOS/Linux) installer
|
|
54
|
-
- install.ps1: Windows PowerShell installer
|
|
55
|
-
- README.md: User-facing documentation with installation instructions
|
|
56
|
-
|
|
57
|
-
Install scripts are MIT licensed. DevPod application is proprietary.
|
|
58
|
-
"
|
|
59
|
-
git push origin main
|
|
60
|
-
|
|
61
|
-
echo ""
|
|
62
|
-
echo "✅ Success! Distribution repository is set up."
|
|
63
|
-
echo ""
|
|
64
|
-
echo "Verify at: https://github.com/spangbaryn/devpod-dist"
|
|
65
|
-
echo ""
|
|
66
|
-
echo "Next: Check that these URLs work:"
|
|
67
|
-
echo " https://raw.githubusercontent.com/spangbaryn/devpod-dist/main/install.sh"
|
|
68
|
-
echo " https://raw.githubusercontent.com/spangbaryn/devpod-dist/main/install.ps1"
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quick test of production-standards-engine
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const engine = require('./lib/production-standards-engine');
|
|
6
|
-
|
|
7
|
-
console.log('Testing Production Standards Engine\n');
|
|
8
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
9
|
-
|
|
10
|
-
// Test 1: Startup MVP
|
|
11
|
-
console.log('Test 1: Startup MVP preset\n');
|
|
12
|
-
const mvp = engine.generateStandards({
|
|
13
|
-
preset: 'startup-mvp',
|
|
14
|
-
refinement: {
|
|
15
|
-
app_description: 'Internal tool for team collaboration',
|
|
16
|
-
user_count: '1-10',
|
|
17
|
-
downtime_impact: 'users_annoyed',
|
|
18
|
-
data_loss_impact: 'annoying',
|
|
19
|
-
sensitive_data: false
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
console.log(`Preset: ${mvp.preset}`);
|
|
24
|
-
console.log(`Profiles: ${mvp.profiles.join(', ') || 'none'}`);
|
|
25
|
-
console.log(`Standards: ${mvp.standards.length} total`);
|
|
26
|
-
console.log(` Security: ${mvp.standards.filter(s => s.domain === 'security').length}`);
|
|
27
|
-
console.log(` Performance: ${mvp.standards.filter(s => s.domain === 'performance').length}`);
|
|
28
|
-
console.log(` Infrastructure: ${mvp.standards.filter(s => s.domain === 'infrastructure').length}`);
|
|
29
|
-
console.log(`Warnings: ${mvp.warnings.length}`);
|
|
30
|
-
console.log(`Cost impact: ${mvp.cost_estimate.impact}`);
|
|
31
|
-
console.log(`Cost drivers: ${mvp.cost_estimate.drivers.slice(0, 3).join(', ')}${mvp.cost_estimate.drivers.length > 3 ? '...' : ''}`);
|
|
32
|
-
console.log('');
|
|
33
|
-
|
|
34
|
-
// Test 2: Production SaaS with GDPR
|
|
35
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
36
|
-
console.log('Test 2: Production SaaS with GDPR\n');
|
|
37
|
-
const saas = engine.generateStandards({
|
|
38
|
-
preset: 'production-saas',
|
|
39
|
-
refinement: {
|
|
40
|
-
app_description: 'Project management SaaS',
|
|
41
|
-
user_count: '100-1k',
|
|
42
|
-
downtime_impact: 'revenue_loss',
|
|
43
|
-
data_loss_impact: 'bad_recoverable',
|
|
44
|
-
sensitive_data: true,
|
|
45
|
-
sensitive_types: ['email', 'project_data'],
|
|
46
|
-
user_geography: 'global',
|
|
47
|
-
compliance: ['GDPR'],
|
|
48
|
-
release_cadence: 'weekly'
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
console.log(`Preset: ${saas.preset}`);
|
|
53
|
-
console.log(`Profiles: ${saas.profiles.join(', ')}`);
|
|
54
|
-
console.log(`Standards: ${saas.standards.length} total`);
|
|
55
|
-
console.log(` Security: ${saas.standards.filter(s => s.domain === 'security').length}`);
|
|
56
|
-
console.log(` Performance: ${saas.standards.filter(s => s.domain === 'performance').length}`);
|
|
57
|
-
console.log(` Compliance: ${saas.standards.filter(s => s.domain === 'compliance').length}`);
|
|
58
|
-
console.log(` Infrastructure: ${saas.standards.filter(s => s.domain === 'infrastructure').length}`);
|
|
59
|
-
console.log(`Warnings: ${saas.warnings.length}`);
|
|
60
|
-
if (saas.warnings.length > 0) {
|
|
61
|
-
saas.warnings.forEach(w => console.log(` - ${w.message}`));
|
|
62
|
-
}
|
|
63
|
-
console.log(`Cost impact: ${saas.cost_estimate.impact}`);
|
|
64
|
-
console.log(`Cost drivers: ${saas.cost_estimate.drivers.join(', ')}`);
|
|
65
|
-
console.log('');
|
|
66
|
-
|
|
67
|
-
// Test 3: Enterprise
|
|
68
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
69
|
-
console.log('Test 3: Enterprise with SOC2\n');
|
|
70
|
-
const enterprise = engine.generateStandards({
|
|
71
|
-
preset: 'enterprise',
|
|
72
|
-
refinement: {
|
|
73
|
-
app_description: 'Enterprise SaaS platform',
|
|
74
|
-
user_count: '10k+',
|
|
75
|
-
downtime_impact: 'contractual_violation',
|
|
76
|
-
data_loss_impact: 'major_problem',
|
|
77
|
-
sensitive_data: true,
|
|
78
|
-
sensitive_types: ['customer_data', 'financial_data'],
|
|
79
|
-
user_geography: 'global',
|
|
80
|
-
compliance: ['SOC2', 'GDPR'],
|
|
81
|
-
release_cadence: 'daily+'
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
console.log(`Preset: ${enterprise.preset}`);
|
|
86
|
-
console.log(`Profiles: ${enterprise.profiles.join(', ')}`);
|
|
87
|
-
console.log(`Standards: ${enterprise.standards.length} total`);
|
|
88
|
-
console.log(` Required: ${enterprise.standards.filter(s => s.required).length}`);
|
|
89
|
-
console.log(` Optional: ${enterprise.standards.filter(s => !s.required).length}`);
|
|
90
|
-
console.log(`Warnings: ${enterprise.warnings.length}`);
|
|
91
|
-
console.log(`Cost impact: ${enterprise.cost_estimate.impact}`);
|
|
92
|
-
console.log(`Cost drivers: ${enterprise.cost_estimate.drivers.join(', ')}`);
|
|
93
|
-
console.log('');
|
|
94
|
-
|
|
95
|
-
// Test 4: Over-engineering warning
|
|
96
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
97
|
-
console.log('Test 4: Over-engineering check (Enterprise + 1-10 users)\n');
|
|
98
|
-
const overEngineered = engine.generateStandards({
|
|
99
|
-
preset: 'enterprise',
|
|
100
|
-
refinement: {
|
|
101
|
-
app_description: 'Small tool',
|
|
102
|
-
user_count: '1-10',
|
|
103
|
-
downtime_impact: 'no_big_deal',
|
|
104
|
-
data_loss_impact: 'annoying',
|
|
105
|
-
sensitive_data: false
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
console.log(`Warnings: ${overEngineered.warnings.length}`);
|
|
110
|
-
if (overEngineered.warnings.length > 0) {
|
|
111
|
-
overEngineered.warnings.forEach(w => console.log(` [${w.severity}] ${w.message}`));
|
|
112
|
-
}
|
|
113
|
-
console.log('');
|
|
114
|
-
|
|
115
|
-
// Show sample standard detail
|
|
116
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
117
|
-
console.log('Sample Standard Detail (from Production SaaS):\n');
|
|
118
|
-
const sampleStandard = saas.standards.find(s => s.id === 'waf_rate_limits');
|
|
119
|
-
if (sampleStandard) {
|
|
120
|
-
console.log(`ID: ${sampleStandard.id}`);
|
|
121
|
-
console.log(`Domain: ${sampleStandard.domain}`);
|
|
122
|
-
console.log(`Required: ${sampleStandard.required}`);
|
|
123
|
-
console.log(`Reasoning: ${sampleStandard.reasoning}`);
|
|
124
|
-
console.log(`Acceptance: ${sampleStandard.acceptance}`);
|
|
125
|
-
console.log(`Pattern: ${sampleStandard.pattern}`);
|
|
126
|
-
}
|
|
127
|
-
console.log('');
|
|
128
|
-
|
|
129
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
130
|
-
console.log('✅ All tests passed!');
|