wogiflow 2.6.4 → 2.7.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 (29) hide show
  1. package/.claude/settings.json +0 -1
  2. package/lib/workspace-changelog.js +182 -0
  3. package/lib/workspace-channel-server.js +75 -2
  4. package/lib/workspace-contracts.js +151 -1
  5. package/lib/workspace-events.js +383 -0
  6. package/lib/workspace-gates.js +740 -0
  7. package/lib/workspace-integration-tests.js +299 -0
  8. package/lib/workspace-intelligence.js +486 -1
  9. package/lib/workspace-locks.js +371 -0
  10. package/lib/workspace-messages.js +203 -3
  11. package/lib/workspace-routing.js +144 -0
  12. package/package.json +1 -1
  13. package/scripts/flow-done-gates.js +70 -0
  14. package/.claude/rules/_internal/README.md +0 -64
  15. package/.claude/rules/_internal/document-structure.md +0 -77
  16. package/.claude/rules/_internal/dual-repo-management.md +0 -174
  17. package/.claude/rules/_internal/feature-refactoring-cleanup.md +0 -87
  18. package/.claude/rules/_internal/github-releases.md +0 -71
  19. package/.claude/rules/_internal/model-management.md +0 -35
  20. package/.claude/rules/_internal/self-maintenance.md +0 -87
  21. package/.claude/rules/architecture/component-reuse.md +0 -38
  22. package/.claude/rules/code-style/naming-conventions.md +0 -107
  23. package/.claude/rules/operations/git-workflows.md +0 -92
  24. package/.claude/rules/operations/scratch-directory.md +0 -54
  25. package/.claude/rules/security/security-patterns.md +0 -176
  26. package/.claude/skills/figma-analyzer/knowledge/learnings.md +0 -11
  27. package/.workflow/specs/architecture.md.template +0 -24
  28. package/.workflow/specs/stack.md.template +0 -33
  29. package/.workflow/specs/testing.md.template +0 -36
@@ -479,6 +479,146 @@ function getExecutionOrder(manifest, targetRepos) {
479
479
  return order;
480
480
  }
481
481
 
482
+ // ============================================================
483
+ // Cross-Repo Dependency-Aware Task Blocking
484
+ // ============================================================
485
+
486
+ /**
487
+ * Block consumer-side tasks until their provider dependencies are complete.
488
+ * Reads workspace-level ready.json and each member's ready.json to find
489
+ * cross-repo dependencies.
490
+ *
491
+ * @param {string} workspaceRoot
492
+ * @param {Object} manifest
493
+ * @returns {{ blockedTasks: Array<Object>, unblockedTasks: Array<Object> }}
494
+ */
495
+ function updateCrossRepoBlocking(workspaceRoot, manifest) {
496
+ const configPath = path.join(workspaceRoot, 'wogi-workspace.json');
497
+ let config;
498
+ try {
499
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
500
+ } catch (_err) {
501
+ return { blockedTasks: [], unblockedTasks: [] };
502
+ }
503
+
504
+ const blockedTasks = [];
505
+ const unblockedTasks = [];
506
+ const memberTasks = {};
507
+
508
+ // Collect all tasks from all member repos
509
+ for (const [name, memberConfig] of Object.entries(config.members || {})) {
510
+ const memberPath = path.resolve(workspaceRoot, memberConfig.path);
511
+ const readyPath = path.join(memberPath, '.workflow', 'state', 'ready.json');
512
+ try {
513
+ if (fs.existsSync(readyPath)) {
514
+ const ready = JSON.parse(fs.readFileSync(readyPath, 'utf-8'));
515
+ memberTasks[name] = {
516
+ path: memberPath,
517
+ readyPath,
518
+ ready,
519
+ inProgress: ready.inProgress || [],
520
+ readyItems: ready.ready || [],
521
+ completed: ready.recentlyCompleted || []
522
+ };
523
+ }
524
+ } catch (_err) {
525
+ // Skip
526
+ }
527
+ }
528
+
529
+ // For each member's ready tasks, check if they depend on workspace tasks
530
+ const executionOrder = getExecutionOrder(manifest, Object.keys(config.members));
531
+
532
+ for (const [name, data] of Object.entries(memberTasks)) {
533
+ const memberPhase = executionOrder.find(o => o.name === name);
534
+ if (!memberPhase) continue;
535
+
536
+ for (const task of data.readyItems) {
537
+ // Check if this task has workspace source and blockedBy
538
+ if (!task.source?.startsWith('workspace:')) continue;
539
+
540
+ const blockedBy = task.blockedBy || [];
541
+ let isBlocked = false;
542
+
543
+ for (const depId of blockedBy) {
544
+ // Check if the blocking task is completed in any member
545
+ let depCompleted = false;
546
+ for (const [depName, depData] of Object.entries(memberTasks)) {
547
+ if (depData.completed.some(t => t.id === depId)) {
548
+ depCompleted = true;
549
+ break;
550
+ }
551
+ }
552
+
553
+ if (!depCompleted) {
554
+ isBlocked = true;
555
+ break;
556
+ }
557
+ }
558
+
559
+ if (isBlocked) {
560
+ blockedTasks.push({ repo: name, task, blockedBy });
561
+ } else if (blockedBy.length > 0) {
562
+ unblockedTasks.push({ repo: name, task });
563
+ }
564
+ }
565
+ }
566
+
567
+ return { blockedTasks, unblockedTasks };
568
+ }
569
+
570
+ /**
571
+ * Build a visual dependency tree for workspace tasks.
572
+ *
573
+ * @param {string} workspaceRoot
574
+ * @param {Object} manifest
575
+ * @returns {string} formatted tree
576
+ */
577
+ function formatDependencyTree(workspaceRoot, manifest) {
578
+ const configPath = path.join(workspaceRoot, 'wogi-workspace.json');
579
+ let config;
580
+ try {
581
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
582
+ } catch (_err) {
583
+ return 'No workspace config found.';
584
+ }
585
+
586
+ const lines = ['Workspace Task Dependencies:'];
587
+ const order = getExecutionOrder(manifest, Object.keys(config.members || {}));
588
+
589
+ for (const entry of order) {
590
+ const memberConfig = config.members[entry.name];
591
+ if (!memberConfig) continue;
592
+
593
+ const memberPath = path.resolve(workspaceRoot, memberConfig.path);
594
+ const readyPath = path.join(memberPath, '.workflow', 'state', 'ready.json');
595
+
596
+ try {
597
+ if (!fs.existsSync(readyPath)) continue;
598
+ const ready = JSON.parse(fs.readFileSync(readyPath, 'utf-8'));
599
+ const wsTasks = [...(ready.inProgress || []), ...(ready.ready || []), ...(ready.blocked || [])]
600
+ .filter(t => t.source?.startsWith('workspace:'));
601
+
602
+ if (wsTasks.length === 0) continue;
603
+
604
+ lines.push(`\n ${entry.name} (${entry.role}, phase ${entry.order}):`);
605
+ for (const task of wsTasks) {
606
+ const status = task.status === 'completed' ? '\u2713' :
607
+ (ready.inProgress || []).some(t => t.id === task.id) ? '\u25B6' :
608
+ task.blockedBy?.length ? '\u2718' : '\u25CB';
609
+ const blockedNote = task.blockedBy?.length
610
+ ? ` [blocked by: ${task.blockedBy.join(', ')}]`
611
+ : '';
612
+ lines.push(` ${status} ${task.id} — ${task.title}${blockedNote}`);
613
+ }
614
+ } catch (_err) {
615
+ // Skip
616
+ }
617
+ }
618
+
619
+ return lines.join('\n');
620
+ }
621
+
482
622
  // ============================================================
483
623
  // Channel-Based Dispatch (wf-d4b98f60)
484
624
  // ============================================================
@@ -772,6 +912,10 @@ module.exports = {
772
912
  // Ordering
773
913
  getExecutionOrder,
774
914
 
915
+ // Cross-repo blocking
916
+ updateCrossRepoBlocking,
917
+ formatDependencyTree,
918
+
775
919
  // Channel dispatch
776
920
  dispatchToChannel,
777
921
  dispatchCrossRepoPlan,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wogiflow",
3
- "version": "2.6.4",
3
+ "version": "2.7.0",
4
4
  "description": "AI-powered development workflow management system with multi-model support",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -57,6 +57,19 @@ function getRegistryManager() {
57
57
  return _registryManagerModule;
58
58
  }
59
59
 
60
+ // Workspace gates — lazy-loaded (only active when workspace mode is detected)
61
+ let _workspaceGatesModule = undefined;
62
+ function getWorkspaceGates() {
63
+ if (_workspaceGatesModule === undefined) {
64
+ try {
65
+ _workspaceGatesModule = require('../lib/workspace-gates');
66
+ } catch (_err) {
67
+ _workspaceGatesModule = null;
68
+ }
69
+ }
70
+ return _workspaceGatesModule;
71
+ }
72
+
60
73
  // ============================================================
61
74
  // Gate Handlers
62
75
  // ============================================================
@@ -717,6 +730,60 @@ function unknownGate(ctx, gateName) {
717
730
  // Gate Registry
718
731
  // ============================================================
719
732
 
733
+ // ============================================================
734
+ // Workspace Quality Gates (conditional — only when workspace active)
735
+ // ============================================================
736
+
737
+ /**
738
+ * Workspace gate handler. Delegates to workspace-gates.js for each
739
+ * sub-gate (crossRepoImpactCheck, contractCompliance, peerNotification,
740
+ * cascadeVerification, integrationMapFreshness).
741
+ *
742
+ * This is a single gate entry in GATE_REGISTRY that runs all applicable
743
+ * workspace sub-gates based on task type.
744
+ */
745
+ function workspaceGate(ctx, gateName) {
746
+ const wsGates = getWorkspaceGates();
747
+ if (!wsGates) {
748
+ return { passed: true, skipped: true };
749
+ }
750
+
751
+ const ws = wsGates.workspaceActive();
752
+ if (!ws.active) {
753
+ return { passed: true, skipped: true };
754
+ }
755
+
756
+ const context = wsGates.loadWorkspaceContext(ws.root);
757
+ const taskMeta = {
758
+ taskId: ctx.taskId,
759
+ taskTitle: ctx.taskTitle || '',
760
+ taskType: ctx.normalizedType || 'feature',
761
+ impactAssessed: ctx.impactAssessed || false
762
+ };
763
+
764
+ const results = wsGates.runAllWorkspaceGates(ws.root, context, taskMeta);
765
+
766
+ // Display results
767
+ for (const r of results.results) {
768
+ if (r.passed) {
769
+ ctx.success(`workspace/${r.gate}: ${r.message}`);
770
+ } else if (r.severity === 'warning') {
771
+ console.log(` ${ctx.color('yellow', '\u25CB')} workspace/${r.gate}: ${r.message}`);
772
+ } else {
773
+ ctx.error(`workspace/${r.gate}: ${r.message}`);
774
+ }
775
+ }
776
+
777
+ if (!results.passed) {
778
+ return {
779
+ passed: false,
780
+ errorOutput: `${results.errors} workspace gate(s) failed, ${results.warnings} warning(s)`
781
+ };
782
+ }
783
+
784
+ return { passed: true };
785
+ }
786
+
720
787
  const GATE_REGISTRY = {
721
788
  tests: testsGate,
722
789
  lint: lintGate,
@@ -737,6 +804,8 @@ const GATE_REGISTRY = {
737
804
  uiVerification: verificationGate,
738
805
  apiVerification: verificationGate,
739
806
  testDiscovery: testDiscoveryGate,
807
+ // Workspace gates (conditional — auto-skip when not in workspace)
808
+ workspaceCompliance: workspaceGate,
740
809
  };
741
810
 
742
811
  /**
@@ -782,5 +851,6 @@ module.exports = {
782
851
  generatedTestsPassGate,
783
852
  verificationGate,
784
853
  testDiscoveryGate,
854
+ workspaceGate,
785
855
  unknownGate,
786
856
  };
@@ -1,64 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Meta-documentation about how project rules are organized"
4
- ---
5
- # Project Rules
6
-
7
- This directory contains coding rules and patterns for this project, organized by category.
8
-
9
- ## Structure
10
-
11
- ```
12
- .claude/rules/
13
- ├── code-style/ # Naming conventions, formatting
14
- │ └── naming-conventions.md
15
- ├── security/ # Security patterns and practices
16
- │ └── security-patterns.md
17
- ├── architecture/ # Design decisions and patterns
18
- │ ├── component-reuse.md
19
- │ └── model-management.md
20
- └── README.md
21
- ```
22
-
23
- ## How Rules Work
24
-
25
- Rules are automatically loaded by Claude Code based on:
26
- - **alwaysApply: true** - Rule is always loaded
27
- - **alwaysApply: false** - Rule is loaded based on `globs` or `description` relevance
28
- - **globs** - File patterns that trigger rule loading
29
-
30
- ## Adding New Rules
31
-
32
- 1. Choose the appropriate category subdirectory
33
- 2. Create a `.md` file with frontmatter:
34
-
35
- ```yaml
36
- ---
37
- alwaysApply: false
38
- description: "Brief description for relevance matching"
39
- globs: src/**/*.ts # Optional: only load for these files
40
- ---
41
- ```
42
-
43
- 3. Write the rule content in markdown
44
-
45
- ## Categories
46
-
47
- | Category | Purpose |
48
- |----------|---------|
49
- | code-style | Naming conventions, formatting, file structure |
50
- | security | Security patterns, input validation, safe practices |
51
- | architecture | Design decisions, component patterns, system organization |
52
-
53
- ## Auto-Generation
54
-
55
- Some rules can be auto-generated from `.workflow/state/decisions.md`:
56
-
57
- ```bash
58
- node scripts/flow-rules-sync.js
59
- ```
60
-
61
- The sync script will route rules to appropriate category subdirectories.
62
-
63
- ---
64
- Last updated: 2026-01-12
@@ -1,77 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "All AI-context documents must use PIN markers for targeted context loading"
4
- globs: ".workflow/**/*.md"
5
- ---
6
-
7
- # Document Structure for AI Context
8
-
9
- All documents in `.workflow/` that are used as AI context MUST follow the PIN standard.
10
-
11
- ## Required Structure
12
-
13
- ### 1. Header with PIN List
14
- Every document starts with a comment listing all pins in the document:
15
- ```markdown
16
- <!-- PINS: pin1, pin2, pin3 -->
17
- ```
18
-
19
- ### 2. Section PIN Markers
20
- Each major section has a PIN marker comment:
21
- ```markdown
22
- ### Section Title
23
- <!-- PIN: section-specific-pin -->
24
- [Content]
25
- ```
26
-
27
- ### 3. PIN Naming Convention
28
- - Use kebab-case: `user-authentication`, not `userAuthentication`
29
- - Use semantic names: `error-handling`, not `eh`
30
- - Use compound names for specificity: `json-parse-safety`
31
-
32
- ## Why PINs Matter
33
-
34
- The PIN system enables:
35
- 1. **Targeted context loading**: Only load sections relevant to current task
36
- 2. **Cheaper model routing**: Haiku can fetch only relevant sections for Opus
37
- 3. **Change detection**: Hash sections independently for smart invalidation
38
- 4. **Cross-reference**: Link sections by PIN across documents
39
-
40
- ## Example Document
41
-
42
- ```markdown
43
- # Config Reference
44
-
45
- <!-- PINS: database, authentication, api-keys, environment -->
46
-
47
- ## Database Settings
48
- <!-- PIN: database -->
49
- | Setting | Default | Description |
50
- |---------|---------|-------------|
51
-
52
- ## Authentication
53
- <!-- PIN: authentication -->
54
- | Setting | Default | Description |
55
- |---------|---------|-------------|
56
- ```
57
-
58
- ## Parsing
59
-
60
- The PIN system automatically parses documents with:
61
- - `flow-section-index.js` - Generates section index with pins
62
- - `flow-section-resolver.js` - Resolves sections by PIN lookup
63
- - `getSectionsByPins(['auth', 'security'])` - Fetch only relevant sections
64
-
65
- ## Files That Must Have PINs
66
-
67
- | File | Required PINs |
68
- |------|---------------|
69
- | `decisions.md` | Per coding rule/pattern |
70
- | `app-map.md` | Per component/screen |
71
- | `product.md` | Per product section |
72
- | `stack.md` | Per technology |
73
-
74
- ## Validation
75
-
76
- Run `node scripts/flow-section-index.js --force` to regenerate the index.
77
- Check `.workflow/state/section-index.json` for indexed sections and their pins.
@@ -1,174 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Dual-repo management rules for wogi-flow and wogiflow-cloud"
4
- globs: "package.json,lib/installer.js,lib/extension-points.js"
5
- ---
6
- # Dual-Repo Management: wogi-flow + wogiflow-cloud
7
-
8
- **Added**: 2026-02-28
9
- **Source**: User directive — formalize dual-repo architecture decisions
10
-
11
- ## Repository Ownership
12
-
13
- | Repo | Package | Visibility | Purpose |
14
- |------|---------|-----------|---------|
15
- | `wogi-flow` | `wogiflow` (npm) | Public (AGPL-3.0) | Free CLI, workflow engine, all local-only features |
16
- | `wogiflow-cloud` | `@wogiflow/teams` (client), `wogiflow-cloud-server` (server) | Private | Teams backend, client hooks, dashboard, portal logic |
17
- | `wogiflow-portal` | N/A (static site) | Public | wogi.ai — landing page, login, signup, knowledge base |
18
-
19
- ## Hard Rule: No Teams Code in the Free Repo
20
-
21
- Team-specific logic MUST NEVER appear in `wogi-flow`. This includes:
22
- - Auth/login UI beyond the thin `wogi login`/`wogi logout` adapter
23
- - Sync engines, presence, real-time features
24
- - Team CRUD, roles, permissions
25
- - Dashboard pages
26
- - Server-side API routes
27
-
28
- The free repo provides **extension points** (hooks in `lib/extension-points.js`) that the cloud client plugs into. The adapter pattern is:
29
- - `wogi-flow` exports hook interfaces and config schema
30
- - `@wogiflow/teams` imports those interfaces and adds team behavior
31
- - All team logic executes from `@wogiflow/teams`, never from `wogiflow` core
32
-
33
- ## Version Management
34
-
35
- ### Independent Versions, Mutual Awareness
36
-
37
- Each repo has its own semver version. They are NOT locked together.
38
-
39
- - `wogi-flow` → `package.json` version (currently 1.6.0)
40
- - `wogiflow-cloud` server → `packages/server/package.json` version (currently 0.1.0)
41
- - `@wogiflow/teams` client → `packages/client/package.json` version (currently 0.1.0)
42
-
43
- ### Cross-Repo Version File
44
-
45
- Each repo maintains a `.workflow/state/partner-versions.json` that records the last-known version of the other repo:
46
-
47
- ```json
48
- // In wogi-flow:
49
- {
50
- "self": { "package": "wogiflow", "version": "1.6.0" },
51
- "partners": {
52
- "wogiflow-cloud-server": { "version": "0.1.0", "checkedAt": "2026-02-28" },
53
- "wogiflow-teams-client": { "version": "0.1.0", "minCompatible": "1.5.0", "checkedAt": "2026-02-28" }
54
- }
55
- }
56
-
57
- // In wogiflow-cloud:
58
- {
59
- "self": { "package": "wogiflow-cloud", "version": "0.1.0" },
60
- "partners": {
61
- "wogiflow": { "version": "1.6.0", "checkedAt": "2026-02-28" }
62
- }
63
- }
64
- ```
65
-
66
- **Update rule**: When releasing either repo, update `partner-versions.json` in BOTH repos.
67
-
68
- ### Compatibility Contract
69
-
70
- The `@wogiflow/teams` client declares its minimum compatible `wogiflow` version via peerDependencies:
71
-
72
- ```json
73
- "peerDependencies": {
74
- "wogiflow": ">=1.5.0"
75
- }
76
- ```
77
-
78
- **When to bump the minimum**:
79
- - When the free repo removes or renames an exported function that the client uses
80
- - When the free repo changes the shape of config.json, ready.json, or other state files
81
- - When the free repo changes hook interfaces (entry point signatures, event payloads)
82
-
83
- **When NOT to bump**:
84
- - New features added to the free repo (additive changes are always compatible)
85
- - Internal refactoring that doesn't change exports
86
-
87
- ## Interface Contract (Public API Surface)
88
-
89
- The cloud client depends on these interfaces from `wogi-flow`. Changes to any of these require updating the client:
90
-
91
- ### Exported Functions (from scripts/)
92
- - `flow-utils.js`: `getConfig()`, `safeJsonParse()`, `writeJson()`, `generateTaskId()`, `validateTaskId()`, `PATHS`, `getReadyData()`, `saveReadyData()`
93
- - `flow-session-state.js`: `trackTaskStart()`, `trackBypassAttempt()`
94
- - `flow-memory-blocks.js`: `setCurrentTask()`
95
-
96
- ### Hook Interfaces (entry point contracts)
97
- - `PreToolUse` hooks receive: `{ tool, toolInput }` via stdin JSON
98
- - `PostToolUse` hooks receive: `{ tool, toolInput, toolResult }` via stdin JSON
99
- - `TaskCompleted` hooks receive: `{ taskId }` via stdin JSON
100
- - `SessionStart`/`SessionEnd` hooks receive: `{}` via stdin JSON
101
-
102
- ### State File Formats
103
- - `ready.json`: `{ inProgress: [], ready: [], blocked: [], recentlyCompleted: [], backlog: [] }`
104
- - `config.json`: Schema documented in `config.schema.json`
105
- - `decisions.md`: Markdown with `## Section` / `### Rule` structure
106
- - `session-state.json`: `{ taskId, status, lastBriefingAt, ... }`
107
-
108
- ### Config Keys Used by Cloud
109
- - `hooks.rules.*` — all hook toggle keys
110
- - `enforcement.*` — strict mode, task gating
111
- - `semanticMatching.*` — reuse detection thresholds
112
-
113
- **When modifying any of the above**: Check wogiflow-cloud for consumers BEFORE releasing.
114
-
115
- ## Change Propagation Rules
116
-
117
- ### OSS Change → Does Cloud Need Updating?
118
-
119
- | Change Type | Cloud Impact | Action Required |
120
- |-------------|-------------|-----------------|
121
- | New feature (additive) | None | No action needed |
122
- | Bug fix (internal) | None | No action needed |
123
- | Exported function renamed/removed | BREAKING | Update client, bump peerDep minimum |
124
- | State file format changed | BREAKING | Update client parsers |
125
- | Hook interface changed | BREAKING | Update client hooks |
126
- | Config key renamed/removed | BREAKING | Update client config readers |
127
- | New config key added | None (additive) | Client can optionally use it |
128
-
129
- ### Cloud Change → Does OSS Need Updating?
130
-
131
- | Change Type | OSS Impact | Action Required |
132
- |-------------|-----------|-----------------|
133
- | New server feature | None | No action needed |
134
- | New client hook | None | No action needed |
135
- | Client needs new OSS export | REQUIRES | Add export to OSS, release OSS first |
136
- | Dashboard changes | None | Entirely separate |
137
-
138
- ### Release Order
139
-
140
- 1. **OSS first**: If the cloud needs a new OSS feature, release OSS first
141
- 2. **Cloud follows**: Cloud releases independently, referencing the OSS version in peerDeps
142
- 3. **Never**: Release cloud with a dependency on an unreleased OSS version
143
-
144
- ```
145
- OSS v1.7.0 (adds new export)
146
-
147
- Cloud client v0.2.0 (uses new export, peerDep bumped to >=1.7.0)
148
-
149
- Cloud server v0.2.0 (may or may not change)
150
- ```
151
-
152
- ## Web Properties
153
-
154
- | Property | Repo | Purpose |
155
- |----------|------|---------|
156
- | wogi.ai (main site) | `wogiflow-portal` | Landing, login, signup, knowledge base |
157
- | Dashboard (admin UI) | `wogiflow-cloud/packages/dashboard/` | Team admin — served by cloud server |
158
-
159
- The portal is a separate deployment from the dashboard. The portal is public-facing (marketing + auth). The dashboard is authenticated (team management).
160
-
161
- ## Verification Checklist (Before Any Release)
162
-
163
- ### Releasing wogi-flow (OSS):
164
- 1. Check `partner-versions.json` — is cloud version current?
165
- 2. If any exported function/interface changed: grep wogiflow-cloud for consumers
166
- 3. Run `node --check` on all modified scripts
167
- 4. Follow GitHub Release Workflow (decisions.md)
168
- 5. After release: update `partner-versions.json` in wogiflow-cloud
169
-
170
- ### Releasing wogiflow-cloud:
171
- 1. Check `partner-versions.json` — is OSS version current?
172
- 2. Verify `peerDependencies.wogiflow` range includes current OSS version
173
- 3. If client needs new OSS export: release OSS first
174
- 4. After release: update `partner-versions.json` in wogi-flow
@@ -1,87 +0,0 @@
1
- ---
2
- alwaysApply: false
3
- description: "Cleanup checklist when refactoring or renaming features"
4
- globs:
5
- - "scripts/*.js"
6
- - ".claude/skills/**/*"
7
- ---
8
-
9
- # Feature Refactoring Cleanup
10
-
11
- When refactoring, renaming, or replacing a feature, ensure complete cleanup of the old implementation.
12
-
13
- ## Mandatory Cleanup Checklist
14
-
15
- When a feature is refactored or renamed, you MUST:
16
-
17
- ### 1. Remove Old Code
18
- - [ ] Delete old script files (e.g., `flow-old-feature.js`)
19
- - [ ] Remove old skill directories (e.g., `.claude/skills/old-feature/`)
20
- - [ ] Remove old hook files if applicable
21
-
22
- ### 2. Update Configuration
23
- - [ ] Rename config keys (e.g., `oldFeature` → `newFeature`)
24
- - [ ] Remove from `skills.installed` array if skill was removed
25
- - [ ] Update any feature flags
26
-
27
- ### 3. Update Documentation
28
- - [ ] Rename/update doc files in `.claude/docs/`
29
- - [ ] Update command references in `commands.md`
30
- - [ ] Update skill-matching.md if skill changed
31
- - [ ] Search for old name in all `.md` files
32
-
33
- ### 4. Clean References
34
- - [ ] Search codebase: `grep -r "old-feature-name" .`
35
- - [ ] Update imports in dependent scripts
36
- - [ ] Update any hardcoded references
37
-
38
- ### 5. Update State Files
39
- - [ ] Clean `.workflow/state/` of old state files
40
- - [ ] Update `ready.json` if tasks reference old feature
41
- - [ ] Archive old change specs
42
-
43
- ## Search Commands
44
-
45
- Run these to find lingering references:
46
-
47
- ```bash
48
- # Find all references to old feature
49
- grep -r "old-feature-name" --include="*.js" --include="*.md" --include="*.json" .
50
-
51
- # Find in config
52
- grep "oldFeatureName" .workflow/config.json
53
-
54
- # Find skill references
55
- grep -r "old-feature" .claude/
56
- ```
57
-
58
- ## Why This Matters
59
-
60
- Incomplete cleanup causes:
61
- - **Confusion**: Old commands/skills appear to work but don't
62
- - **Bloat**: Dead code accumulates
63
- - **Errors**: Old references cause runtime failures
64
- - **Documentation drift**: Docs describe non-existent features
65
-
66
- ## Example: transcript-digestion → long-input-gate
67
-
68
- When this refactoring happened without proper cleanup:
69
-
70
- | Artifact | Status | Should Have Been |
71
- |----------|--------|------------------|
72
- | `.claude/skills/transcript-digestion/` | Left behind | Deleted |
73
- | `config.transcriptDigestion` | Left as-is | Renamed to `longInputGate` |
74
- | `skills.installed` array | Still listed | Removed |
75
- | `skill-matching.md` | Old references | Updated |
76
- | `transcript-digestion.md` doc | Still existed | Renamed/rewritten |
77
-
78
- ## Automation Opportunity
79
-
80
- Consider adding a `flow refactor-cleanup <old-name> <new-name>` command that:
81
- 1. Searches for all references
82
- 2. Shows what needs updating
83
- 3. Optionally auto-updates simple cases
84
-
85
- ---
86
-
87
- Last updated: 2026-01-14