specweave 1.0.67 → 1.0.68

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "1.0.67",
3
+ "version": "1.0.68",
4
4
  "description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,6 +13,14 @@ description: Start autonomous execution session with stop hook integration. Work
13
13
  /sw:auto [INCREMENT_IDS...] [OPTIONS]
14
14
  ```
15
15
 
16
+ :::tip šŸš€ Claude Code's Game-Changing Features for Auto Mode
17
+ **Compact Command (VSCode)** — Use `compact` mode to keep Claude Code inside your VSCode window. Work continuously for **hours** in the same session without context switching between terminal and editor. Perfect for long auto mode sessions!
18
+
19
+ **STOP Hooks with Subagents** — Stop hooks now work with spawned subagents! This means `/sw:auto` can validate quality gates at EVERY level of execution. When auto mode spawns specialized agents (QA, Security, Performance), the stop hook validates their results before allowing the session to continue.
20
+
21
+ **Real-world proof**: Boris Cherny (Claude Code creator) shipped 259 PRs, 497 commits, 40,000 lines in one month without opening an IDE — using autonomous execution with stop hooks. [See demo](https://x.com/bcherny/status/2004916410687050167)
22
+ :::
23
+
16
24
  ## Arguments
17
25
 
18
26
  - `INCREMENT_IDS`: One or more increment IDs to process (e.g., `0001`, `0001-feature`)
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { ACStatusManager } from "../vendor/core/increment/ac-status-manager.js";
3
+ import { SyncCoordinator } from "../../../../dist/src/sync/sync-coordinator.js";
4
+ import { consoleLogger } from "../vendor/utils/logger.js";
5
+ import { readFileSync, existsSync } from "fs";
6
+ import * as path from "path";
3
7
  async function updateACStatus(incrementId) {
4
8
  try {
5
9
  const projectRoot = process.cwd();
@@ -25,6 +29,7 @@ async function updateACStatus(incrementId) {
25
29
  console.log("\n\u{1F4DD} Changes:");
26
30
  result.changes.forEach((change) => console.log(` ${change}`));
27
31
  }
32
+ await syncACsToGitHub(projectRoot, incrementId);
28
33
  } else if (result.synced) {
29
34
  console.log("\u2705 All ACs already in sync (no changes needed)");
30
35
  } else {
@@ -34,6 +39,51 @@ async function updateACStatus(incrementId) {
34
39
  console.error("\u274C Error updating AC status:", error);
35
40
  }
36
41
  }
42
+ async function syncACsToGitHub(projectRoot, incrementId) {
43
+ try {
44
+ const configPath = path.join(projectRoot, ".specweave/config.json");
45
+ if (!existsSync(configPath)) {
46
+ console.log("\u2139\uFE0F No config.json found, skipping GitHub sync");
47
+ return;
48
+ }
49
+ const configContent = readFileSync(configPath, "utf-8");
50
+ const config = JSON.parse(configContent);
51
+ const isGitHubEnabled = config.sync?.github?.enabled || config.sync?.profiles && Object.values(config.sync.profiles).some(
52
+ (p) => p?.provider === "github"
53
+ ) || config.sync?.provider === "github";
54
+ if (!isGitHubEnabled) {
55
+ console.log("\u2139\uFE0F GitHub sync not enabled, skipping");
56
+ return;
57
+ }
58
+ const canUpdateExternal = config.sync?.settings?.canUpdateExternalItems !== false;
59
+ if (!canUpdateExternal) {
60
+ console.log("\u2139\uFE0F canUpdateExternalItems=false, skipping GitHub sync");
61
+ return;
62
+ }
63
+ console.log("\n\u{1F517} Syncing AC checkboxes to GitHub...");
64
+ const coordinator = new SyncCoordinator({
65
+ projectRoot,
66
+ incrementId,
67
+ logger: consoleLogger
68
+ });
69
+ const syncResult = await coordinator.syncACCheckboxesToGitHub(config, {
70
+ addComment: false
71
+ // Don't add comment on every AC update (prevent spam)
72
+ });
73
+ if (syncResult.success && syncResult.updated > 0) {
74
+ console.log(` \u2705 Updated ${syncResult.updated} AC(s) in GitHub issues`);
75
+ if (syncResult.issues.length > 0) {
76
+ console.log(` \u{1F4DD} Issues updated: ${syncResult.issues.join(", ")}`);
77
+ }
78
+ } else if (syncResult.success) {
79
+ console.log(" \u2139\uFE0F No GitHub updates needed");
80
+ } else {
81
+ console.log(" \u26A0\uFE0F GitHub sync had errors (non-blocking)");
82
+ }
83
+ } catch (error) {
84
+ console.log(` \u26A0\uFE0F GitHub sync failed: ${error.message}`);
85
+ }
86
+ }
37
87
  const isMainModule = import.meta.url === `file://${process.argv[1]}`;
38
88
  if (isMainModule) {
39
89
  const incrementId = process.argv[2];
@@ -9,6 +9,7 @@
9
9
  * - Warns about orphaned ACs (no implementing tasks)
10
10
  * - Provides detailed sync result with diff
11
11
  * - Atomic file writes to prevent corruption
12
+ * - **NEW v1.0.68**: Auto-syncs AC checkboxes to GitHub issues
12
13
  *
13
14
  * Flow:
14
15
  * 1. Parse tasks.md → Map AC-IDs to completion status
@@ -16,17 +17,23 @@
16
17
  * 3. Compare task completion vs spec checkboxes
17
18
  * 4. Update spec.md only for 100% complete ACs
18
19
  * 5. Log conflicts, warnings, and changes
20
+ * 6. **NEW**: Sync updated ACs to linked GitHub issues
19
21
  *
20
22
  * Called by: plugins/specweave/hooks/post-task-completion.sh
21
23
  *
22
24
  * Example:
23
25
  * - Tasks: T-001 [x], T-002 [x] (both have AC-US1-01) → AC-US1-01 100% complete
24
26
  * - spec.md: - [ ] AC-US1-01 → - [x] AC-US1-01 āœ…
27
+ * - GitHub issue: - [ ] **AC-US1-01** → - [x] **AC-US1-01** šŸ”—
25
28
  * - Tasks: T-003 [x], T-004 [ ] (both have AC-US1-02) → AC-US1-02 50% complete
26
29
  * - spec.md: - [ ] AC-US1-02 → NO CHANGE (partial completion)
27
30
  */
28
31
 
29
32
  import { ACStatusManager } from '../vendor/core/increment/ac-status-manager.js';
33
+ import { SyncCoordinator } from '../../../../dist/src/sync/sync-coordinator.js';
34
+ import { consoleLogger } from '../vendor/utils/logger.js';
35
+ import { readFileSync, existsSync } from 'fs';
36
+ import * as path from 'path';
30
37
 
31
38
  /**
32
39
  * Main entry point - uses ACStatusManager for sophisticated sync
@@ -68,6 +75,9 @@ async function updateACStatus(incrementId: string): Promise<void> {
68
75
  console.log('\nšŸ“ Changes:');
69
76
  result.changes.forEach((change: string) => console.log(` ${change}`));
70
77
  }
78
+
79
+ // NEW v1.0.68: Auto-sync AC checkboxes to GitHub issues
80
+ await syncACsToGitHub(projectRoot, incrementId);
71
81
  } else if (result.synced) {
72
82
  console.log('āœ… All ACs already in sync (no changes needed)');
73
83
  } else {
@@ -80,6 +90,79 @@ async function updateACStatus(incrementId: string): Promise<void> {
80
90
  }
81
91
  }
82
92
 
93
+ /**
94
+ * Sync AC checkboxes to GitHub issues (v1.0.68)
95
+ *
96
+ * CRITICAL FIX: Previously, AC completion only updated spec.md locally.
97
+ * GitHub issues were NOT updated until manual /sw:sync-progress was run.
98
+ * This fixes issue #966 by auto-syncing to GitHub after AC updates.
99
+ *
100
+ * @param projectRoot - Project root directory
101
+ * @param incrementId - Increment ID
102
+ */
103
+ async function syncACsToGitHub(projectRoot: string, incrementId: string): Promise<void> {
104
+ try {
105
+ // Check if GitHub sync is enabled in config
106
+ const configPath = path.join(projectRoot, '.specweave/config.json');
107
+ if (!existsSync(configPath)) {
108
+ console.log('ā„¹ļø No config.json found, skipping GitHub sync');
109
+ return;
110
+ }
111
+
112
+ const configContent = readFileSync(configPath, 'utf-8');
113
+ const config = JSON.parse(configContent);
114
+
115
+ // Check for GitHub sync enabled
116
+ const isGitHubEnabled =
117
+ config.sync?.github?.enabled ||
118
+ (config.sync?.profiles && Object.values(config.sync.profiles).some(
119
+ (p: any) => p?.provider === 'github'
120
+ )) ||
121
+ config.sync?.provider === 'github';
122
+
123
+ if (!isGitHubEnabled) {
124
+ console.log('ā„¹ļø GitHub sync not enabled, skipping');
125
+ return;
126
+ }
127
+
128
+ // Check if external sync is allowed
129
+ const canUpdateExternal = config.sync?.settings?.canUpdateExternalItems !== false;
130
+ if (!canUpdateExternal) {
131
+ console.log('ā„¹ļø canUpdateExternalItems=false, skipping GitHub sync');
132
+ return;
133
+ }
134
+
135
+ console.log('\nšŸ”— Syncing AC checkboxes to GitHub...');
136
+
137
+ // Use SyncCoordinator for GitHub sync
138
+ const coordinator = new SyncCoordinator({
139
+ projectRoot,
140
+ incrementId,
141
+ logger: consoleLogger
142
+ });
143
+
144
+ const syncResult = await coordinator.syncACCheckboxesToGitHub(config, {
145
+ addComment: false // Don't add comment on every AC update (prevent spam)
146
+ });
147
+
148
+ if (syncResult.success && syncResult.updated > 0) {
149
+ console.log(` āœ… Updated ${syncResult.updated} AC(s) in GitHub issues`);
150
+ if (syncResult.issues.length > 0) {
151
+ console.log(` šŸ“ Issues updated: ${syncResult.issues.join(', ')}`);
152
+ }
153
+ } else if (syncResult.success) {
154
+ console.log(' ā„¹ļø No GitHub updates needed');
155
+ } else {
156
+ console.log(' āš ļø GitHub sync had errors (non-blocking)');
157
+ }
158
+
159
+ } catch (error: any) {
160
+ // Non-blocking: Log but don't fail the hook
161
+ console.log(` āš ļø GitHub sync failed: ${error.message}`);
162
+ // Continue - local AC sync already succeeded
163
+ }
164
+ }
165
+
83
166
  // CLI Entry Point (ES Module)
84
167
  const isMainModule = import.meta.url === `file://${process.argv[1]}`;
85
168