specweave 2.0.3 → 2.1.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 (90) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.md +15 -6
  3. package/dist/dashboard/assets/index-BeKUULf0.css +1 -0
  4. package/dist/dashboard/assets/index-Bf5TF0_l.js +13 -0
  5. package/dist/dashboard/index.html +2 -2
  6. package/dist/src/cli/commands/sync.d.ts.map +1 -1
  7. package/dist/src/cli/commands/sync.js +23 -5
  8. package/dist/src/cli/commands/sync.js.map +1 -1
  9. package/dist/src/core/doctor/checkers/hooks-checker.d.ts +1 -1
  10. package/dist/src/core/doctor/checkers/hooks-checker.js +1 -1
  11. package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -1
  12. package/dist/src/core/hooks/handlers/session-start.js +20 -0
  13. package/dist/src/core/hooks/handlers/session-start.js.map +1 -1
  14. package/dist/src/core/intent/portable-context.d.ts +4 -0
  15. package/dist/src/core/intent/portable-context.d.ts.map +1 -0
  16. package/dist/src/core/intent/portable-context.js +68 -0
  17. package/dist/src/core/intent/portable-context.js.map +1 -0
  18. package/dist/src/core/intent/types.d.ts +28 -0
  19. package/dist/src/core/intent/types.d.ts.map +1 -0
  20. package/dist/src/core/intent/types.js +3 -0
  21. package/dist/src/core/intent/types.js.map +1 -0
  22. package/dist/src/core/intent/validation.d.ts +5 -0
  23. package/dist/src/core/intent/validation.d.ts.map +1 -0
  24. package/dist/src/core/intent/validation.js +39 -0
  25. package/dist/src/core/intent/validation.js.map +1 -0
  26. package/dist/src/core/session/handoff-pointer.d.ts +4 -0
  27. package/dist/src/core/session/handoff-pointer.d.ts.map +1 -0
  28. package/dist/src/core/session/handoff-pointer.js +60 -0
  29. package/dist/src/core/session/handoff-pointer.js.map +1 -0
  30. package/dist/src/core/session/work-handoff.d.ts.map +1 -1
  31. package/dist/src/core/session/work-handoff.js +10 -3
  32. package/dist/src/core/session/work-handoff.js.map +1 -1
  33. package/dist/src/dashboard/server/dashboard-server.d.ts +1 -0
  34. package/dist/src/dashboard/server/dashboard-server.d.ts.map +1 -1
  35. package/dist/src/dashboard/server/dashboard-server.js +10 -90
  36. package/dist/src/dashboard/server/dashboard-server.js.map +1 -1
  37. package/dist/src/dashboard/server/data/cost-aggregator.d.ts +10 -5
  38. package/dist/src/dashboard/server/data/cost-aggregator.d.ts.map +1 -1
  39. package/dist/src/dashboard/server/data/cost-aggregator.js +31 -33
  40. package/dist/src/dashboard/server/data/cost-aggregator.js.map +1 -1
  41. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts +0 -1
  42. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts.map +1 -1
  43. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js +14 -66
  44. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js.map +1 -1
  45. package/dist/src/dashboard/server/data/dashboard-task-board.d.ts +4 -0
  46. package/dist/src/dashboard/server/data/dashboard-task-board.d.ts.map +1 -0
  47. package/dist/src/dashboard/server/data/dashboard-task-board.js +56 -0
  48. package/dist/src/dashboard/server/data/dashboard-task-board.js.map +1 -0
  49. package/dist/src/dashboard/server/data/intent-store.d.ts +19 -0
  50. package/dist/src/dashboard/server/data/intent-store.d.ts.map +1 -0
  51. package/dist/src/dashboard/server/data/intent-store.js +268 -0
  52. package/dist/src/dashboard/server/data/intent-store.js.map +1 -0
  53. package/dist/src/dashboard/server/data/local-sessions.d.ts +15 -0
  54. package/dist/src/dashboard/server/data/local-sessions.d.ts.map +1 -0
  55. package/dist/src/dashboard/server/data/local-sessions.js +197 -0
  56. package/dist/src/dashboard/server/data/local-sessions.js.map +1 -0
  57. package/dist/src/dashboard/server/data/work-projection.d.ts +8 -0
  58. package/dist/src/dashboard/server/data/work-projection.d.ts.map +1 -0
  59. package/dist/src/dashboard/server/data/work-projection.js +175 -0
  60. package/dist/src/dashboard/server/data/work-projection.js.map +1 -0
  61. package/dist/src/dashboard/server/file-watcher.d.ts.map +1 -1
  62. package/dist/src/dashboard/server/file-watcher.js +2 -1
  63. package/dist/src/dashboard/server/file-watcher.js.map +1 -1
  64. package/dist/src/dashboard/server/local-request.d.ts +4 -0
  65. package/dist/src/dashboard/server/local-request.d.ts.map +1 -0
  66. package/dist/src/dashboard/server/local-request.js +29 -0
  67. package/dist/src/dashboard/server/local-request.js.map +1 -0
  68. package/dist/src/dashboard/server/routes/work-routes.d.ts +5 -0
  69. package/dist/src/dashboard/server/routes/work-routes.d.ts.map +1 -0
  70. package/dist/src/dashboard/server/routes/work-routes.js +37 -0
  71. package/dist/src/dashboard/server/routes/work-routes.js.map +1 -0
  72. package/dist/src/dashboard/types.d.ts +3 -3
  73. package/dist/src/dashboard/types.d.ts.map +1 -1
  74. package/dist/src/dashboard/work-types.d.ts +39 -0
  75. package/dist/src/dashboard/work-types.d.ts.map +1 -0
  76. package/dist/src/dashboard/work-types.js +3 -0
  77. package/dist/src/dashboard/work-types.js.map +1 -0
  78. package/dist/src/sync/external-change-puller.d.ts +19 -0
  79. package/dist/src/sync/external-change-puller.d.ts.map +1 -1
  80. package/dist/src/sync/external-change-puller.js +87 -77
  81. package/dist/src/sync/external-change-puller.js.map +1 -1
  82. package/package.json +3 -3
  83. package/plugins/specweave/.claude-plugin/plugin.json +2 -2
  84. package/plugins/specweave/hooks/hooks.json +1 -24
  85. package/plugins/specweave/hooks/run.mjs +24 -1
  86. package/plugins/specweave/skills/increment/SKILL.md +7 -5
  87. package/src/templates/AGENTS.md.template +5 -5
  88. package/src/templates/CLAUDE.md.template +5 -5
  89. package/dist/dashboard/assets/index-BiJhGDZV.js +0 -13
  90. package/dist/dashboard/assets/index-heYRtWFf.css +0 -1
@@ -12,6 +12,17 @@
12
12
  * @module sync/external-change-puller
13
13
  */
14
14
  import { consoleLogger } from '../utils/logger.js';
15
+ import { maskCredentials } from '../utils/credential-masker.js';
16
+ /** A rejected fetch must not be mistaken for a complete synchronization. */
17
+ export class ExternalPullError extends Error {
18
+ constructor(changes, failures, completedPlatforms) {
19
+ super(`External pull incomplete: ${failures.map(f => f.platform).join(', ')}.`);
20
+ this.changes = changes;
21
+ this.failures = failures;
22
+ this.completedPlatforms = completedPlatforms;
23
+ this.name = 'ExternalPullError';
24
+ }
25
+ }
15
26
  /**
16
27
  * ExternalChangePuller - Fetches changes from external tools
17
28
  *
@@ -23,6 +34,7 @@ export class ExternalChangePuller {
23
34
  this.projectRoot = options.projectRoot;
24
35
  this.logger = options.logger ?? consoleLogger;
25
36
  this.platforms = options.platforms ?? ['ado', 'jira', 'github'];
37
+ this.github = options.github;
26
38
  }
27
39
  /**
28
40
  * Fetch recent changes from all configured platforms
@@ -30,30 +42,42 @@ export class ExternalChangePuller {
30
42
  * @param since - Timestamp to query changes from
31
43
  * @param linkedItems - Optional map of platform -> item IDs to filter
32
44
  * @returns Array of external changes from all platforms
45
+ * @throws ExternalPullError with successful results when any provider fails
33
46
  */
34
47
  async fetchRecentChanges(since, linkedItems) {
35
48
  const allChanges = [];
49
+ const failures = [];
50
+ const recordFailure = (platform, error) => {
51
+ const message = maskCredentials(error instanceof Error ? error.message : String(error));
52
+ failures.push({ platform, message });
53
+ this.logger.warn(`${platform} fetch failed: ${message}`);
54
+ };
36
55
  this.logger.log(`⬇️ Fetching changes since ${since.toISOString()}`);
37
56
  // Fetch from each platform in parallel
38
57
  const fetchPromises = [];
39
58
  if (this.platforms.includes('ado')) {
40
59
  fetchPromises.push(this.fetchAdoChanges(since, linkedItems?.ado)
41
60
  .then(changes => { allChanges.push(...changes); })
42
- .catch(err => { this.logger.warn(`ADO fetch failed: ${err.message}`); }));
61
+ .catch(err => { recordFailure('ado', err); }));
43
62
  }
44
63
  if (this.platforms.includes('jira')) {
45
64
  fetchPromises.push(this.fetchJiraChanges(since, linkedItems?.jira)
46
65
  .then(changes => { allChanges.push(...changes); })
47
- .catch(err => { this.logger.warn(`JIRA fetch failed: ${err.message}`); }));
66
+ .catch(err => { recordFailure('jira', err); }));
48
67
  }
49
68
  if (this.platforms.includes('github')) {
50
69
  fetchPromises.push(this.fetchGitHubChanges(since, linkedItems?.github)
51
70
  .then(changes => { allChanges.push(...changes); })
52
- .catch(err => { this.logger.warn(`GitHub fetch failed: ${err.message}`); }));
71
+ .catch(err => { recordFailure('github', err); }));
53
72
  }
54
73
  await Promise.all(fetchPromises);
55
74
  // Sort by changedAt (most recent first)
56
75
  allChanges.sort((a, b) => new Date(b.changedAt).getTime() - new Date(a.changedAt).getTime());
76
+ if (failures.length > 0) {
77
+ failures.sort((a, b) => a.platform.localeCompare(b.platform));
78
+ const completed = this.platforms.filter(platform => !failures.some(f => f.platform === platform));
79
+ throw new ExternalPullError(allChanges, failures, completed);
80
+ }
57
81
  this.logger.log(`📥 Fetched ${allChanges.length} changes from external tools`);
58
82
  return allChanges;
59
83
  }
@@ -61,91 +85,77 @@ export class ExternalChangePuller {
61
85
  * Fetch changes from Azure DevOps
62
86
  */
63
87
  async fetchAdoChanges(since, linkedItemIds) {
64
- try {
65
- // Dynamic import to avoid initialization errors when ADO is not configured
66
- const { AdoClient } = await import('../integrations/ado/ado-client.js');
67
- const client = new AdoClient();
68
- const adoChanges = await client.fetchRecentChanges(since, linkedItemIds);
69
- // Map to unified format
70
- return adoChanges.map(change => ({
71
- platform: 'ado',
72
- externalId: change.externalId,
73
- changedAt: change.changedAt,
74
- changedBy: change.changedBy,
75
- changedFields: change.changedFields,
76
- currentState: {
77
- status: change.currentState.status,
78
- priority: change.currentState.priority,
79
- assignee: change.currentState.assignee,
80
- },
81
- }));
82
- }
83
- catch (err) {
84
- this.logger.debug(`ADO not configured or error: ${err.message}`);
85
- return [];
86
- }
88
+ // Dynamic import to avoid initialization errors when ADO is not configured
89
+ const { AdoClient } = await import('../integrations/ado/ado-client.js');
90
+ const client = new AdoClient();
91
+ const adoChanges = await client.fetchRecentChanges(since, linkedItemIds);
92
+ // Map to unified format
93
+ return adoChanges.map(change => ({
94
+ platform: 'ado',
95
+ externalId: change.externalId,
96
+ changedAt: change.changedAt,
97
+ changedBy: change.changedBy,
98
+ changedFields: change.changedFields,
99
+ currentState: {
100
+ status: change.currentState.status,
101
+ priority: change.currentState.priority,
102
+ assignee: change.currentState.assignee,
103
+ },
104
+ }));
87
105
  }
88
106
  /**
89
107
  * Fetch changes from JIRA
90
108
  */
91
109
  async fetchJiraChanges(since, linkedIssueKeys) {
92
- try {
93
- // Dynamic import to avoid initialization errors when JIRA is not configured
94
- const { JiraClient } = await import('../integrations/jira/jira-client.js');
95
- const client = new JiraClient();
96
- const jiraChanges = await client.fetchRecentChanges(since, linkedIssueKeys);
97
- // Map to unified format
98
- return jiraChanges.map(change => ({
99
- platform: 'jira',
100
- externalId: change.externalId,
101
- changedAt: change.changedAt,
102
- changedBy: change.changedBy,
103
- changedFields: change.changedFields,
104
- currentState: {
105
- status: change.currentState.status,
106
- priority: change.currentState.priority,
107
- assignee: change.currentState.assignee,
108
- },
109
- }));
110
- }
111
- catch (err) {
112
- this.logger.debug(`JIRA not configured or error: ${err.message}`);
113
- return [];
114
- }
110
+ // Dynamic import to avoid initialization errors when JIRA is not configured
111
+ const { JiraClient } = await import('../integrations/jira/jira-client.js');
112
+ const client = new JiraClient();
113
+ const jiraChanges = await client.fetchRecentChanges(since, linkedIssueKeys);
114
+ // Map to unified format
115
+ return jiraChanges.map(change => ({
116
+ platform: 'jira',
117
+ externalId: change.externalId,
118
+ changedAt: change.changedAt,
119
+ changedBy: change.changedBy,
120
+ changedFields: change.changedFields,
121
+ currentState: {
122
+ status: change.currentState.status,
123
+ priority: change.currentState.priority,
124
+ assignee: change.currentState.assignee,
125
+ },
126
+ }));
115
127
  }
116
128
  /**
117
129
  * Fetch changes from GitHub
118
130
  */
119
131
  async fetchGitHubChanges(since, linkedIssueNumbers) {
120
- try {
121
- // Dynamic import to avoid initialization errors when GitHub is not configured
122
- const { GitHubClientV2 } = await import('../../plugins/specweave/lib/integrations/github/github-client-v2.js');
123
- // Detect repo from git remote
124
- const detected = await GitHubClientV2.detectRepo(this.projectRoot);
125
- if (!detected) {
126
- this.logger.debug('GitHub: No git remote detected');
127
- return [];
128
- }
129
- const client = GitHubClientV2.fromRepo(detected.owner, detected.repo);
130
- const githubChanges = await client.fetchRecentChanges(since, linkedIssueNumbers);
131
- // Map to unified format (GitHub returns slightly different format)
132
- return githubChanges.map(change => ({
133
- platform: 'github',
134
- externalId: change.externalId,
135
- changedAt: change.changedAt,
136
- changedBy: change.changedBy,
137
- changedFields: change.changedFields,
138
- currentState: {
139
- status: change.currentState.status,
140
- priority: null, // GitHub doesn't have priority
141
- assignee: change.currentState.assignee,
142
- },
143
- }));
144
- }
145
- catch (err) {
146
- this.logger.debug(`GitHub not configured or error: ${err.message}`);
147
- return [];
132
+ // Dynamic import to avoid initialization errors when GitHub is not configured
133
+ const { GitHubClientV2 } = await import('../../plugins/specweave/lib/integrations/github/github-client-v2.js');
134
+ // Detect repo from git remote
135
+ const detected = this.github ?? await GitHubClientV2.detectRepo(this.projectRoot);
136
+ if (!detected) {
137
+ throw new Error('No GitHub repository configured and no GitHub remote detected. Run specweave sync setup.');
148
138
  }
139
+ const client = new GitHubClientV2({
140
+ provider: 'github',
141
+ displayName: `${detected.owner}/${detected.repo}`,
142
+ config: { owner: detected.owner, repo: detected.repo, ...(this.github?.token ? { token: this.github.token } : {}) },
143
+ timeRange: { default: '1M', max: '6M' },
144
+ }, this.projectRoot);
145
+ const githubChanges = await client.fetchRecentChanges(since, linkedIssueNumbers);
146
+ // Map to unified format (GitHub returns slightly different format)
147
+ return githubChanges.map(change => ({
148
+ platform: 'github',
149
+ externalId: change.externalId,
150
+ changedAt: change.changedAt,
151
+ changedBy: change.changedBy,
152
+ changedFields: change.changedFields,
153
+ currentState: {
154
+ status: change.currentState.status,
155
+ priority: null, // GitHub doesn't have priority
156
+ assignee: change.currentState.assignee,
157
+ },
158
+ }));
149
159
  }
150
160
  /**
151
161
  * Map external status to SpecWeave status
@@ -1 +1 @@
1
- {"version":3,"file":"external-change-puller.js","sourceRoot":"","sources":["../../../src/sync/external-change-puller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAU,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA6C3D;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAK/B,YAAY,OAAoC;QAC9C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;QAC9C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,kBAAkB,CACtB,KAAW,EACX,WAIC;QAED,MAAM,UAAU,GAAqB,EAAE,CAAC;QAExC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAErE,uCAAuC;QACvC,MAAM,aAAa,GAAoB,EAAE,CAAC;QAE1C,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,aAAa,CAAC,IAAI,CAChB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC;iBAC1C,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;iBACjD,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3E,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,aAAa,CAAC,IAAI,CAChB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC;iBAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;iBACjD,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAC5E,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,aAAa,CAAC,IAAI,CAChB,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC;iBAChD,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;iBACjD,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAEjC,wCAAwC;QACxC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACvB,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAClE,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,UAAU,CAAC,MAAM,8BAA8B,CAAC,CAAC;QAE/E,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAC3B,KAAW,EACX,aAAwB;QAExB,IAAI,CAAC;YACH,2EAA2E;YAC3E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC;YACxE,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAE/B,MAAM,UAAU,GAAwB,MAAM,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YAE9F,wBAAwB;YACxB,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC/B,QAAQ,EAAE,KAAc;gBACxB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,YAAY,EAAE;oBACZ,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;oBAClC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;oBACtC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;iBACvC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAC5B,KAAW,EACX,eAA0B;QAE1B,IAAI,CAAC;YACH,4EAA4E;YAC5E,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAEhC,MAAM,WAAW,GAAyB,MAAM,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YAElG,wBAAwB;YACxB,OAAO,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAChC,QAAQ,EAAE,MAAe;gBACzB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,YAAY,EAAE;oBACZ,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;oBAClC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;oBACtC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;iBACvC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,KAAW,EACX,kBAA6B;QAE7B,IAAI,CAAC;YACH,8EAA8E;YAC9E,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,qEAAqE,CAAC,CAAC;YAE/G,8BAA8B;YAC9B,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACpD,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtE,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;YAEjF,mEAAmE;YACnE,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAClC,QAAQ,EAAE,QAAiB;gBAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,YAAY,EAAE;oBACZ,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;oBAClC,QAAQ,EAAE,IAA8B,EAAE,+BAA+B;oBACzE,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;iBACvC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACpE,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,oBAAoB,CAClB,QAAmC,EACnC,cAAsB;QAEtB,6BAA6B;QAC7B,MAAM,UAAU,GAA2C;YACzD,GAAG,EAAE;gBACH,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,aAAa;gBACvB,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,WAAW;gBACrB,SAAS,EAAE,WAAW;aACvB;YACD,IAAI,EAAE;gBACJ,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,aAAa;gBAC5B,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,WAAW;gBACrB,WAAW,EAAE,WAAW;aACzB;YACD,MAAM,EAAE;gBACN,MAAM,EAAE,aAAa;gBACrB,QAAQ,EAAE,WAAW;aACtB;SACF,CAAC;QAEF,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvC,OAAO,GAAG,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClF,CAAC;CACF"}
1
+ {"version":3,"file":"external-change-puller.js","sourceRoot":"","sources":["../../../src/sync/external-change-puller.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "2.0.3",
4
- "description": "100+ domain-expert AI skills — PM, Architect, Frontend, QA, Security and more. Skills learn your team's patterns permanently. Spec-first planning, autonomous execution, multi-agent teams, synced to GitHub/JIRA. Claude Code, Cursor, Copilot & more.",
3
+ "version": "2.1.0",
4
+ "description": "Keep intent, specifications, and verified progress portable across AI coding tools. A local live work board, append-only task evidence, explicit handoffs, and optional GitHub/Jira/Azure DevOps integrations.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "specweave": "./bin/specweave.js"
@@ -10,7 +10,7 @@
10
10
  "preinstall": "node scripts/check-node-version.js || exit 0",
11
11
  "preuninstall": "node scripts/preuninstall.cjs",
12
12
  "version": "node scripts/build/auto-changelog.js && node scripts/build/stamp-plugin-version.cjs && git add CHANGELOG.md plugins/specweave/.claude-plugin/plugin.json .claude-plugin/marketplace.json",
13
- "postversion": "echo '✅ Version bumped with CHANGELOG entry'",
13
+ "postversion": "echo '\u2705 Version bumped with CHANGELOG entry'",
14
14
  "clean": "rm -rf dist/",
15
15
  "build": "tsc && npm run build:dashboard && npm run copy:locales && npm run copy:plugins && npm run copy:hook-deps && npm run copy:adapters && npm run stamp:plugin-version",
16
16
  "stamp:plugin-version": "node scripts/build/stamp-plugin-version.cjs",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sw",
3
- "description": "SpecWeave: increment lifecycle for any AI tool. 10 skills (increment, do, done, review, team, handoff, sync, auto, brainstorm, qa), 4 exec-form hooks, and the specweave CLI for everything deterministic.",
4
- "version": "2.0.3",
3
+ "description": "Portable intent and verified progress across coding tools. Ten focused workflow skills, two default lifecycle hooks, and a deterministic CLI and live local dashboard.",
4
+ "version": "2.1.0",
5
5
  "author": {
6
6
  "name": "SpecWeave Team",
7
7
  "url": "https://spec-weave.com"
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "SpecWeave hooks: portable command strings and bounded worker execution.",
2
+ "description": "Minimal hooks: compact session context and an opt-in auto loop. Handoffs are explicit CLI actions.",
3
3
  "hooks": {
4
4
  "SessionStart": [
5
5
  {
@@ -12,18 +12,6 @@
12
12
  ]
13
13
  }
14
14
  ],
15
- "PreToolUse": [
16
- {
17
- "matcher": "Write|Edit",
18
- "hooks": [
19
- {
20
- "type": "command",
21
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run.mjs\" pre-tool-use",
22
- "timeout": 10
23
- }
24
- ]
25
- }
26
- ],
27
15
  "Stop": [
28
16
  {
29
17
  "hooks": [
@@ -34,17 +22,6 @@
34
22
  }
35
23
  ]
36
24
  }
37
- ],
38
- "PreCompact": [
39
- {
40
- "hooks": [
41
- {
42
- "type": "command",
43
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run.mjs\" pre-compact",
44
- "timeout": 10
45
- }
46
- ]
47
- }
48
25
  ]
49
26
  }
50
27
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // SpecWeave hook supervisor: parent deadline remains live while the worker blocks in Git.
3
3
  import { spawn, spawnSync } from 'node:child_process';
4
- import { appendFileSync, mkdirSync } from 'node:fs';
4
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
5
5
  import { homedir } from 'node:os';
6
6
  import path from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
@@ -10,6 +10,27 @@ const worker = path.join(path.dirname(fileURLToPath(import.meta.url)), 'run-work
10
10
  const budget = event === 'stop' ? 25000 : 7500;
11
11
  let child, finished = false, input = '', output = '', size = 0;
12
12
  const started = Date.now();
13
+ // Ordinary turns should not resolve npm, import the CLI, or start a second Node
14
+ // process. Auto mode is explicit and its small local marker is authoritative.
15
+ function hasActiveAutoSession(data) {
16
+ let current = path.resolve(typeof data.cwd === 'string' ? data.cwd : process.cwd());
17
+ for (let depth = 0; depth < 100; depth++) {
18
+ const state = path.join(current, '.specweave', 'state');
19
+ if (existsSync(path.join(current, '.specweave', 'config.json'))) {
20
+ const sessionId = process.env.CLAUDE_SESSION_ID;
21
+ // Match session-state-manager's path-safe IDs, including dots and spaces.
22
+ const scoped = sessionId && !/[/\\]|\.\.|\0/.test(sessionId)
23
+ ? path.join(state, 'sessions', sessionId, 'auto-mode.json') : null;
24
+ const marker = scoped && existsSync(scoped) ? scoped : path.join(state, 'auto-mode.json');
25
+ try { return JSON.parse(readFileSync(marker, 'utf8')).active === true; }
26
+ catch { return false; }
27
+ }
28
+ const parent = path.dirname(current);
29
+ if (parent === current) break;
30
+ current = parent;
31
+ }
32
+ return false;
33
+ }
13
34
  function record(reason) {
14
35
  try {
15
36
  const dir = path.join(homedir(), '.specweave', 'logs');
@@ -49,6 +70,8 @@ process.stdin.on('end',()=>{
49
70
  try {data=JSON.parse(input);if(!data || typeof data!=='object'||Array.isArray(data))throw Error();}
50
71
  catch {return finish({},'invalid_input');}
51
72
  if(!['session-start','pre-tool-use','pre-compact','stop'].includes(event))return finish({});
73
+ if(process.env.SPECWEAVE_DISABLE_HOOKS === '1')return finish({});
74
+ if(event === 'stop' && !hasActiveAutoSession(data))return finish({});
52
75
  const env={...process.env};
53
76
  child=spawn(process.execPath,[worker,event],{env,detached:process.platform !== 'win32',stdio:['pipe','pipe','pipe']});
54
77
  child.stdout.setEncoding('utf8');
@@ -11,11 +11,13 @@ An increment is one folder — `.specweave/increments/NNNN-slug/` — holding
11
11
  `ledger.jsonl` (state, written by the CLI) and `metadata.json`. It is the unit of
12
12
  work and the tracker; every commit for it carries its id in the subject.
13
13
 
14
- ## Plan mode first (blocking)
14
+ ## Scope before implementation
15
15
 
16
- Planning produces a document the user approves before any code is written. If your
17
- tool has a plan mode, enter it now (Claude Code: `EnterPlanMode`) and wait for
18
- confirmation. Do not create files, do not implement, until the plan is approved.
16
+ Write a concise plan for work that needs shared acceptance criteria. Ask only about
17
+ material ambiguity or actions beyond the user's authorization. When the user has
18
+ asked for autonomous execution, make routine decisions and continue through
19
+ implementation and verification. A small self-contained fix can remain a
20
+ lightweight intent without this workflow.
19
21
 
20
22
  ## Steps
21
23
 
@@ -79,7 +81,7 @@ confirmation. Do not create files, do not implement, until the plan is approved.
79
81
  least one task; every task needs a `Test:` that a machine can run (or an explicit
80
82
  "manual: <what to check>"). Shared contracts (types, schema, migrations) go in an early
81
83
  task everything else depends on.
82
- 6. **Present the plan** (problem, ACs, task list, risks) and get approval. Then leave plan mode.
84
+ 6. **Share the plan** (problem, ACs, tasks, material risks). Resolve any remaining decision that needs the user; otherwise continue within existing authorization.
83
85
  7. **Hand off to execution**: `sw:do <id>` for one agent; `sw:team <id>` when the work has
84
86
  3+ disjoint lanes or 15+ tasks.
85
87
 
@@ -1,7 +1,7 @@
1
1
  <!-- SECTION:header required -->
2
2
  # {PROJECT_NAME}
3
3
 
4
- SpecWeave project. Work happens in increments under `.specweave/increments/NNNN-slug/`. `spec.md` (Problem, ACs, Approach) is the source of truth; the ledger records who did what. This file is for Codex, OpenCode, Cursor, Gemini, Aider and humans; Claude Code reads CLAUDE.md (same content). Keep it under one page; project-specific notes go in **Project notes** at the bottom.
4
+ SpecWeave project. Small requests live in the intent board; scoped work lives in increments under `.specweave/increments/NNNN-slug/`. `spec.md` (Problem, ACs, Approach) is the source of truth; the ledger records who did what. This file is for Codex, OpenCode, Cursor, Gemini, Aider and humans; Claude Code reads CLAUDE.md (same content). Keep it under one page; project-specific notes go in **Project notes** at the bottom.
5
5
  <!-- /SECTION -->
6
6
 
7
7
  <!-- SECTION:structure -->
@@ -9,6 +9,7 @@ SpecWeave project. Work happens in increments under `.specweave/increments/NNNN-
9
9
 
10
10
  ```
11
11
  .specweave/
12
+ intents/board.jsonl append-only intent history (latest revision per id; planning state, not verification)
12
13
  increments/NNNN-slug/ spec.md (Problem · ACs · Approach) · tasks.md (tasks + rendered board) · ledger.jsonl (claims/done, CLI-written) · handoff.md · reports/ (evidence; binaries in reports/artifacts/, gitignored)
13
14
  docs/ ADRs and hand-written docs (read before changing architecture)
14
15
  config.json
@@ -23,7 +24,7 @@ Only those files (plus optional `plan.md` when Approach outgrows a page, and `sc
23
24
 
24
25
  | Step | Command (each step is also a standalone skill you can install into any tool with `npx vskill install anton-abyzov/specweave/sw-do` — same for `sw-increment`, `sw-review`, `sw-handoff`, `sw-task`) |
25
26
  |---|---|
26
- | Plan a feature: write `spec.md` (Problem, Scope, `AC-01…` checkboxes, Approach: files that change, order of work, risks, decisions), get approval before any code | `specweave create-increment "title"` |
27
+ | Plan a feature: write `spec.md` (Problem, Scope, `AC-01…` checkboxes, Approach: files that change, order of work, risks, decisions), resolve material scope questions before implementation | `specweave create-increment "title"` |
27
28
  | Work the tasks | `specweave task next` → `specweave task claim T-NN` → implement → commit (`NNNN: …`) → `specweave task done T-NN --run "<test cmd>"` (the command runs through your OS shell: cmd.exe on Windows, sh elsewhere) |
28
29
  | Verify the whole increment | `specweave verify` |
29
30
  | Review before closing (recommended for anything that ships) | in a fresh session: read spec.md, list findings by severity citing path:line, re-verify each before writing `reports/review.md`; the authoring session never approves its own work |
@@ -31,7 +32,7 @@ Only those files (plus optional `plan.md` when Approach outgrows a page, and `sc
31
32
  | Stop for any reason | `specweave handoff` |
32
33
 
33
34
  Without the `specweave` CLI: create the folder by hand (id = highest existing 4-digit prefix + 1, zero-padded); append one JSON line per event to `ledger.jsonl` as UTF-8 without BOM, LF-terminated, e.g. `{"t":"T-01","e":"claim","by":"<tool>@<host>","at":"<ISO>"}` (bash: `>>`; PowerShell: `[IO.File]::AppendAllText('ledger.jsonl', $line + "`n")`, never `>>`, it writes UTF-16); mark done with the same line using `"e":"done","evidence":"<commit sha>"` after the Test command exits 0; write `reports/verify.md` with the real test output and say the increment is ready to close (closing itself needs the CLI).
34
- Start every feature with an increment, even a small one, unless the user says "no increment". Fix a bug by writing the failing test first, then fixing the code without touching the test.
35
+ Use an increment for work that needs shared scope, acceptance criteria, or a handoff. Small self-contained fixes can remain a lightweight intent. For bugs, reproduce the failure and add a regression test when it protects behavior. User authorization carries through routine implementation and verification.
35
36
  <!-- /SECTION -->
36
37
 
37
38
  <!-- SECTION:verify required -->
@@ -48,8 +49,7 @@ Run the project's build/test/lint (see **Commands**) before reporting any task c
48
49
  3. Never edit ledger lines or another task's status; append only. On a git conflict in `ledger.jsonl` keep every line from both sides.
49
50
  4. `done` needs the task's **Test** command exit 0 and a commit sha. A task that turns out unnecessary is closed with `specweave task skip T-NN --reason "..."` (no CLI: append a `skip` ledger line with a reason), never ticked.
50
51
  5. When you stop: `specweave task release --all-mine` then `specweave handoff`.
51
-
52
- Resuming: find the active increment with `specweave status` (or the `NNNN-*` folder whose `metadata.json` has `"status": "active"`), read `spec.md`, then the latest `handoff.md`, then `specweave task next`.
52
+ Resuming: check `.specweave/intents/board.jsonl` (latest revision per id) or `specweave dashboard` for unfinished intents, including work without an increment. Then find the active increment with `specweave status` (or the `NNNN-*` folder whose `metadata.json` has `"status": "active"`), read `spec.md`, then the latest `handoff.md`, then `specweave task next`.
53
53
  <!-- /SECTION -->
54
54
 
55
55
  <!-- SECTION:conventions required -->
@@ -1,7 +1,7 @@
1
1
  <!-- SECTION:header required -->
2
2
  # {PROJECT_NAME}
3
3
 
4
- SpecWeave project. Work happens in increments under `.specweave/increments/NNNN-slug/`. `spec.md` (Problem, ACs, Approach) is the source of truth; the ledger records who did what. Keep this file under one page; project-specific notes go in **Project notes** at the bottom.
4
+ SpecWeave project. Small requests live in the intent board; scoped work lives in increments under `.specweave/increments/NNNN-slug/`. `spec.md` (Problem, ACs, Approach) is the source of truth; the ledger records who did what. Keep this file under one page; project-specific notes go in **Project notes** at the bottom.
5
5
  <!-- /SECTION -->
6
6
 
7
7
  <!-- SECTION:structure -->
@@ -9,6 +9,7 @@ SpecWeave project. Work happens in increments under `.specweave/increments/NNNN-
9
9
 
10
10
  ```
11
11
  .specweave/
12
+ intents/board.jsonl append-only intent history (latest revision per id; planning state, not verification)
12
13
  increments/NNNN-slug/ spec.md (Problem · ACs · Approach) · tasks.md (tasks + rendered board) · ledger.jsonl (claims/done, CLI-written) · handoff.md · reports/ (evidence; binaries in reports/artifacts/, gitignored)
13
14
  docs/ ADRs and hand-written docs (read before changing architecture)
14
15
  config.json
@@ -23,14 +24,14 @@ Only those files (plus optional `plan.md` when Approach outgrows a page, and `sc
23
24
 
24
25
  | Step | Command |
25
26
  |---|---|
26
- | Plan a feature (spec.md with ACs + Approach, in plan mode; approved before any code) | `/sw:increment "title"` |
27
+ | Plan a feature (spec.md with ACs + Approach; resolve material scope questions) | `/sw:increment "title"` |
27
28
  | Work the tasks (claim → implement → commit → done with evidence) | `/sw:do` (loops `specweave task next` / `claim` / `done --run`) |
28
29
  | Verify the whole increment | `specweave verify` |
29
30
  | Review before closing (recommended for anything that ships: fresh context, findings cite path:line and are re-verified) | `/sw:review` |
30
31
  | Close (needs a green verify or `--reason`) | `/sw:done` |
31
32
  | Stop for any reason (context, tokens, switching tools) | `/sw:handoff` |
32
33
 
33
- Start every feature with the increment, even a small one, unless the user says "no increment". Fix a bug by writing the failing test first, then fixing the code without touching the test.
34
+ Use an increment for work that needs shared scope, acceptance criteria, or a handoff. Small self-contained fixes can remain a lightweight intent. For bugs, reproduce the failure and add a regression test when it protects behavior. User authorization carries through routine implementation and verification.
34
35
  <!-- /SECTION -->
35
36
 
36
37
  <!-- SECTION:verify required -->
@@ -47,8 +48,7 @@ Run the project's build/test/lint (see **Commands**) before reporting any task c
47
48
  3. Never edit ledger lines or another task's status; append only. On a git conflict in `ledger.jsonl` keep every line from both sides.
48
49
  4. `done` needs the task's **Test** command exit 0 and a commit sha. A task that turns out unnecessary is closed with `specweave task skip T-NN --reason "..."`, never ticked.
49
50
  5. When you stop: `specweave task release --all-mine` then `/sw:handoff`.
50
-
51
- Resuming: find the active increment with `specweave status` (or the `NNNN-*` folder whose `metadata.json` has `"status": "active"`), read `spec.md`, then the latest `handoff.md`, then `/sw:do`.
51
+ Resuming: check `.specweave/intents/board.jsonl` (latest revision per id) or `specweave dashboard` for unfinished intents, including work without an increment. Then find the active increment with `specweave status` (or the `NNNN-*` folder whose `metadata.json` has `"status": "active"`), read `spec.md`, then the latest `handoff.md`, then `/sw:do`.
52
52
  <!-- /SECTION -->
53
53
 
54
54
  <!-- SECTION:conventions required -->