agileflow 2.96.0 → 2.96.2

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/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.96.2] - 2026-02-06
11
+
12
+ ### Fixed
13
+ - Smart docs folder detection for existing AgileFlow installations
14
+
15
+ ## [2.96.1] - 2026-02-06
16
+
17
+ ### Fixed
18
+ - Fix js-yaml module resolution in copied lib files
19
+
10
20
  ## [2.96.0] - 2026-02-05
11
21
 
12
22
  ### Added
@@ -38,28 +38,27 @@ function createClaudeBridge(options = {}) {
38
38
 
39
39
  return new Promise((resolve, reject) => {
40
40
  // Spawn claude with streaming JSON output
41
- claudeProcess = spawn('claude', [
42
- '--print',
43
- '--output-format', 'stream-json',
44
- '--permission-mode', 'default',
45
- content
46
- ], {
47
- cwd,
48
- env: { ...process.env },
49
- stdio: ['ignore', 'pipe', 'pipe']
50
- });
41
+ claudeProcess = spawn(
42
+ 'claude',
43
+ ['--print', '--output-format', 'stream-json', '--permission-mode', 'default', content],
44
+ {
45
+ cwd,
46
+ env: { ...process.env },
47
+ stdio: ['ignore', 'pipe', 'pipe'],
48
+ }
49
+ );
51
50
 
52
51
  // Parse NDJSON output line by line
53
52
  const rl = readline.createInterface({
54
53
  input: claudeProcess.stdout,
55
- crlfDelay: Infinity
54
+ crlfDelay: Infinity,
56
55
  });
57
56
 
58
57
  let fullResponse = '';
59
58
  let toolUseBuffer = new Map();
60
59
  let hadAssistantText = false;
61
60
 
62
- rl.on('line', (line) => {
61
+ rl.on('line', line => {
63
62
  try {
64
63
  const event = JSON.parse(line);
65
64
  const result = processEvent(event, {
@@ -68,7 +67,7 @@ function createClaudeBridge(options = {}) {
68
67
  onToolResult,
69
68
  onInit,
70
69
  toolUseBuffer,
71
- hadAssistantText
70
+ hadAssistantText,
72
71
  });
73
72
 
74
73
  // Track if we've sent assistant text
@@ -93,12 +92,12 @@ function createClaudeBridge(options = {}) {
93
92
  }
94
93
  });
95
94
 
96
- claudeProcess.stderr.on('data', (data) => {
95
+ claudeProcess.stderr.on('data', data => {
97
96
  const errorText = data.toString();
98
97
  if (onError) onError(errorText);
99
98
  });
100
99
 
101
- claudeProcess.on('close', (code) => {
100
+ claudeProcess.on('close', code => {
102
101
  isRunning = false;
103
102
  claudeProcess = null;
104
103
 
@@ -112,7 +111,7 @@ function createClaudeBridge(options = {}) {
112
111
  }
113
112
  });
114
113
 
115
- claudeProcess.on('error', (err) => {
114
+ claudeProcess.on('error', err => {
116
115
  isRunning = false;
117
116
  claudeProcess = null;
118
117
  if (onError) onError(err.message);
@@ -142,7 +141,7 @@ function createClaudeBridge(options = {}) {
142
141
  return {
143
142
  sendMessage,
144
143
  cancel,
145
- isBusy
144
+ isBusy,
146
145
  };
147
146
  }
148
147
 
@@ -187,12 +186,7 @@ function processEvent(event, handlers) {
187
186
  for (const block of event.message.content) {
188
187
  if (block.type === 'tool_result' && onToolResult) {
189
188
  const toolUse = toolUseBuffer.get(block.tool_use_id);
190
- onToolResult(
191
- block.tool_use_id,
192
- block.content,
193
- block.is_error,
194
- toolUse?.name
195
- );
189
+ onToolResult(block.tool_use_id, block.content, block.is_error, toolUse?.name);
196
190
  }
197
191
  }
198
192
  }
@@ -217,5 +211,5 @@ function processEvent(event, handlers) {
217
211
  }
218
212
 
219
213
  module.exports = {
220
- createClaudeBridge
214
+ createClaudeBridge,
221
215
  };
@@ -21,65 +21,65 @@
21
21
  */
22
22
  const OutboundMessageType = {
23
23
  // Connection & Session
24
- SESSION_STATE: 'session_state', // Session connected/resumed
25
- SESSION_ERROR: 'session_error', // Session error
24
+ SESSION_STATE: 'session_state', // Session connected/resumed
25
+ SESSION_ERROR: 'session_error', // Session error
26
26
 
27
27
  // Text Streaming
28
- TEXT: 'text', // Claude text response
29
- TEXT_DELTA: 'text_delta', // Streaming text chunk
28
+ TEXT: 'text', // Claude text response
29
+ TEXT_DELTA: 'text_delta', // Streaming text chunk
30
30
 
31
31
  // Tool Calls
32
- TOOL_START: 'tool_start', // Tool call started
33
- TOOL_RESULT: 'tool_result', // Tool call completed
32
+ TOOL_START: 'tool_start', // Tool call started
33
+ TOOL_RESULT: 'tool_result', // Tool call completed
34
34
 
35
35
  // File Operations
36
- FILE_READ: 'file_read', // File was read
37
- FILE_WRITE: 'file_write', // File was written
38
- FILE_EDIT: 'file_edit', // File was edited (diff)
36
+ FILE_READ: 'file_read', // File was read
37
+ FILE_WRITE: 'file_write', // File was written
38
+ FILE_EDIT: 'file_edit', // File was edited (diff)
39
39
 
40
40
  // Shell Operations
41
- BASH_START: 'bash_start', // Bash command started
42
- BASH_OUTPUT: 'bash_output', // Bash output chunk
43
- BASH_END: 'bash_end', // Bash command completed
41
+ BASH_START: 'bash_start', // Bash command started
42
+ BASH_OUTPUT: 'bash_output', // Bash output chunk
43
+ BASH_END: 'bash_end', // Bash command completed
44
44
 
45
45
  // Task Management
46
- TASK_CREATED: 'task_created', // Task was created
47
- TASK_UPDATED: 'task_updated', // Task status changed
48
- TASK_LIST: 'task_list', // Full task list
46
+ TASK_CREATED: 'task_created', // Task was created
47
+ TASK_UPDATED: 'task_updated', // Task status changed
48
+ TASK_LIST: 'task_list', // Full task list
49
49
 
50
50
  // Git Status
51
- GIT_STATUS: 'git_status', // Git status update
52
- GIT_DIFF: 'git_diff', // Git diff content
51
+ GIT_STATUS: 'git_status', // Git status update
52
+ GIT_DIFF: 'git_diff', // Git diff content
53
53
 
54
54
  // Project Status
55
- STATUS_UPDATE: 'status_update', // Story/epic status update
55
+ STATUS_UPDATE: 'status_update', // Story/epic status update
56
56
 
57
57
  // Agent Communication
58
- AGENT_SPAWN: 'agent_spawn', // Sub-agent spawned
59
- AGENT_RESULT: 'agent_result', // Sub-agent completed
58
+ AGENT_SPAWN: 'agent_spawn', // Sub-agent spawned
59
+ AGENT_RESULT: 'agent_result', // Sub-agent completed
60
60
 
61
61
  // Notifications
62
- NOTIFICATION: 'notification', // General notification
62
+ NOTIFICATION: 'notification', // General notification
63
63
 
64
64
  // Terminal
65
- TERMINAL_OUTPUT: 'terminal_output', // Terminal output data
66
- TERMINAL_RESIZE: 'terminal_resize', // Terminal resize acknowledgment
67
- TERMINAL_EXIT: 'terminal_exit', // Terminal process exited
65
+ TERMINAL_OUTPUT: 'terminal_output', // Terminal output data
66
+ TERMINAL_RESIZE: 'terminal_resize', // Terminal resize acknowledgment
67
+ TERMINAL_EXIT: 'terminal_exit', // Terminal process exited
68
68
 
69
69
  // Automations
70
- AUTOMATION_LIST: 'automation_list', // List of all automations
70
+ AUTOMATION_LIST: 'automation_list', // List of all automations
71
71
  AUTOMATION_STATUS: 'automation_status', // Automation run status update
72
72
  AUTOMATION_RESULT: 'automation_result', // Automation run completed
73
73
 
74
74
  // Inbox
75
- INBOX_LIST: 'inbox_list', // List of inbox items
76
- INBOX_ITEM: 'inbox_item', // Single inbox item
75
+ INBOX_LIST: 'inbox_list', // List of inbox items
76
+ INBOX_ITEM: 'inbox_item', // Single inbox item
77
77
 
78
78
  // User Interaction
79
79
  ASK_USER_QUESTION: 'ask_user_question', // Claude is asking user a question
80
80
 
81
81
  // Errors
82
- ERROR: 'error', // General error
82
+ ERROR: 'error', // General error
83
83
  };
84
84
 
85
85
  /**
@@ -88,43 +88,43 @@ const OutboundMessageType = {
88
88
  */
89
89
  const InboundMessageType = {
90
90
  // Messages
91
- MESSAGE: 'message', // User message to Claude
92
- CANCEL: 'cancel', // Cancel current operation
91
+ MESSAGE: 'message', // User message to Claude
92
+ CANCEL: 'cancel', // Cancel current operation
93
93
 
94
94
  // Session
95
- SESSION_INIT: 'session_init', // Initialize/resume session
96
- SESSION_CLOSE: 'session_close', // Close session
95
+ SESSION_INIT: 'session_init', // Initialize/resume session
96
+ SESSION_CLOSE: 'session_close', // Close session
97
97
 
98
98
  // Requests
99
- REFRESH: 'refresh', // Request status refresh
99
+ REFRESH: 'refresh', // Request status refresh
100
100
 
101
101
  // Git Operations
102
- GIT_STAGE: 'git_stage', // Stage file(s)
103
- GIT_UNSTAGE: 'git_unstage', // Unstage file(s)
104
- GIT_REVERT: 'git_revert', // Revert file(s)
105
- GIT_COMMIT: 'git_commit', // Create commit
106
- GIT_PUSH: 'git_push', // Push to remote
107
- GIT_PR: 'git_pr', // Create pull request
102
+ GIT_STAGE: 'git_stage', // Stage file(s)
103
+ GIT_UNSTAGE: 'git_unstage', // Unstage file(s)
104
+ GIT_REVERT: 'git_revert', // Revert file(s)
105
+ GIT_COMMIT: 'git_commit', // Create commit
106
+ GIT_PUSH: 'git_push', // Push to remote
107
+ GIT_PR: 'git_pr', // Create pull request
108
108
  GIT_DIFF_REQUEST: 'git_diff_request', // Request diff for a file
109
109
 
110
110
  // Feedback
111
- INLINE_COMMENT: 'inline_comment', // Comment on diff line
111
+ INLINE_COMMENT: 'inline_comment', // Comment on diff line
112
112
 
113
113
  // Terminal
114
- TERMINAL_INPUT: 'terminal_input', // Terminal stdin
115
- TERMINAL_RESIZE: 'terminal_resize', // Resize terminal
116
- TERMINAL_SPAWN: 'terminal_spawn', // Spawn new terminal
117
- TERMINAL_CLOSE: 'terminal_close', // Close terminal
114
+ TERMINAL_INPUT: 'terminal_input', // Terminal stdin
115
+ TERMINAL_RESIZE: 'terminal_resize', // Resize terminal
116
+ TERMINAL_SPAWN: 'terminal_spawn', // Spawn new terminal
117
+ TERMINAL_CLOSE: 'terminal_close', // Close terminal
118
118
 
119
119
  // Automation
120
- AUTOMATION_RUN: 'automation_run', // Run automation
121
- AUTOMATION_STOP: 'automation_stop', // Stop automation
120
+ AUTOMATION_RUN: 'automation_run', // Run automation
121
+ AUTOMATION_STOP: 'automation_stop', // Stop automation
122
122
  AUTOMATION_LIST_REQUEST: 'automation_list_request', // Request automation list
123
123
  INBOX_LIST_REQUEST: 'inbox_list_request', // Request inbox list
124
- INBOX_ACTION: 'inbox_action', // Accept/dismiss inbox item
124
+ INBOX_ACTION: 'inbox_action', // Accept/dismiss inbox item
125
125
 
126
126
  // User Interaction Response
127
- USER_ANSWER: 'user_answer', // User's answer to AskUserQuestion
127
+ USER_ANSWER: 'user_answer', // User's answer to AskUserQuestion
128
128
  };
129
129
 
130
130
  // ============================================================================
@@ -14,7 +14,7 @@ import {
14
14
  CLICommand,
15
15
  IREventHandler,
16
16
  CLAUDE_CAPABILITIES,
17
- } from "../protocol/driver";
17
+ } from '../protocol/driver';
18
18
  import {
19
19
  IREnvelope,
20
20
  IRSource,
@@ -27,31 +27,31 @@ import {
27
27
  IRTask,
28
28
  IRGit,
29
29
  IRError,
30
- } from "../protocol/ir";
30
+ } from '../protocol/ir';
31
31
 
32
32
  // ============================================================================
33
33
  // Tool Name Mapping (Claude -> IR normalized names)
34
34
  // ============================================================================
35
35
 
36
36
  const CLAUDE_TOOL_MAPPING: Record<string, string> = {
37
- "Read": "file_read",
38
- "Write": "file_write",
39
- "Edit": "file_edit",
40
- "Bash": "shell_exec",
41
- "Glob": "file_glob",
42
- "Grep": "file_grep",
43
- "WebSearch": "web_search",
44
- "WebFetch": "web_fetch",
45
- "Task": "agent_spawn",
46
- "TaskCreate": "todo_create",
47
- "TaskUpdate": "todo_update",
48
- "TaskList": "todo_list",
49
- "TaskGet": "todo_get",
50
- "AskUserQuestion": "user_question",
51
- "EnterPlanMode": "plan_mode_enter",
52
- "ExitPlanMode": "plan_mode_exit",
53
- "Skill": "skill_invoke",
54
- "NotebookEdit": "notebook_edit",
37
+ Read: 'file_read',
38
+ Write: 'file_write',
39
+ Edit: 'file_edit',
40
+ Bash: 'shell_exec',
41
+ Glob: 'file_glob',
42
+ Grep: 'file_grep',
43
+ WebSearch: 'web_search',
44
+ WebFetch: 'web_fetch',
45
+ Task: 'agent_spawn',
46
+ TaskCreate: 'todo_create',
47
+ TaskUpdate: 'todo_update',
48
+ TaskList: 'todo_list',
49
+ TaskGet: 'todo_get',
50
+ AskUserQuestion: 'user_question',
51
+ EnterPlanMode: 'plan_mode_enter',
52
+ ExitPlanMode: 'plan_mode_exit',
53
+ Skill: 'skill_invoke',
54
+ NotebookEdit: 'notebook_edit',
55
55
  };
56
56
 
57
57
  /**
@@ -66,12 +66,12 @@ function normalizeToolName(claudeName: string): string {
66
66
  // ============================================================================
67
67
 
68
68
  export class ClaudeDriver implements Driver {
69
- readonly id: IRSource = "claude";
70
- readonly name = "Claude Code";
69
+ readonly id: IRSource = 'claude';
70
+ readonly name = 'Claude Code';
71
71
 
72
72
  private _status: DriverStatus = {
73
- state: "stopped",
74
- provider: "claude",
73
+ state: 'stopped',
74
+ provider: 'claude',
75
75
  };
76
76
 
77
77
  private _capabilities: Capability[] = [...CLAUDE_CAPABILITIES];
@@ -94,21 +94,21 @@ export class ClaudeDriver implements Driver {
94
94
  this._sessions.set(sessionId, { config, seqCounter: 0 });
95
95
 
96
96
  this._status = {
97
- state: "ready",
98
- provider: "claude",
99
- model: config.model || "claude-3-opus",
97
+ state: 'ready',
98
+ provider: 'claude',
99
+ model: config.model || 'claude-3-opus',
100
100
  contextMax: config.maxTokens || 200000,
101
101
  };
102
102
 
103
103
  // Emit init event
104
104
  const initPayload: IRInit = {
105
- provider: "claude",
106
- version: "1.0.0", // TODO: Get actual version from CLI
105
+ provider: 'claude',
106
+ version: '1.0.0', // TODO: Get actual version from CLI
107
107
  capabilities: this._capabilities.filter(c => c.available).map(c => c.name),
108
108
  maxContext: config.maxTokens || 200000,
109
109
  };
110
110
 
111
- this._emit(createIREnvelope("init", sessionId, "claude", initPayload));
111
+ this._emit(createIREnvelope('init', sessionId, 'claude', initPayload));
112
112
  }
113
113
 
114
114
  async stop(sessionId: string): Promise<void> {
@@ -117,7 +117,7 @@ export class ClaudeDriver implements Driver {
117
117
  if (this._sessions.size === 0) {
118
118
  this._status = {
119
119
  ...this._status,
120
- state: "stopped",
120
+ state: 'stopped',
121
121
  };
122
122
  }
123
123
  }
@@ -147,14 +147,14 @@ export class ClaudeDriver implements Driver {
147
147
 
148
148
  async send(sessionId: string, command: CLICommand): Promise<void> {
149
149
  // Mark as busy
150
- this._status = { ...this._status, state: "busy" };
150
+ this._status = { ...this._status, state: 'busy' };
151
151
 
152
152
  // This would normally send to the CLI process
153
153
  // For now, just emit a session state change
154
154
  const sessionPayload: IRSession = {
155
- state: "thinking",
155
+ state: 'thinking',
156
156
  };
157
- this._emit(createIREnvelope("session", sessionId, "claude", sessionPayload));
157
+ this._emit(createIREnvelope('session', sessionId, 'claude', sessionPayload));
158
158
  }
159
159
 
160
160
  // -------------------------------------------------------------------------
@@ -170,58 +170,60 @@ export class ClaudeDriver implements Driver {
170
170
  if (!session) return null;
171
171
 
172
172
  switch (claudeMessage.type) {
173
- case "text":
174
- return createIREnvelope<IRTextDelta>("text_delta", sessionId, "claude", {
173
+ case 'text':
174
+ return createIREnvelope<IRTextDelta>('text_delta', sessionId, 'claude', {
175
175
  text: claudeMessage.content,
176
176
  done: claudeMessage.done ?? false,
177
177
  });
178
178
 
179
- case "tool_use":
180
- return createIREnvelope<IRToolStart>("tool_start", sessionId, "claude", {
179
+ case 'tool_use':
180
+ return createIREnvelope<IRToolStart>('tool_start', sessionId, 'claude', {
181
181
  id: claudeMessage.id || `tool_${Date.now()}`,
182
182
  name: normalizeToolName(claudeMessage.tool),
183
183
  nativeName: claudeMessage.tool,
184
184
  input: claudeMessage.input || {},
185
185
  });
186
186
 
187
- case "tool_result":
188
- return createIREnvelope<IRToolResult>("tool_result", sessionId, "claude", {
189
- id: claudeMessage.id || "",
187
+ case 'tool_result':
188
+ return createIREnvelope<IRToolResult>('tool_result', sessionId, 'claude', {
189
+ id: claudeMessage.id || '',
190
190
  ok: !claudeMessage.error,
191
191
  output: claudeMessage.content,
192
192
  error: claudeMessage.error,
193
193
  });
194
194
 
195
- case "task":
196
- return createIREnvelope<IRTask>("task", sessionId, "claude", {
197
- action: claudeMessage.action as "create" | "update" | "delete" | "list",
198
- task: claudeMessage.task ? {
199
- ...claudeMessage.task,
200
- status: claudeMessage.task.status as "pending" | "in_progress" | "completed",
201
- } : undefined,
195
+ case 'task':
196
+ return createIREnvelope<IRTask>('task', sessionId, 'claude', {
197
+ action: claudeMessage.action as 'create' | 'update' | 'delete' | 'list',
198
+ task: claudeMessage.task
199
+ ? {
200
+ ...claudeMessage.task,
201
+ status: claudeMessage.task.status as 'pending' | 'in_progress' | 'completed',
202
+ }
203
+ : undefined,
202
204
  tasks: claudeMessage.tasks?.map((t: { id: string; subject: string; status: string }) => ({
203
205
  ...t,
204
- status: t.status as "pending" | "in_progress" | "completed",
206
+ status: t.status as 'pending' | 'in_progress' | 'completed',
205
207
  })),
206
208
  });
207
209
 
208
- case "git_status":
209
- return createIREnvelope<IRGit>("git", sessionId, "claude", {
210
- action: "status",
210
+ case 'git_status':
211
+ return createIREnvelope<IRGit>('git', sessionId, 'claude', {
212
+ action: 'status',
211
213
  branch: claudeMessage.branch,
212
214
  staged: claudeMessage.staged,
213
215
  unstaged: claudeMessage.unstaged,
214
216
  });
215
217
 
216
- case "session_state":
217
- return createIREnvelope<IRSession>("session", sessionId, "claude", {
218
- state: claudeMessage.state as "connected" | "thinking" | "idle" | "error",
218
+ case 'session_state':
219
+ return createIREnvelope<IRSession>('session', sessionId, 'claude', {
220
+ state: claudeMessage.state as 'connected' | 'thinking' | 'idle' | 'error',
219
221
  message: claudeMessage.message,
220
222
  });
221
223
 
222
- case "error":
223
- return createIREnvelope<IRError>("error", sessionId, "claude", {
224
- code: claudeMessage.code || "UNKNOWN",
224
+ case 'error':
225
+ return createIREnvelope<IRError>('error', sessionId, 'claude', {
226
+ code: claudeMessage.code || 'UNKNOWN',
225
227
  message: claudeMessage.message,
226
228
  details: claudeMessage.details,
227
229
  recoverable: claudeMessage.recoverable ?? true,
@@ -253,11 +255,11 @@ export class ClaudeDriver implements Driver {
253
255
  }
254
256
 
255
257
  private _emit(envelope: IREnvelope): void {
256
- Array.from(this._eventHandlers).forEach((handler) => {
258
+ Array.from(this._eventHandlers).forEach(handler => {
257
259
  try {
258
260
  handler(envelope);
259
261
  } catch (error) {
260
- console.error("[ClaudeDriver] Event handler error:", error);
262
+ console.error('[ClaudeDriver] Event handler error:', error);
261
263
  }
262
264
  });
263
265
  }