@vibescope/mcp-server 0.2.8 → 0.3.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.
- package/CHANGELOG.md +84 -84
- package/README.md +194 -194
- package/dist/api-client.d.ts +41 -5
- package/dist/api-client.js +34 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +30 -38
- package/dist/handlers/discovery.js +2 -0
- package/dist/handlers/roles.js +1 -8
- package/dist/handlers/session.d.ts +11 -0
- package/dist/handlers/session.js +124 -32
- package/dist/handlers/tasks.d.ts +8 -0
- package/dist/handlers/tasks.js +163 -3
- package/dist/handlers/tool-docs.js +840 -828
- package/dist/handlers/validation.js +71 -15
- package/dist/index.js +73 -73
- package/dist/setup.js +6 -6
- package/dist/templates/agent-guidelines.js +185 -185
- package/dist/templates/help-content.d.ts +24 -0
- package/dist/templates/help-content.js +1728 -0
- package/dist/tools.js +132 -87
- package/dist/utils.d.ts +15 -11
- package/dist/utils.js +53 -28
- package/docs/TOOLS.md +2406 -2053
- package/package.json +1 -1
- package/scripts/generate-docs.ts +212 -212
- package/scripts/version-bump.ts +203 -203
- package/src/api-client.test.ts +723 -723
- package/src/api-client.ts +2561 -2499
- package/src/cli.test.ts +24 -8
- package/src/cli.ts +204 -212
- package/src/handlers/__test-setup__.ts +236 -236
- package/src/handlers/__test-utils__.ts +87 -87
- package/src/handlers/blockers.test.ts +468 -468
- package/src/handlers/blockers.ts +163 -163
- package/src/handlers/bodies-of-work.test.ts +704 -704
- package/src/handlers/bodies-of-work.ts +526 -526
- package/src/handlers/connectors.test.ts +834 -834
- package/src/handlers/connectors.ts +229 -229
- package/src/handlers/cost.test.ts +462 -462
- package/src/handlers/cost.ts +285 -285
- package/src/handlers/decisions.test.ts +382 -382
- package/src/handlers/decisions.ts +153 -153
- package/src/handlers/deployment.test.ts +551 -551
- package/src/handlers/deployment.ts +541 -541
- package/src/handlers/discovery.test.ts +206 -206
- package/src/handlers/discovery.ts +392 -390
- package/src/handlers/fallback.test.ts +537 -537
- package/src/handlers/fallback.ts +194 -194
- package/src/handlers/file-checkouts.test.ts +750 -750
- package/src/handlers/file-checkouts.ts +185 -185
- package/src/handlers/findings.test.ts +633 -633
- package/src/handlers/findings.ts +239 -239
- package/src/handlers/git-issues.test.ts +631 -631
- package/src/handlers/git-issues.ts +136 -136
- package/src/handlers/ideas.test.ts +644 -644
- package/src/handlers/ideas.ts +207 -207
- package/src/handlers/index.ts +84 -84
- package/src/handlers/milestones.test.ts +475 -475
- package/src/handlers/milestones.ts +180 -180
- package/src/handlers/organizations.test.ts +826 -826
- package/src/handlers/organizations.ts +315 -315
- package/src/handlers/progress.test.ts +269 -269
- package/src/handlers/progress.ts +77 -77
- package/src/handlers/project.test.ts +546 -546
- package/src/handlers/project.ts +239 -239
- package/src/handlers/requests.test.ts +303 -303
- package/src/handlers/requests.ts +99 -99
- package/src/handlers/roles.test.ts +305 -303
- package/src/handlers/roles.ts +219 -226
- package/src/handlers/session.test.ts +998 -875
- package/src/handlers/session.ts +839 -738
- package/src/handlers/sprints.test.ts +732 -732
- package/src/handlers/sprints.ts +537 -537
- package/src/handlers/tasks.test.ts +931 -907
- package/src/handlers/tasks.ts +1121 -945
- package/src/handlers/tool-categories.test.ts +66 -66
- package/src/handlers/tool-docs.ts +1109 -1096
- package/src/handlers/types.test.ts +259 -259
- package/src/handlers/types.ts +175 -175
- package/src/handlers/validation.test.ts +582 -582
- package/src/handlers/validation.ts +159 -97
- package/src/index.test.ts +674 -0
- package/src/index.ts +792 -792
- package/src/setup.test.ts +233 -233
- package/src/setup.ts +404 -403
- package/src/templates/agent-guidelines.ts +210 -210
- package/src/templates/help-content.ts +1751 -0
- package/src/token-tracking.test.ts +463 -463
- package/src/token-tracking.ts +166 -166
- package/src/tools.test.ts +416 -0
- package/src/tools.ts +3607 -3562
- package/src/utils.test.ts +785 -683
- package/src/utils.ts +469 -436
- package/src/validators.test.ts +223 -223
- package/src/validators.ts +249 -249
- package/tsconfig.json +16 -16
- package/vitest.config.ts +14 -14
package/dist/api-client.js
CHANGED
|
@@ -67,6 +67,11 @@ export class VibescopeApiClient {
|
|
|
67
67
|
session_id: sessionId
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
+
async signalIdle(sessionId) {
|
|
71
|
+
return this.request('POST', '/api/mcp/sessions/idle', {
|
|
72
|
+
session_id: sessionId
|
|
73
|
+
});
|
|
74
|
+
}
|
|
70
75
|
// Project endpoints
|
|
71
76
|
async listProjects() {
|
|
72
77
|
return this.request('GET', '/api/mcp/projects');
|
|
@@ -182,6 +187,35 @@ export class VibescopeApiClient {
|
|
|
182
187
|
async deleteTask(taskId) {
|
|
183
188
|
return this.request('DELETE', `/api/mcp/tasks/${taskId}`);
|
|
184
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Release a task back to pending status.
|
|
192
|
+
* Clears session assignment, git branch, and worktree info.
|
|
193
|
+
*/
|
|
194
|
+
async releaseTask(taskId, params) {
|
|
195
|
+
return this.proxy('release_task', {
|
|
196
|
+
task_id: taskId,
|
|
197
|
+
reason: params?.reason,
|
|
198
|
+
}, params?.session_id ? {
|
|
199
|
+
session_id: params.session_id,
|
|
200
|
+
persona: null,
|
|
201
|
+
instance_id: '',
|
|
202
|
+
} : undefined);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Cancel a task with an optional reason.
|
|
206
|
+
* Task remains visible with cancelled status for historical tracking.
|
|
207
|
+
*/
|
|
208
|
+
async cancelTask(taskId, params) {
|
|
209
|
+
return this.proxy('cancel_task', {
|
|
210
|
+
task_id: taskId,
|
|
211
|
+
cancelled_reason: params?.cancelled_reason,
|
|
212
|
+
cancellation_note: params?.cancellation_note,
|
|
213
|
+
}, params?.session_id ? {
|
|
214
|
+
session_id: params.session_id,
|
|
215
|
+
persona: null,
|
|
216
|
+
instance_id: '',
|
|
217
|
+
} : undefined);
|
|
218
|
+
}
|
|
185
219
|
// Progress endpoints
|
|
186
220
|
async logProgress(projectId, params) {
|
|
187
221
|
return this.request('POST', `/api/mcp/projects/${projectId}/progress`, params);
|
package/dist/cli.d.ts
CHANGED
|
@@ -27,6 +27,6 @@ export interface VerificationResult {
|
|
|
27
27
|
session_duration_minutes: number | null;
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
-
export
|
|
30
|
+
export { normalizeGitUrl } from './utils.js';
|
|
31
31
|
export declare function detectGitUrl(): string | null;
|
|
32
32
|
export declare function verify(gitUrl?: string, projectId?: string): Promise<VerificationResult>;
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { execSync } from 'child_process';
|
|
15
15
|
import { runSetup } from './setup.js';
|
|
16
|
+
import { normalizeGitUrl as normalizeGitUrlFn } from './utils.js';
|
|
16
17
|
// ============================================================================
|
|
17
18
|
// Configuration (read at runtime for testability)
|
|
18
19
|
// ============================================================================
|
|
@@ -25,17 +26,8 @@ function getApiUrl() {
|
|
|
25
26
|
// ============================================================================
|
|
26
27
|
// Git URL Detection
|
|
27
28
|
// ============================================================================
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
let normalized = url.replace(/\.git$/, '');
|
|
31
|
-
// Convert SSH to HTTPS format
|
|
32
|
-
if (normalized.startsWith('git@')) {
|
|
33
|
-
normalized = normalized
|
|
34
|
-
.replace(/^git@/, 'https://')
|
|
35
|
-
.replace(/:([^/])/, '/$1');
|
|
36
|
-
}
|
|
37
|
-
return normalized;
|
|
38
|
-
}
|
|
29
|
+
// Re-export normalizeGitUrl from utils for backwards compatibility with tests
|
|
30
|
+
export { normalizeGitUrl } from './utils.js';
|
|
39
31
|
export function detectGitUrl() {
|
|
40
32
|
try {
|
|
41
33
|
const url = execSync('git config --get remote.origin.url', {
|
|
@@ -43,7 +35,7 @@ export function detectGitUrl() {
|
|
|
43
35
|
timeout: 5000,
|
|
44
36
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
45
37
|
}).trim();
|
|
46
|
-
return
|
|
38
|
+
return normalizeGitUrlFn(url);
|
|
47
39
|
}
|
|
48
40
|
catch {
|
|
49
41
|
return null;
|
|
@@ -124,32 +116,32 @@ async function main() {
|
|
|
124
116
|
}
|
|
125
117
|
}
|
|
126
118
|
else if (command === 'help' || command === '--help' || command === '-h') {
|
|
127
|
-
console.log(`
|
|
128
|
-
Vibescope CLI - Setup wizard and enforcement verification tool
|
|
129
|
-
|
|
130
|
-
Usage:
|
|
131
|
-
vibescope-cli setup Interactive setup wizard for your IDE
|
|
132
|
-
vibescope-cli verify [options] Check Vibescope compliance before exit
|
|
133
|
-
|
|
134
|
-
Setup:
|
|
135
|
-
Configures Vibescope MCP integration for:
|
|
136
|
-
- Claude Code (CLI)
|
|
137
|
-
- Claude Desktop
|
|
138
|
-
- Cursor
|
|
139
|
-
- Gemini CLI
|
|
140
|
-
|
|
141
|
-
Verify Options:
|
|
142
|
-
--git-url <url> Git repository URL (auto-detected if not provided)
|
|
143
|
-
--project-id <id> Vibescope project UUID
|
|
144
|
-
|
|
145
|
-
Exit Codes (verify):
|
|
146
|
-
0 Compliant - agent can exit
|
|
147
|
-
1 Non-compliant - agent should continue work
|
|
148
|
-
2 Error - allow exit with warning
|
|
149
|
-
|
|
150
|
-
Environment Variables:
|
|
151
|
-
VIBESCOPE_API_KEY Required for verify - Your Vibescope API key
|
|
152
|
-
VIBESCOPE_API_URL Optional - API URL (default: https://vibescope.dev)
|
|
119
|
+
console.log(`
|
|
120
|
+
Vibescope CLI - Setup wizard and enforcement verification tool
|
|
121
|
+
|
|
122
|
+
Usage:
|
|
123
|
+
vibescope-cli setup Interactive setup wizard for your IDE
|
|
124
|
+
vibescope-cli verify [options] Check Vibescope compliance before exit
|
|
125
|
+
|
|
126
|
+
Setup:
|
|
127
|
+
Configures Vibescope MCP integration for:
|
|
128
|
+
- Claude Code (CLI)
|
|
129
|
+
- Claude Desktop
|
|
130
|
+
- Cursor
|
|
131
|
+
- Gemini CLI
|
|
132
|
+
|
|
133
|
+
Verify Options:
|
|
134
|
+
--git-url <url> Git repository URL (auto-detected if not provided)
|
|
135
|
+
--project-id <id> Vibescope project UUID
|
|
136
|
+
|
|
137
|
+
Exit Codes (verify):
|
|
138
|
+
0 Compliant - agent can exit
|
|
139
|
+
1 Non-compliant - agent should continue work
|
|
140
|
+
2 Error - allow exit with warning
|
|
141
|
+
|
|
142
|
+
Environment Variables:
|
|
143
|
+
VIBESCOPE_API_KEY Required for verify - Your Vibescope API key
|
|
144
|
+
VIBESCOPE_API_URL Optional - API URL (default: https://vibescope.dev)
|
|
153
145
|
`);
|
|
154
146
|
process.exit(0);
|
|
155
147
|
}
|
|
@@ -40,6 +40,7 @@ export const TOOL_CATEGORIES = {
|
|
|
40
40
|
{ name: 'get_token_usage', brief: 'View token stats' },
|
|
41
41
|
{ name: 'report_token_usage', brief: 'Report actual Claude API usage' },
|
|
42
42
|
{ name: 'heartbeat', brief: 'Maintain active status' },
|
|
43
|
+
{ name: 'signal_idle', brief: 'Signal agent is idle' },
|
|
43
44
|
{ name: 'end_work_session', brief: 'End session, release tasks' },
|
|
44
45
|
{ name: 'confirm_agent_setup', brief: 'Mark agent setup as complete' },
|
|
45
46
|
],
|
|
@@ -69,6 +70,7 @@ export const TOOL_CATEGORIES = {
|
|
|
69
70
|
{ name: 'complete_task', brief: 'Mark task done' },
|
|
70
71
|
{ name: 'delete_task', brief: 'Remove a task' },
|
|
71
72
|
{ name: 'cancel_task', brief: 'Cancel task with reason' },
|
|
73
|
+
{ name: 'release_task', brief: 'Unclaim task to pending' },
|
|
72
74
|
{ name: 'batch_update_tasks', brief: 'Update multiple tasks' },
|
|
73
75
|
{ name: 'batch_complete_tasks', brief: 'Complete multiple tasks' },
|
|
74
76
|
{ name: 'add_task_reference', brief: 'Add URL to task' },
|
package/dist/handlers/roles.js
CHANGED
|
@@ -63,14 +63,7 @@ export const setSessionRole = async (args, ctx) => {
|
|
|
63
63
|
result: { error: 'role is required' },
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
if (!validRoles.includes(role)) {
|
|
68
|
-
return {
|
|
69
|
-
result: {
|
|
70
|
-
error: `Invalid role: ${role}. Must be one of: ${validRoles.join(', ')}`,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
66
|
+
// Role is now open-ended - any role name accepted
|
|
74
67
|
// Update local session state
|
|
75
68
|
updateSession({ currentRole: role });
|
|
76
69
|
// If there's an active session, update it on the server too
|
|
@@ -26,6 +26,17 @@ export declare const reportTokenUsage: Handler;
|
|
|
26
26
|
* This marks the agent type as onboarded, so future sessions won't receive setup instructions.
|
|
27
27
|
*/
|
|
28
28
|
export declare const confirmAgentSetup: Handler;
|
|
29
|
+
/**
|
|
30
|
+
* Signal that the agent is idle (no more tasks to work on).
|
|
31
|
+
* This immediately updates the session status to 'idle', providing real-time
|
|
32
|
+
* visibility on the dashboard instead of waiting for heartbeat timeout.
|
|
33
|
+
*
|
|
34
|
+
* Call this when:
|
|
35
|
+
* - complete_task returns no next_task
|
|
36
|
+
* - get_next_task returns no tasks
|
|
37
|
+
* - There's genuinely no work to do
|
|
38
|
+
*/
|
|
39
|
+
export declare const signalIdle: Handler;
|
|
29
40
|
/**
|
|
30
41
|
* Session handlers registry
|
|
31
42
|
*/
|
package/dist/handlers/session.js
CHANGED
|
@@ -12,21 +12,20 @@ import os from 'os';
|
|
|
12
12
|
import { parseArgs, createEnumValidator } from '../validators.js';
|
|
13
13
|
import { getApiClient } from '../api-client.js';
|
|
14
14
|
import { getAgentGuidelinesTemplate, getAgentGuidelinesSummary } from '../templates/agent-guidelines.js';
|
|
15
|
+
import { getFallbackHelpContent, getAvailableHelpTopics } from '../templates/help-content.js';
|
|
16
|
+
import { normalizeGitUrl } from '../utils.js';
|
|
15
17
|
// Auto-detect machine hostname for worktree tracking
|
|
16
18
|
const MACHINE_HOSTNAME = os.hostname();
|
|
17
19
|
const VALID_MODES = ['lite', 'full'];
|
|
18
|
-
const VALID_MODELS = ['opus', 'sonnet', 'haiku'];
|
|
19
|
-
const VALID_ROLES = ['developer', 'validator', 'deployer', 'reviewer', 'maintainer'];
|
|
20
|
-
const VALID_AGENT_TYPES = ['claude', 'gemini', 'cursor', 'windsurf', 'other'];
|
|
21
20
|
// Argument schemas for type-safe parsing
|
|
22
21
|
const startWorkSessionSchema = {
|
|
23
22
|
project_id: { type: 'string' },
|
|
24
23
|
git_url: { type: 'string' },
|
|
25
24
|
mode: { type: 'string', default: 'lite', validate: createEnumValidator(VALID_MODES) },
|
|
26
|
-
model: { type: 'string',
|
|
27
|
-
role: { type: 'string', default: 'developer',
|
|
25
|
+
model: { type: 'string' }, // Open-ended - any model name accepted
|
|
26
|
+
role: { type: 'string', default: 'developer' }, // Open-ended - any role name accepted
|
|
28
27
|
hostname: { type: 'string' }, // Machine hostname for worktree tracking
|
|
29
|
-
agent_type: { type: 'string'
|
|
28
|
+
agent_type: { type: 'string' }, // Open-ended - any agent type accepted
|
|
30
29
|
};
|
|
31
30
|
const heartbeatSchema = {
|
|
32
31
|
session_id: { type: 'string' },
|
|
@@ -43,19 +42,20 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
43
42
|
const { project_id, git_url, mode, model, role, hostname: providedHostname, agent_type } = parseArgs(args, startWorkSessionSchema);
|
|
44
43
|
// Use auto-detected hostname if not provided - enables machine-aware worktree filtering
|
|
45
44
|
const hostname = providedHostname || MACHINE_HOSTNAME;
|
|
45
|
+
// Normalize git_url and track if it was changed - helps agents understand URL matching
|
|
46
|
+
const normalizedGitUrl = git_url ? normalizeGitUrl(git_url) : null;
|
|
47
|
+
const gitUrlWasNormalized = git_url && normalizedGitUrl && git_url !== normalizedGitUrl;
|
|
46
48
|
const { session, updateSession } = ctx;
|
|
47
49
|
// Reset token tracking for new session with model info
|
|
50
|
+
// Model is now open-ended - use as-is (normalize Claude model names for consistency)
|
|
48
51
|
const normalizedModel = model ? model.toLowerCase().replace(/^claude[- ]*/i, '') : null;
|
|
49
|
-
const validModel = normalizedModel && VALID_MODELS.includes(normalizedModel)
|
|
50
|
-
? normalizedModel
|
|
51
|
-
: null;
|
|
52
52
|
updateSession({
|
|
53
53
|
tokenUsage: {
|
|
54
54
|
callCount: 0,
|
|
55
55
|
totalTokens: 0,
|
|
56
56
|
byTool: {},
|
|
57
57
|
byModel: {},
|
|
58
|
-
currentModel:
|
|
58
|
+
currentModel: normalizedModel,
|
|
59
59
|
},
|
|
60
60
|
});
|
|
61
61
|
// Require project_id or git_url
|
|
@@ -149,6 +149,19 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
149
149
|
result.persona = data.persona;
|
|
150
150
|
result.role = data.role;
|
|
151
151
|
result.project = data.project;
|
|
152
|
+
// Inform agent if git_url was normalized (helps explain URL matching behavior)
|
|
153
|
+
if (gitUrlWasNormalized) {
|
|
154
|
+
result.git_url_normalized = {
|
|
155
|
+
message: 'Your git URL was normalized for project lookup. All URL formats for the same repository resolve to the same project.',
|
|
156
|
+
original: git_url,
|
|
157
|
+
normalized: normalizedGitUrl,
|
|
158
|
+
examples: [
|
|
159
|
+
'git@github.com:owner/repo.git → https://github.com/owner/repo',
|
|
160
|
+
'https://GITHUB.COM/Owner/Repo/ → https://github.com/owner/repo',
|
|
161
|
+
'http://github.com/owner/repo.git → https://github.com/owner/repo',
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
152
165
|
// Add task data
|
|
153
166
|
if (data.next_task) {
|
|
154
167
|
result.next_task = data.next_task;
|
|
@@ -209,6 +222,31 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
209
222
|
command: `git worktree add ../<project>-<persona>-<task> -b feature/<task-id> ${baseBranch}`,
|
|
210
223
|
help: 'Run get_help("git") for full instructions',
|
|
211
224
|
};
|
|
225
|
+
// Add FIRST_TIME_CONNECTION guidance for git-flow
|
|
226
|
+
if (data.project.git_workflow === 'git-flow') {
|
|
227
|
+
result.FIRST_TIME_CONNECTION = {
|
|
228
|
+
workflow: 'git-flow',
|
|
229
|
+
steps: [
|
|
230
|
+
`1. git checkout ${data.project.git_develop_branch || 'develop'}`,
|
|
231
|
+
`2. git pull origin ${data.project.git_develop_branch || 'develop'}`,
|
|
232
|
+
'3. All feature branches must be created from develop',
|
|
233
|
+
],
|
|
234
|
+
warning: 'Working from main or stale branches causes merge conflicts.',
|
|
235
|
+
base_branch: data.project.git_develop_branch || 'develop',
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
else if (data.project.git_workflow === 'github-flow') {
|
|
239
|
+
result.FIRST_TIME_CONNECTION = {
|
|
240
|
+
workflow: 'github-flow',
|
|
241
|
+
steps: [
|
|
242
|
+
`1. git checkout ${data.project.git_main_branch || 'main'}`,
|
|
243
|
+
`2. git pull origin ${data.project.git_main_branch || 'main'}`,
|
|
244
|
+
'3. All feature branches must be created from main',
|
|
245
|
+
],
|
|
246
|
+
warning: 'Working from stale branches causes merge conflicts.',
|
|
247
|
+
base_branch: data.project.git_main_branch || 'main',
|
|
248
|
+
};
|
|
249
|
+
}
|
|
212
250
|
}
|
|
213
251
|
}
|
|
214
252
|
// Add agent setup instructions if this is a new agent type for the project
|
|
@@ -337,28 +375,23 @@ export const getHelp = async (args, _ctx) => {
|
|
|
337
375
|
const { topic } = parseArgs(args, getHelpSchema);
|
|
338
376
|
const apiClient = getApiClient();
|
|
339
377
|
const response = await apiClient.getHelpTopic(topic);
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return {
|
|
343
|
-
result: {
|
|
344
|
-
error: response.error || `Failed to fetch help topic: ${topic}`,
|
|
345
|
-
},
|
|
346
|
-
};
|
|
378
|
+
// Try database content first
|
|
379
|
+
if (response.ok && response.data?.content) {
|
|
380
|
+
return { result: { topic, content: response.data.content } };
|
|
347
381
|
}
|
|
348
|
-
if
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
? topicsResponse.data.map(t => t.slug)
|
|
353
|
-
: ['getting_started', 'tasks', 'validation', 'deployment', 'git', 'blockers', 'milestones', 'fallback', 'session', 'tokens', 'sprints', 'topics'];
|
|
354
|
-
return {
|
|
355
|
-
result: {
|
|
356
|
-
error: `Unknown topic: ${topic}`,
|
|
357
|
-
available,
|
|
358
|
-
},
|
|
359
|
-
};
|
|
382
|
+
// Fall back to local content if database is empty or unavailable
|
|
383
|
+
const fallback = getFallbackHelpContent(topic);
|
|
384
|
+
if (fallback) {
|
|
385
|
+
return { result: { topic, content: fallback.content } };
|
|
360
386
|
}
|
|
361
|
-
|
|
387
|
+
// Topic not found in either source - show available topics
|
|
388
|
+
const available = getAvailableHelpTopics();
|
|
389
|
+
return {
|
|
390
|
+
result: {
|
|
391
|
+
error: `Unknown topic: ${topic}`,
|
|
392
|
+
available,
|
|
393
|
+
},
|
|
394
|
+
};
|
|
362
395
|
};
|
|
363
396
|
const MODEL_PRICING = {
|
|
364
397
|
standard: {
|
|
@@ -479,11 +512,11 @@ export const getTokenUsage = async (_args, ctx) => {
|
|
|
479
512
|
const reportTokenUsageSchema = {
|
|
480
513
|
input_tokens: { type: 'number', required: true },
|
|
481
514
|
output_tokens: { type: 'number', required: true },
|
|
482
|
-
model: { type: 'string',
|
|
515
|
+
model: { type: 'string' }, // Open-ended - any model name accepted
|
|
483
516
|
};
|
|
484
517
|
const confirmAgentSetupSchema = {
|
|
485
518
|
project_id: { type: 'string', required: true },
|
|
486
|
-
agent_type: { type: 'string', required: true,
|
|
519
|
+
agent_type: { type: 'string', required: true }, // Open-ended - any agent type accepted
|
|
487
520
|
};
|
|
488
521
|
/**
|
|
489
522
|
* Report actual Claude API token usage for accurate cost tracking.
|
|
@@ -610,6 +643,64 @@ export const confirmAgentSetup = async (args, _ctx) => {
|
|
|
610
643
|
},
|
|
611
644
|
};
|
|
612
645
|
};
|
|
646
|
+
const signalIdleSchema = {
|
|
647
|
+
session_id: { type: 'string' },
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Signal that the agent is idle (no more tasks to work on).
|
|
651
|
+
* This immediately updates the session status to 'idle', providing real-time
|
|
652
|
+
* visibility on the dashboard instead of waiting for heartbeat timeout.
|
|
653
|
+
*
|
|
654
|
+
* Call this when:
|
|
655
|
+
* - complete_task returns no next_task
|
|
656
|
+
* - get_next_task returns no tasks
|
|
657
|
+
* - There's genuinely no work to do
|
|
658
|
+
*/
|
|
659
|
+
export const signalIdle = async (args, ctx) => {
|
|
660
|
+
const { session_id } = parseArgs(args, signalIdleSchema);
|
|
661
|
+
const { session } = ctx;
|
|
662
|
+
const targetSession = session_id || session.currentSessionId;
|
|
663
|
+
if (!targetSession) {
|
|
664
|
+
return {
|
|
665
|
+
result: {
|
|
666
|
+
error: 'No active session. Call start_work_session first.',
|
|
667
|
+
},
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
const apiClient = getApiClient();
|
|
671
|
+
const response = await apiClient.signalIdle(targetSession);
|
|
672
|
+
if (!response.ok) {
|
|
673
|
+
return {
|
|
674
|
+
result: {
|
|
675
|
+
error: response.error || 'Failed to signal idle',
|
|
676
|
+
},
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
return {
|
|
680
|
+
result: {
|
|
681
|
+
success: true,
|
|
682
|
+
session_id: targetSession,
|
|
683
|
+
status: 'idle',
|
|
684
|
+
message: 'Session marked as idle. Dashboard will show you as inactive until you start a new task.',
|
|
685
|
+
next_steps: [
|
|
686
|
+
'Wait for new tasks to be added by the user',
|
|
687
|
+
'Or call start_fallback_activity() to do background work',
|
|
688
|
+
'Or call end_work_session() if you are done for the session',
|
|
689
|
+
],
|
|
690
|
+
AUTONOMY_RULES: {
|
|
691
|
+
message: 'Agents must be autonomous. Follow these rules:',
|
|
692
|
+
rules: [
|
|
693
|
+
'Never ask "should I continue?" → Just continue',
|
|
694
|
+
'Never ask "should I clear context?" → Just clear it',
|
|
695
|
+
'Never say "let me know what to do" → Use get_next_task or fallback activities',
|
|
696
|
+
'When context grows large: /clear → start_work_session (don\'t ask, just do it)',
|
|
697
|
+
],
|
|
698
|
+
preferred_activities: ['code_review', 'security_review', 'test_coverage', 'documentation_review', 'dependency_audit'],
|
|
699
|
+
directive: 'BE PROACTIVE: Start a fallback activity now rather than waiting for user input.',
|
|
700
|
+
},
|
|
701
|
+
},
|
|
702
|
+
};
|
|
703
|
+
};
|
|
613
704
|
/**
|
|
614
705
|
* Session handlers registry
|
|
615
706
|
*/
|
|
@@ -617,6 +708,7 @@ export const sessionHandlers = {
|
|
|
617
708
|
start_work_session: startWorkSession,
|
|
618
709
|
heartbeat: heartbeat,
|
|
619
710
|
end_work_session: endWorkSession,
|
|
711
|
+
signal_idle: signalIdle,
|
|
620
712
|
get_help: getHelp,
|
|
621
713
|
get_token_usage: getTokenUsage,
|
|
622
714
|
report_token_usage: reportTokenUsage,
|
package/dist/handlers/tasks.d.ts
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* - update_task
|
|
13
13
|
* - complete_task
|
|
14
14
|
* - delete_task
|
|
15
|
+
* - release_task
|
|
16
|
+
* - cancel_task
|
|
15
17
|
* - add_task_reference
|
|
16
18
|
* - remove_task_reference
|
|
17
19
|
* - batch_update_tasks
|
|
@@ -39,6 +41,12 @@ export declare const addTask: Handler;
|
|
|
39
41
|
export declare const updateTask: Handler;
|
|
40
42
|
export declare const completeTask: Handler;
|
|
41
43
|
export declare const deleteTask: Handler;
|
|
44
|
+
/**
|
|
45
|
+
* Release a task back to pending status.
|
|
46
|
+
* Use when an agent needs to give up a claimed task (context limits, conflicts, user request).
|
|
47
|
+
*/
|
|
48
|
+
export declare const releaseTask: Handler;
|
|
49
|
+
export declare const cancelTask: Handler;
|
|
42
50
|
export declare const addTaskReference: Handler;
|
|
43
51
|
export declare const removeTaskReference: Handler;
|
|
44
52
|
export declare const batchUpdateTasks: Handler;
|