@antistud/handrails-cli 0.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.
- package/dist/bin/handrails-rig.d.ts +9 -0
- package/dist/bin/handrails-rig.js +19 -0
- package/dist/bin/handrails-rig.js.map +1 -0
- package/dist/bin/handrails.d.ts +2 -0
- package/dist/bin/handrails.js +10 -0
- package/dist/bin/handrails.js.map +1 -0
- package/dist/src/bridge/daemon.d.ts +50 -0
- package/dist/src/bridge/daemon.js +319 -0
- package/dist/src/bridge/daemon.js.map +1 -0
- package/dist/src/claude/context-manager.d.ts +41 -0
- package/dist/src/claude/context-manager.js +184 -0
- package/dist/src/claude/context-manager.js.map +1 -0
- package/dist/src/claude/reader.d.ts +17 -0
- package/dist/src/claude/reader.js +186 -0
- package/dist/src/claude/reader.js.map +1 -0
- package/dist/src/cli/commands/config.d.ts +2 -0
- package/dist/src/cli/commands/config.js +59 -0
- package/dist/src/cli/commands/config.js.map +1 -0
- package/dist/src/cli/commands/context.d.ts +2 -0
- package/dist/src/cli/commands/context.js +158 -0
- package/dist/src/cli/commands/context.js.map +1 -0
- package/dist/src/cli/commands/daemon.d.ts +2 -0
- package/dist/src/cli/commands/daemon.js +29 -0
- package/dist/src/cli/commands/daemon.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts +2 -0
- package/dist/src/cli/commands/init.js +197 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/login.d.ts +2 -0
- package/dist/src/cli/commands/login.js +87 -0
- package/dist/src/cli/commands/login.js.map +1 -0
- package/dist/src/cli/commands/rig.d.ts +2 -0
- package/dist/src/cli/commands/rig.js +49 -0
- package/dist/src/cli/commands/rig.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +2 -0
- package/dist/src/cli/commands/status.js +119 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/commands/sync.d.ts +2 -0
- package/dist/src/cli/commands/sync.js +149 -0
- package/dist/src/cli/commands/sync.js.map +1 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.js +62 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/config/index.d.ts +20 -0
- package/dist/src/config/index.js +131 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/schema.d.ts +59 -0
- package/dist/src/config/schema.js +14 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/handrails/auth.d.ts +15 -0
- package/dist/src/handrails/auth.js +80 -0
- package/dist/src/handrails/auth.js.map +1 -0
- package/dist/src/handrails/client.d.ts +100 -0
- package/dist/src/handrails/client.js +135 -0
- package/dist/src/handrails/client.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +34 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +10 -0
- package/dist/src/mcp/server.js +167 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/context-tools.d.ts +8 -0
- package/dist/src/mcp/tools/context-tools.js +111 -0
- package/dist/src/mcp/tools/context-tools.js.map +1 -0
- package/dist/src/mcp/tools/sync-tools.d.ts +9 -0
- package/dist/src/mcp/tools/sync-tools.js +170 -0
- package/dist/src/mcp/tools/sync-tools.js.map +1 -0
- package/dist/src/runner/executor.d.ts +8 -0
- package/dist/src/runner/executor.js +39 -0
- package/dist/src/runner/executor.js.map +1 -0
- package/dist/src/runner/executors/claude-code.d.ts +7 -0
- package/dist/src/runner/executors/claude-code.js +247 -0
- package/dist/src/runner/executors/claude-code.js.map +1 -0
- package/dist/src/runner/executors/codex.d.ts +9 -0
- package/dist/src/runner/executors/codex.js +72 -0
- package/dist/src/runner/executors/codex.js.map +1 -0
- package/dist/src/runner/executors/opencode.d.ts +9 -0
- package/dist/src/runner/executors/opencode.js +71 -0
- package/dist/src/runner/executors/opencode.js.map +1 -0
- package/dist/src/runner/executors/types.d.ts +24 -0
- package/dist/src/runner/executors/types.js +27 -0
- package/dist/src/runner/executors/types.js.map +1 -0
- package/dist/src/runner/index.d.ts +34 -0
- package/dist/src/runner/index.js +234 -0
- package/dist/src/runner/index.js.map +1 -0
- package/dist/src/runner/logger.d.ts +14 -0
- package/dist/src/runner/logger.js +35 -0
- package/dist/src/runner/logger.js.map +1 -0
- package/dist/src/workflow/engine.d.ts +44 -0
- package/dist/src/workflow/engine.js +383 -0
- package/dist/src/workflow/engine.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Standalone rig entrypoint.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx @handrails/cli rig --rig-key rig_xxx
|
|
8
|
+
* npx @handrails/cli rig --rig-key rig_xxx --api-url http://localhost:3030
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const cli_1 = require("../src/cli");
|
|
12
|
+
// Inject 'rig' as the command so the user doesn't have to type it
|
|
13
|
+
const args = [...process.argv.slice(0, 2), 'rig', ...process.argv.slice(2)];
|
|
14
|
+
const program = (0, cli_1.createProgram)();
|
|
15
|
+
program.parseAsync(args).catch((err) => {
|
|
16
|
+
console.error(err.message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=handrails-rig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handrails-rig.js","sourceRoot":"","sources":["../../bin/handrails-rig.ts"],"names":[],"mappings":";;AAEA;;;;;;GAMG;;AAEH,oCAA2C;AAE3C,kEAAkE;AAClE,MAAM,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,MAAM,OAAO,GAAG,IAAA,mBAAa,GAAE,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACrC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const cli_1 = require("../src/cli");
|
|
5
|
+
const program = (0, cli_1.createProgram)();
|
|
6
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
7
|
+
console.error(err.message);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=handrails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handrails.js","sourceRoot":"","sources":["../../bin/handrails.ts"],"names":[],"mappings":";;;AAEA,oCAA2C;AAE3C,MAAM,OAAO,GAAG,IAAA,mBAAa,GAAE,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { HandrailsClient } from '../handrails/client';
|
|
2
|
+
export interface BridgeMessage {
|
|
3
|
+
jsonrpc: '2.0';
|
|
4
|
+
id?: string;
|
|
5
|
+
method?: string;
|
|
6
|
+
params?: any;
|
|
7
|
+
result?: any;
|
|
8
|
+
error?: {
|
|
9
|
+
code: number;
|
|
10
|
+
message: string;
|
|
11
|
+
data?: any;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export type ToolHandler = (params: any) => Promise<any>;
|
|
15
|
+
export declare class BridgeDaemon {
|
|
16
|
+
private ws;
|
|
17
|
+
private apiUrl;
|
|
18
|
+
private apiKey;
|
|
19
|
+
private machineName;
|
|
20
|
+
private connectionId;
|
|
21
|
+
private reconnectAttempts;
|
|
22
|
+
private maxReconnectAttempts;
|
|
23
|
+
private reconnectTimer;
|
|
24
|
+
private heartbeatTimer;
|
|
25
|
+
private isShuttingDown;
|
|
26
|
+
private toolHandlers;
|
|
27
|
+
private pendingResponses;
|
|
28
|
+
private client;
|
|
29
|
+
private activeEngines;
|
|
30
|
+
constructor(apiUrl?: string, apiKey?: string);
|
|
31
|
+
private registerBuiltinTools;
|
|
32
|
+
registerTool(method: string, handler: ToolHandler): void;
|
|
33
|
+
start(): Promise<void>;
|
|
34
|
+
private connect;
|
|
35
|
+
private handleMessage;
|
|
36
|
+
private send;
|
|
37
|
+
private sendResponse;
|
|
38
|
+
sendNotification(method: string, params?: any): void;
|
|
39
|
+
/**
|
|
40
|
+
* Send a request to the server and wait for a response.
|
|
41
|
+
* Used for workflow decision nodes that need user input from the web UI.
|
|
42
|
+
*/
|
|
43
|
+
sendRequestAndWait(method: string, params?: any, timeoutMs?: number): Promise<any>;
|
|
44
|
+
getClient(): HandrailsClient;
|
|
45
|
+
getConnectionId(): string | null;
|
|
46
|
+
private startHeartbeat;
|
|
47
|
+
private stopHeartbeat;
|
|
48
|
+
private scheduleReconnect;
|
|
49
|
+
private shutdown;
|
|
50
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.BridgeDaemon = void 0;
|
|
40
|
+
const ws_1 = __importDefault(require("ws"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const config_1 = require("../config");
|
|
43
|
+
const client_1 = require("../handrails/client");
|
|
44
|
+
const engine_1 = require("../workflow/engine");
|
|
45
|
+
class BridgeDaemon {
|
|
46
|
+
constructor(apiUrl, apiKey) {
|
|
47
|
+
this.ws = null;
|
|
48
|
+
this.connectionId = null;
|
|
49
|
+
this.reconnectAttempts = 0;
|
|
50
|
+
this.maxReconnectAttempts = 50;
|
|
51
|
+
this.reconnectTimer = null;
|
|
52
|
+
this.heartbeatTimer = null;
|
|
53
|
+
this.isShuttingDown = false;
|
|
54
|
+
this.toolHandlers = new Map();
|
|
55
|
+
this.pendingResponses = new Map();
|
|
56
|
+
this.activeEngines = new Map();
|
|
57
|
+
const config = (0, config_1.loadConfig)();
|
|
58
|
+
this.apiUrl = apiUrl || config.apiUrl;
|
|
59
|
+
this.apiKey = apiKey || config.apiKey;
|
|
60
|
+
this.machineName = os.hostname();
|
|
61
|
+
this.client = new client_1.HandrailsClient(this.apiUrl, this.apiKey);
|
|
62
|
+
// Register built-in tool handlers
|
|
63
|
+
this.registerBuiltinTools();
|
|
64
|
+
}
|
|
65
|
+
registerBuiltinTools() {
|
|
66
|
+
// Ping/pong for health checks
|
|
67
|
+
this.registerTool('ping', async () => ({ pong: true, timestamp: new Date().toISOString() }));
|
|
68
|
+
// Read file from local filesystem
|
|
69
|
+
this.registerTool('file.read', async (params) => {
|
|
70
|
+
const fs = require('fs');
|
|
71
|
+
const content = fs.readFileSync(params.path, 'utf-8');
|
|
72
|
+
return { content, path: params.path };
|
|
73
|
+
});
|
|
74
|
+
// List directory contents
|
|
75
|
+
this.registerTool('file.list', async (params) => {
|
|
76
|
+
const fs = require('fs');
|
|
77
|
+
const entries = fs.readdirSync(params.path, { withFileTypes: true });
|
|
78
|
+
return {
|
|
79
|
+
entries: entries.map((e) => ({
|
|
80
|
+
name: e.name,
|
|
81
|
+
type: e.isDirectory() ? 'directory' : 'file',
|
|
82
|
+
})),
|
|
83
|
+
path: params.path,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
// Search files with grep-like pattern
|
|
87
|
+
this.registerTool('file.search', async (params) => {
|
|
88
|
+
const { execSync } = require('child_process');
|
|
89
|
+
try {
|
|
90
|
+
const result = execSync(`grep -rn "${params.pattern.replace(/"/g, '\\"')}" "${params.path}" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.py" --include="*.go" --include="*.rs" -l`, { encoding: 'utf-8', maxBuffer: 1024 * 1024 });
|
|
91
|
+
return { files: result.trim().split('\n').filter(Boolean) };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return { files: [] };
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
// Run a shell command
|
|
98
|
+
this.registerTool('shell.exec', async (params) => {
|
|
99
|
+
const { execSync } = require('child_process');
|
|
100
|
+
try {
|
|
101
|
+
const stdout = execSync(params.command, {
|
|
102
|
+
encoding: 'utf-8',
|
|
103
|
+
cwd: params.cwd || process.cwd(),
|
|
104
|
+
maxBuffer: 5 * 1024 * 1024,
|
|
105
|
+
timeout: 30000,
|
|
106
|
+
});
|
|
107
|
+
return { stdout, exitCode: 0 };
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return {
|
|
111
|
+
stdout: error.stdout || '',
|
|
112
|
+
stderr: error.stderr || '',
|
|
113
|
+
exitCode: error.status || 1,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// Git status
|
|
118
|
+
this.registerTool('git.status', async (params) => {
|
|
119
|
+
const { execSync } = require('child_process');
|
|
120
|
+
const cwd = params?.cwd || process.cwd();
|
|
121
|
+
const status = execSync('git status --porcelain', { encoding: 'utf-8', cwd });
|
|
122
|
+
const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd }).trim();
|
|
123
|
+
return { branch, files: status.trim().split('\n').filter(Boolean) };
|
|
124
|
+
});
|
|
125
|
+
// Workflow: start execution
|
|
126
|
+
this.registerTool('workflow.start', async (params) => {
|
|
127
|
+
const engine = new engine_1.WorkflowEngine(this, this.client);
|
|
128
|
+
this.activeEngines.set(params.run_id, engine);
|
|
129
|
+
// Execute asynchronously - progress is streamed via notifications
|
|
130
|
+
engine.execute(params.workflow, params.run_id, params.input)
|
|
131
|
+
.finally(() => this.activeEngines.delete(params.run_id));
|
|
132
|
+
return { accepted: true, run_id: params.run_id };
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
registerTool(method, handler) {
|
|
136
|
+
this.toolHandlers.set(method, handler);
|
|
137
|
+
}
|
|
138
|
+
async start() {
|
|
139
|
+
if (!this.apiKey) {
|
|
140
|
+
throw new Error('Not authenticated. Run "handrails login" first.');
|
|
141
|
+
}
|
|
142
|
+
console.log(`Connecting to Handrails bridge at ${this.apiUrl}...`);
|
|
143
|
+
this.connect();
|
|
144
|
+
// Handle graceful shutdown
|
|
145
|
+
process.on('SIGINT', () => this.shutdown());
|
|
146
|
+
process.on('SIGTERM', () => this.shutdown());
|
|
147
|
+
// Keep process alive
|
|
148
|
+
return new Promise(() => { });
|
|
149
|
+
}
|
|
150
|
+
connect() {
|
|
151
|
+
if (this.isShuttingDown)
|
|
152
|
+
return;
|
|
153
|
+
const wsUrl = this.apiUrl
|
|
154
|
+
.replace('https://', 'wss://')
|
|
155
|
+
.replace('http://', 'ws://');
|
|
156
|
+
const url = `${wsUrl}/bridge-ws?api_key=${encodeURIComponent(this.apiKey)}&machine=${encodeURIComponent(this.machineName)}`;
|
|
157
|
+
this.ws = new ws_1.default(url);
|
|
158
|
+
this.ws.on('open', () => {
|
|
159
|
+
this.reconnectAttempts = 0;
|
|
160
|
+
console.log('Connected to Handrails bridge');
|
|
161
|
+
this.startHeartbeat();
|
|
162
|
+
});
|
|
163
|
+
this.ws.on('message', (data) => {
|
|
164
|
+
try {
|
|
165
|
+
const message = JSON.parse(data.toString());
|
|
166
|
+
this.handleMessage(message);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error('Error parsing message:', error);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
this.ws.on('close', (code, reason) => {
|
|
173
|
+
console.log(`Bridge connection closed: ${code} ${reason}`);
|
|
174
|
+
this.stopHeartbeat();
|
|
175
|
+
this.connectionId = null;
|
|
176
|
+
this.scheduleReconnect();
|
|
177
|
+
});
|
|
178
|
+
this.ws.on('error', (error) => {
|
|
179
|
+
console.error('Bridge connection error:', error.message);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async handleMessage(message) {
|
|
183
|
+
// Handle welcome message
|
|
184
|
+
if (message.method === 'bridge.connected') {
|
|
185
|
+
this.connectionId = message.params?.connectionId;
|
|
186
|
+
console.log(`Bridge established. Connection ID: ${this.connectionId}`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
// Handle ping from server
|
|
190
|
+
if (message.method === 'ping') {
|
|
191
|
+
this.send({ jsonrpc: '2.0', method: 'heartbeat' });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Handle workflow user response (notification from server when user answers a decision prompt)
|
|
195
|
+
if (message.method === 'workflow.user_response' && message.params) {
|
|
196
|
+
const { run_id, node_id, response } = message.params;
|
|
197
|
+
const engine = this.activeEngines.get(run_id);
|
|
198
|
+
if (engine) {
|
|
199
|
+
engine.handleUserResponse(run_id, node_id, response);
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// Handle response to our requests (for workflow user responses, etc.)
|
|
204
|
+
if (message.id && !message.method) {
|
|
205
|
+
const pending = this.pendingResponses.get(message.id);
|
|
206
|
+
if (pending) {
|
|
207
|
+
this.pendingResponses.delete(message.id);
|
|
208
|
+
if (message.error) {
|
|
209
|
+
pending.reject(message.error);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
pending.resolve(message.result);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// Handle incoming request (tool execution, workflow start, etc.)
|
|
218
|
+
if (message.id && message.method) {
|
|
219
|
+
const handler = this.toolHandlers.get(message.method);
|
|
220
|
+
if (!handler) {
|
|
221
|
+
this.sendResponse(message.id, undefined, {
|
|
222
|
+
code: -32601,
|
|
223
|
+
message: `Method not found: ${message.method}`,
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const result = await handler(message.params);
|
|
229
|
+
this.sendResponse(message.id, result);
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
this.sendResponse(message.id, undefined, {
|
|
233
|
+
code: -32000,
|
|
234
|
+
message: error.message || 'Tool execution failed',
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
send(message) {
|
|
241
|
+
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
242
|
+
this.ws.send(JSON.stringify(message));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
sendResponse(id, result, error) {
|
|
246
|
+
const response = { jsonrpc: '2.0', id };
|
|
247
|
+
if (error) {
|
|
248
|
+
response.error = error;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
response.result = result;
|
|
252
|
+
}
|
|
253
|
+
this.send(response);
|
|
254
|
+
}
|
|
255
|
+
sendNotification(method, params) {
|
|
256
|
+
this.send({ jsonrpc: '2.0', method, params });
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Send a request to the server and wait for a response.
|
|
260
|
+
* Used for workflow decision nodes that need user input from the web UI.
|
|
261
|
+
*/
|
|
262
|
+
async sendRequestAndWait(method, params, timeoutMs = 300000) {
|
|
263
|
+
const id = Math.random().toString(36).substring(2, 10);
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const timer = setTimeout(() => {
|
|
266
|
+
this.pendingResponses.delete(id);
|
|
267
|
+
reject(new Error(`Request timed out after ${timeoutMs}ms`));
|
|
268
|
+
}, timeoutMs);
|
|
269
|
+
this.pendingResponses.set(id, {
|
|
270
|
+
resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
271
|
+
reject: (error) => { clearTimeout(timer); reject(error); },
|
|
272
|
+
});
|
|
273
|
+
this.send({ jsonrpc: '2.0', id, method, params });
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
getClient() {
|
|
277
|
+
return this.client;
|
|
278
|
+
}
|
|
279
|
+
getConnectionId() {
|
|
280
|
+
return this.connectionId;
|
|
281
|
+
}
|
|
282
|
+
startHeartbeat() {
|
|
283
|
+
this.heartbeatTimer = setInterval(() => {
|
|
284
|
+
this.send({ jsonrpc: '2.0', method: 'heartbeat' });
|
|
285
|
+
}, 25000);
|
|
286
|
+
}
|
|
287
|
+
stopHeartbeat() {
|
|
288
|
+
if (this.heartbeatTimer) {
|
|
289
|
+
clearInterval(this.heartbeatTimer);
|
|
290
|
+
this.heartbeatTimer = null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
scheduleReconnect() {
|
|
294
|
+
if (this.isShuttingDown)
|
|
295
|
+
return;
|
|
296
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
297
|
+
console.error('Max reconnect attempts reached. Exiting.');
|
|
298
|
+
process.exit(1);
|
|
299
|
+
}
|
|
300
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
|
|
301
|
+
this.reconnectAttempts++;
|
|
302
|
+
console.log(`Reconnecting in ${delay / 1000}s (attempt ${this.reconnectAttempts})...`);
|
|
303
|
+
this.reconnectTimer = setTimeout(() => {
|
|
304
|
+
this.connect();
|
|
305
|
+
}, delay);
|
|
306
|
+
}
|
|
307
|
+
shutdown() {
|
|
308
|
+
console.log('\nShutting down bridge daemon...');
|
|
309
|
+
this.isShuttingDown = true;
|
|
310
|
+
this.stopHeartbeat();
|
|
311
|
+
if (this.reconnectTimer)
|
|
312
|
+
clearTimeout(this.reconnectTimer);
|
|
313
|
+
if (this.ws)
|
|
314
|
+
this.ws.close(1000, 'Client shutting down');
|
|
315
|
+
process.exit(0);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
exports.BridgeDaemon = BridgeDaemon;
|
|
319
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/bridge/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the current CLAUDE.md content for a project, separated into
|
|
3
|
+
* team-managed and local sections.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getContextSections(projectPath: string): {
|
|
6
|
+
full: string | null;
|
|
7
|
+
teamSection: string | null;
|
|
8
|
+
localSection: string | null;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Pull team CLAUDE.md template from Handrails and merge with local content.
|
|
12
|
+
*/
|
|
13
|
+
export declare function pullContext(projectPath: string): Promise<{
|
|
14
|
+
updated: boolean;
|
|
15
|
+
templateFound: boolean;
|
|
16
|
+
path: string;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Push the local (non-team) section of CLAUDE.md to Handrails as a template suggestion.
|
|
20
|
+
*/
|
|
21
|
+
export declare function pushContext(projectPath: string): Promise<{
|
|
22
|
+
pushed: boolean;
|
|
23
|
+
content: string | null;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Sync slash commands between local and team.
|
|
27
|
+
* Pull: team commands -> local slash-commands dir
|
|
28
|
+
* Push: local-only commands -> stored as knowledge in Handrails
|
|
29
|
+
*/
|
|
30
|
+
export declare function syncSlashCommands(direction?: 'pull' | 'push' | 'both'): Promise<{
|
|
31
|
+
pulled: number;
|
|
32
|
+
pushed: number;
|
|
33
|
+
commands: string[];
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Suggest an update to CLAUDE.md — returns the proposed content without writing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function suggestContextUpdate(projectPath: string, addition: string, section?: 'local' | 'team'): {
|
|
39
|
+
currentContent: string | null;
|
|
40
|
+
proposedContent: string;
|
|
41
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getContextSections = getContextSections;
|
|
37
|
+
exports.pullContext = pullContext;
|
|
38
|
+
exports.pushContext = pushContext;
|
|
39
|
+
exports.syncSlashCommands = syncSlashCommands;
|
|
40
|
+
exports.suggestContextUpdate = suggestContextUpdate;
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const client_1 = require("../handrails/client");
|
|
43
|
+
const config_1 = require("../config");
|
|
44
|
+
const reader_1 = require("./reader");
|
|
45
|
+
const TEAM_SECTION_START = '<!-- handrails:team-context:start -->';
|
|
46
|
+
const TEAM_SECTION_END = '<!-- handrails:team-context:end -->';
|
|
47
|
+
/**
|
|
48
|
+
* Get the current CLAUDE.md content for a project, separated into
|
|
49
|
+
* team-managed and local sections.
|
|
50
|
+
*/
|
|
51
|
+
function getContextSections(projectPath) {
|
|
52
|
+
const content = (0, reader_1.getProjectClaudeMd)(projectPath);
|
|
53
|
+
if (!content)
|
|
54
|
+
return { full: null, teamSection: null, localSection: null };
|
|
55
|
+
const startIdx = content.indexOf(TEAM_SECTION_START);
|
|
56
|
+
const endIdx = content.indexOf(TEAM_SECTION_END);
|
|
57
|
+
if (startIdx === -1 || endIdx === -1) {
|
|
58
|
+
return { full: content, teamSection: null, localSection: content };
|
|
59
|
+
}
|
|
60
|
+
const teamSection = content.substring(startIdx + TEAM_SECTION_START.length, endIdx).trim();
|
|
61
|
+
const beforeTeam = content.substring(0, startIdx).trim();
|
|
62
|
+
const afterTeam = content.substring(endIdx + TEAM_SECTION_END.length).trim();
|
|
63
|
+
const localSection = [beforeTeam, afterTeam].filter(Boolean).join('\n\n');
|
|
64
|
+
return { full: content, teamSection, localSection };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Pull team CLAUDE.md template from Handrails and merge with local content.
|
|
68
|
+
*/
|
|
69
|
+
async function pullContext(projectPath) {
|
|
70
|
+
const config = (0, config_1.loadConfig)();
|
|
71
|
+
const projectConfig = config.projects[projectPath];
|
|
72
|
+
const projectTag = projectConfig?.projectTag || path.basename(projectPath);
|
|
73
|
+
const client = new client_1.HandrailsClient();
|
|
74
|
+
const template = await client.getClaudeMdTemplate(projectTag);
|
|
75
|
+
const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
|
|
76
|
+
if (!template) {
|
|
77
|
+
return { updated: false, templateFound: false, path: claudeMdPath };
|
|
78
|
+
}
|
|
79
|
+
const existing = (0, reader_1.getProjectClaudeMd)(projectPath);
|
|
80
|
+
if (!existing) {
|
|
81
|
+
// No local CLAUDE.md — write the team template with markers
|
|
82
|
+
const content = `${TEAM_SECTION_START}\n${template}\n${TEAM_SECTION_END}\n`;
|
|
83
|
+
(0, reader_1.writeProjectClaudeMd)(projectPath, content);
|
|
84
|
+
return { updated: true, templateFound: true, path: claudeMdPath };
|
|
85
|
+
}
|
|
86
|
+
// Merge: replace team section, preserve local content
|
|
87
|
+
const { localSection } = getContextSections(projectPath);
|
|
88
|
+
const parts = [];
|
|
89
|
+
if (localSection) {
|
|
90
|
+
parts.push(localSection);
|
|
91
|
+
parts.push('');
|
|
92
|
+
}
|
|
93
|
+
parts.push(TEAM_SECTION_START);
|
|
94
|
+
parts.push(template);
|
|
95
|
+
parts.push(TEAM_SECTION_END);
|
|
96
|
+
(0, reader_1.writeProjectClaudeMd)(projectPath, parts.join('\n'));
|
|
97
|
+
return { updated: true, templateFound: true, path: claudeMdPath };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Push the local (non-team) section of CLAUDE.md to Handrails as a template suggestion.
|
|
101
|
+
*/
|
|
102
|
+
async function pushContext(projectPath) {
|
|
103
|
+
const { localSection } = getContextSections(projectPath);
|
|
104
|
+
if (!localSection) {
|
|
105
|
+
return { pushed: false, content: null };
|
|
106
|
+
}
|
|
107
|
+
const config = (0, config_1.loadConfig)();
|
|
108
|
+
const projectConfig = config.projects[projectPath];
|
|
109
|
+
const projectTag = projectConfig?.projectTag || path.basename(projectPath);
|
|
110
|
+
const client = new client_1.HandrailsClient();
|
|
111
|
+
await client.saveClaudeMdTemplate(localSection, projectTag);
|
|
112
|
+
return { pushed: true, content: localSection };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sync slash commands between local and team.
|
|
116
|
+
* Pull: team commands -> local slash-commands dir
|
|
117
|
+
* Push: local-only commands -> stored as knowledge in Handrails
|
|
118
|
+
*/
|
|
119
|
+
async function syncSlashCommands(direction = 'both') {
|
|
120
|
+
const client = new client_1.HandrailsClient();
|
|
121
|
+
let pulled = 0;
|
|
122
|
+
let pushed = 0;
|
|
123
|
+
const commands = [];
|
|
124
|
+
if (direction === 'pull' || direction === 'both') {
|
|
125
|
+
const teamCommands = await client.listCommands();
|
|
126
|
+
for (const cmd of teamCommands) {
|
|
127
|
+
if (!cmd.is_active)
|
|
128
|
+
continue;
|
|
129
|
+
const content = cmd.description
|
|
130
|
+
? `${cmd.description}\n\n${cmd.system_prompt}`
|
|
131
|
+
: cmd.system_prompt;
|
|
132
|
+
(0, reader_1.writeSlashCommand)(cmd.name, content);
|
|
133
|
+
commands.push(`pull: /${cmd.name}`);
|
|
134
|
+
pulled++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (direction === 'push' || direction === 'both') {
|
|
138
|
+
const localCommands = (0, reader_1.getSlashCommands)();
|
|
139
|
+
const teamCommands = direction === 'both'
|
|
140
|
+
? await client.listCommands()
|
|
141
|
+
: await client.listCommands();
|
|
142
|
+
const teamNames = new Set(teamCommands.map(c => c.name));
|
|
143
|
+
for (const local of localCommands) {
|
|
144
|
+
if (teamNames.has(local.name))
|
|
145
|
+
continue; // Already exists on team
|
|
146
|
+
// Store local command as knowledge for now
|
|
147
|
+
// (full command sync would need a POST /mcp/commands endpoint)
|
|
148
|
+
await client.storeDocument(`Slash Command: /${local.name}`, `# /${local.name}\n\n${local.content}`);
|
|
149
|
+
commands.push(`push: /${local.name}`);
|
|
150
|
+
pushed++;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { pulled, pushed, commands };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Suggest an update to CLAUDE.md — returns the proposed content without writing.
|
|
157
|
+
*/
|
|
158
|
+
function suggestContextUpdate(projectPath, addition, section = 'local') {
|
|
159
|
+
const current = (0, reader_1.getProjectClaudeMd)(projectPath);
|
|
160
|
+
if (!current) {
|
|
161
|
+
return {
|
|
162
|
+
currentContent: null,
|
|
163
|
+
proposedContent: `${addition}\n`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (section === 'team') {
|
|
167
|
+
const startIdx = current.indexOf(TEAM_SECTION_START);
|
|
168
|
+
const endIdx = current.indexOf(TEAM_SECTION_END);
|
|
169
|
+
if (startIdx !== -1 && endIdx !== -1) {
|
|
170
|
+
const teamContent = current.substring(startIdx + TEAM_SECTION_START.length, endIdx).trim();
|
|
171
|
+
const newTeamContent = `${teamContent}\n\n${addition}`;
|
|
172
|
+
const proposed = current.substring(0, startIdx + TEAM_SECTION_START.length) +
|
|
173
|
+
'\n' + newTeamContent + '\n' +
|
|
174
|
+
current.substring(endIdx);
|
|
175
|
+
return { currentContent: current, proposedContent: proposed };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Append to end (local section)
|
|
179
|
+
return {
|
|
180
|
+
currentContent: current,
|
|
181
|
+
proposedContent: `${current}\n\n${addition}\n`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=context-manager.js.map
|