mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
- Added `skills-manager.js` for managing Claude Code skills with functionalities for loading, displaying, and editing skills. - Introduced a Notifier module in `notifier.ts` for CLI to server communication, enabling notifications for UI updates on data changes. - Created comprehensive documentation for the Chain Search implementation, including usage examples and performance tips. - Developed a test suite for the Chain Search engine, covering basic search, quick search, symbol search, and files-only search functionalities.
130 lines
3.2 KiB
TypeScript
130 lines
3.2 KiB
TypeScript
/**
|
|
* Notifier Module - CLI to Server Communication
|
|
* Provides best-effort notification to running CCW Server
|
|
* when CLI commands modify data that should trigger UI updates
|
|
*/
|
|
|
|
import http from 'http';
|
|
|
|
// Default server configuration
|
|
const DEFAULT_HOST = 'localhost';
|
|
const DEFAULT_PORT = 3456;
|
|
const NOTIFY_TIMEOUT = 2000; // 2 seconds - quick timeout for best-effort
|
|
|
|
export type NotifyScope = 'memory' | 'history' | 'insights' | 'all';
|
|
|
|
export interface NotifyPayload {
|
|
type: 'REFRESH_REQUIRED' | 'MEMORY_UPDATED' | 'HISTORY_UPDATED' | 'INSIGHT_GENERATED';
|
|
scope: NotifyScope;
|
|
data?: {
|
|
entityType?: string;
|
|
entityId?: string | number;
|
|
action?: string;
|
|
executionId?: string;
|
|
[key: string]: unknown;
|
|
};
|
|
}
|
|
|
|
export interface NotifyResult {
|
|
success: boolean;
|
|
error?: string;
|
|
}
|
|
|
|
/**
|
|
* Send notification to CCW Server (best-effort, non-blocking)
|
|
* If server is not running or unreachable, silently fails
|
|
*/
|
|
export async function notifyServer(
|
|
payload: NotifyPayload,
|
|
options?: { host?: string; port?: number }
|
|
): Promise<NotifyResult> {
|
|
const host = options?.host || DEFAULT_HOST;
|
|
const port = options?.port || DEFAULT_PORT;
|
|
|
|
return new Promise((resolve) => {
|
|
const postData = JSON.stringify(payload);
|
|
|
|
const req = http.request(
|
|
{
|
|
hostname: host,
|
|
port: port,
|
|
path: '/api/system/notify',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(postData),
|
|
},
|
|
timeout: NOTIFY_TIMEOUT,
|
|
},
|
|
(res) => {
|
|
// Success if we get a 2xx response
|
|
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
resolve({ success: true });
|
|
} else {
|
|
resolve({ success: false, error: `HTTP ${res.statusCode}` });
|
|
}
|
|
}
|
|
);
|
|
|
|
// Handle errors silently - server may not be running
|
|
req.on('error', () => {
|
|
resolve({ success: false, error: 'Server not reachable' });
|
|
});
|
|
|
|
req.on('timeout', () => {
|
|
req.destroy();
|
|
resolve({ success: false, error: 'Timeout' });
|
|
});
|
|
|
|
req.write(postData);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convenience: Notify memory update
|
|
*/
|
|
export async function notifyMemoryUpdate(data?: {
|
|
entityType?: string;
|
|
entityId?: string | number;
|
|
action?: string;
|
|
}): Promise<NotifyResult> {
|
|
return notifyServer({
|
|
type: 'MEMORY_UPDATED',
|
|
scope: 'memory',
|
|
data,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convenience: Notify CLI history update
|
|
*/
|
|
export async function notifyHistoryUpdate(executionId?: string): Promise<NotifyResult> {
|
|
return notifyServer({
|
|
type: 'HISTORY_UPDATED',
|
|
scope: 'history',
|
|
data: executionId ? { executionId } : undefined,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convenience: Notify insight generated
|
|
*/
|
|
export async function notifyInsightGenerated(executionId?: string): Promise<NotifyResult> {
|
|
return notifyServer({
|
|
type: 'INSIGHT_GENERATED',
|
|
scope: 'insights',
|
|
data: executionId ? { executionId } : undefined,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convenience: Request full refresh
|
|
*/
|
|
export async function notifyRefreshRequired(scope: NotifyScope = 'all'): Promise<NotifyResult> {
|
|
return notifyServer({
|
|
type: 'REFRESH_REQUIRED',
|
|
scope,
|
|
});
|
|
}
|