httpcat-cli 0.0.9 → 0.0.11
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/chat-automation.js +171 -0
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +685 -138
- package/dist/commands/chat.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/homebrew-httpcat/Formula/httpcat.rb +18 -0
- package/homebrew-httpcat/README.md +31 -0
- package/homebrew-httpcat/homebrew-httpcat/Formula/httpcat.rb +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Automated chat script for httpcat chat --json mode
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node chat-automation.js <token> [message1] [message2] ...
|
|
8
|
+
*
|
|
9
|
+
* Or pipe messages:
|
|
10
|
+
* echo -e "Hello\nWorld" | node chat-automation.js <token>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { spawn } from 'child_process';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
import { dirname, join } from 'path';
|
|
16
|
+
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = dirname(__filename);
|
|
19
|
+
|
|
20
|
+
const token = process.argv[2];
|
|
21
|
+
|
|
22
|
+
if (!token) {
|
|
23
|
+
console.error('Usage: node chat-automation.js <token> [message1] [message2] ...');
|
|
24
|
+
console.error(' Or: echo -e "msg1\\nmsg2" | node chat-automation.js <token>');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Get messages from command line args or stdin
|
|
29
|
+
const messages = process.argv.slice(3);
|
|
30
|
+
|
|
31
|
+
// Spawn httpcat chat process
|
|
32
|
+
const chatProcess = spawn('httpcat', ['chat', '--json', token], {
|
|
33
|
+
stdio: ['pipe', 'pipe', 'inherit'], // Capture stdout to parse JSON
|
|
34
|
+
shell: true,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Handle JSON output from chat
|
|
38
|
+
let outputBuffer = '';
|
|
39
|
+
chatProcess.stdout.on('data', (data) => {
|
|
40
|
+
outputBuffer += data.toString();
|
|
41
|
+
const lines = outputBuffer.split('\n');
|
|
42
|
+
outputBuffer = lines.pop() || ''; // Keep incomplete line
|
|
43
|
+
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
if (!line.trim()) continue;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const event = JSON.parse(line);
|
|
49
|
+
|
|
50
|
+
switch (event.type) {
|
|
51
|
+
case 'joined':
|
|
52
|
+
console.error(`✅ Joined chat. Lease ID: ${event.leaseId}`);
|
|
53
|
+
// Send initial messages if provided
|
|
54
|
+
if (messages.length > 0) {
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
messages.forEach((msg, index) => {
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
if (chatProcess.stdin && !chatProcess.stdin.destroyed) {
|
|
59
|
+
chatProcess.stdin.write(msg + '\n');
|
|
60
|
+
}
|
|
61
|
+
}, index * 1000); // 1 second between messages
|
|
62
|
+
});
|
|
63
|
+
}, 2000); // Wait 2 seconds after joining
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case 'message':
|
|
68
|
+
const msg = event.data;
|
|
69
|
+
const author = msg.authorShort || msg.author?.slice(0, 6);
|
|
70
|
+
const time = new Date(msg.timestamp).toLocaleTimeString();
|
|
71
|
+
console.error(`[${time}] ${author}: ${msg.message}`);
|
|
72
|
+
|
|
73
|
+
// Auto-respond to messages containing "claude" (case-insensitive)
|
|
74
|
+
// Check if message is from someone else (not our own)
|
|
75
|
+
const isOwn = msg.author?.toLowerCase() === process.env.HTTPCAT_ADDRESS?.toLowerCase();
|
|
76
|
+
if (msg.message.toLowerCase().includes('claude') && !isOwn) {
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
const response = `Hello! I'm Claude, an AI assistant. How can I help you?`;
|
|
79
|
+
if (chatProcess.stdin && !chatProcess.stdin.destroyed) {
|
|
80
|
+
chatProcess.stdin.write(response + '\n');
|
|
81
|
+
}
|
|
82
|
+
}, 1000);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
|
|
86
|
+
case 'message_sent':
|
|
87
|
+
console.error(`✅ Message sent: ${event.messageId}`);
|
|
88
|
+
break;
|
|
89
|
+
|
|
90
|
+
case 'lease_expired':
|
|
91
|
+
console.error('⏱️ Lease expired. Sending /renew...');
|
|
92
|
+
if (chatProcess.stdin && !chatProcess.stdin.destroyed) {
|
|
93
|
+
chatProcess.stdin.write('/renew\n');
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
|
|
97
|
+
case 'error':
|
|
98
|
+
console.error(`❌ Error: ${event.error}`);
|
|
99
|
+
break;
|
|
100
|
+
|
|
101
|
+
case 'exiting':
|
|
102
|
+
console.error('👋 Chat session ended');
|
|
103
|
+
process.exit(0);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
// Not JSON, might be regular output - ignore or log
|
|
108
|
+
if (line.trim() && !line.startsWith('{')) {
|
|
109
|
+
console.error(line);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Send messages from stdin if no command line args
|
|
116
|
+
if (messages.length === 0 && !process.stdin.isTTY) {
|
|
117
|
+
let stdinBuffer = '';
|
|
118
|
+
|
|
119
|
+
process.stdin.setEncoding('utf8');
|
|
120
|
+
process.stdin.on('data', (chunk) => {
|
|
121
|
+
stdinBuffer += chunk.toString();
|
|
122
|
+
const lines = stdinBuffer.split('\n');
|
|
123
|
+
stdinBuffer = lines.pop() || '';
|
|
124
|
+
|
|
125
|
+
for (const line of lines) {
|
|
126
|
+
const trimmed = line.trim();
|
|
127
|
+
if (trimmed) {
|
|
128
|
+
// Wait a bit for chat to be ready, then send
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
if (chatProcess.stdin && !chatProcess.stdin.destroyed) {
|
|
131
|
+
chatProcess.stdin.write(trimmed + '\n');
|
|
132
|
+
}
|
|
133
|
+
}, 2000);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
process.stdin.on('end', () => {
|
|
139
|
+
// Keep process alive to receive messages
|
|
140
|
+
// User can Ctrl+C to exit
|
|
141
|
+
});
|
|
142
|
+
} else if (messages.length > 0) {
|
|
143
|
+
// Messages provided via command line - will be sent after joining
|
|
144
|
+
// (handled in the 'joined' event handler above)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Handle process errors
|
|
148
|
+
chatProcess.on('error', (error) => {
|
|
149
|
+
console.error(`❌ Failed to start chat process: ${error.message}`);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
chatProcess.on('exit', (code) => {
|
|
154
|
+
if (code !== 0 && code !== null) {
|
|
155
|
+
console.error(`Chat process exited with code ${code}`);
|
|
156
|
+
}
|
|
157
|
+
process.exit(code || 0);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Handle Ctrl+C
|
|
161
|
+
process.on('SIGINT', () => {
|
|
162
|
+
console.error('\n👋 Shutting down...');
|
|
163
|
+
if (chatProcess.stdin && !chatProcess.stdin.destroyed) {
|
|
164
|
+
chatProcess.stdin.write('/exit\n');
|
|
165
|
+
}
|
|
166
|
+
setTimeout(() => {
|
|
167
|
+
chatProcess.kill();
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}, 1000);
|
|
170
|
+
});
|
|
171
|
+
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAW7C,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,GAAG,eAAe,GAAG,OAAO,CAAC;IAC5C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuDD,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,aAAa,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,cAAc,CAAC,CA+BzB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,CAa5B;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AAgND,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,OAAe,EACzB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CA+zDf;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAQjE"}
|