gm-orchestrator 0.2.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/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +215 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/orchestrator.d.ts +23 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +173 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/permissions.d.ts +18 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +42 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +25 -0
- package/dist/core/prompt-builder.d.ts.map +1 -0
- package/dist/core/prompt-builder.js +84 -0
- package/dist/core/prompt-builder.js.map +1 -0
- package/dist/core/task-utils.d.ts +5 -0
- package/dist/core/task-utils.d.ts.map +1 -0
- package/dist/core/task-utils.js +27 -0
- package/dist/core/task-utils.js.map +1 -0
- package/dist/core/types.d.ts +150 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/claude-runner.d.ts +14 -0
- package/dist/infra/claude-runner.d.ts.map +1 -0
- package/dist/infra/claude-runner.js +42 -0
- package/dist/infra/claude-runner.js.map +1 -0
- package/dist/infra/config.d.ts +7 -0
- package/dist/infra/config.d.ts.map +1 -0
- package/dist/infra/config.js +61 -0
- package/dist/infra/config.js.map +1 -0
- package/dist/infra/gm-client.d.ts +32 -0
- package/dist/infra/gm-client.d.ts.map +1 -0
- package/dist/infra/gm-client.js +70 -0
- package/dist/infra/gm-client.js.map +1 -0
- package/dist/infra/gm-discovery.d.ts +16 -0
- package/dist/infra/gm-discovery.d.ts.map +1 -0
- package/dist/infra/gm-discovery.js +53 -0
- package/dist/infra/gm-discovery.js.map +1 -0
- package/dist/infra/logger.d.ts +13 -0
- package/dist/infra/logger.d.ts.map +1 -0
- package/dist/infra/logger.js +44 -0
- package/dist/infra/logger.js.map +1 -0
- package/dist/infra/notifications/desktop.d.ts +6 -0
- package/dist/infra/notifications/desktop.d.ts.map +1 -0
- package/dist/infra/notifications/desktop.js +18 -0
- package/dist/infra/notifications/desktop.js.map +1 -0
- package/dist/infra/notifications/index.d.ts +9 -0
- package/dist/infra/notifications/index.d.ts.map +1 -0
- package/dist/infra/notifications/index.js +40 -0
- package/dist/infra/notifications/index.js.map +1 -0
- package/dist/infra/notifications/telegram.d.ts +9 -0
- package/dist/infra/notifications/telegram.d.ts.map +1 -0
- package/dist/infra/notifications/telegram.js +41 -0
- package/dist/infra/notifications/telegram.js.map +1 -0
- package/dist/infra/notifications/types.d.ts +30 -0
- package/dist/infra/notifications/types.d.ts.map +1 -0
- package/dist/infra/notifications/types.js +3 -0
- package/dist/infra/notifications/types.js.map +1 -0
- package/dist/infra/notifications/webhook.d.ts +9 -0
- package/dist/infra/notifications/webhook.d.ts.map +1 -0
- package/dist/infra/notifications/webhook.js +39 -0
- package/dist/infra/notifications/webhook.js.map +1 -0
- package/dist/infra/task-poller.d.ts +9 -0
- package/dist/infra/task-poller.d.ts.map +1 -0
- package/dist/infra/task-poller.js +42 -0
- package/dist/infra/task-poller.js.map +1 -0
- package/dist/server/api.d.ts +23 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +143 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +73 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/runner-service.d.ts +15 -0
- package/dist/server/runner-service.d.ts.map +1 -0
- package/dist/server/runner-service.js +193 -0
- package/dist/server/runner-service.js.map +1 -0
- package/dist/server/ws.d.ts +9 -0
- package/dist/server/ws.d.ts.map +1 -0
- package/dist/server/ws.js +30 -0
- package/dist/server/ws.js.map +1 -0
- package/dist/ui/assets/index-BYPkFAEX.css +1 -0
- package/dist/ui/assets/index-CEQTkIqE.js +60 -0
- package/dist/ui/index.html +13 -0
- package/package.json +70 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { buildPrompt } from '../core/prompt-builder.js';
|
|
3
|
+
export class ClaudeRunner {
|
|
4
|
+
/**
|
|
5
|
+
* Spawns `claude --print <prompt>` as a child process.
|
|
6
|
+
* Streams stdout/stderr to the parent terminal.
|
|
7
|
+
* Resolves when the process exits (for any reason).
|
|
8
|
+
*
|
|
9
|
+
* Note: the orchestrator does NOT rely on process exit for completion
|
|
10
|
+
* detection — it polls GraphMemory task status instead. The session
|
|
11
|
+
* promise is awaited only for cleanup after the poller signals done.
|
|
12
|
+
*/
|
|
13
|
+
async run(task, config) {
|
|
14
|
+
const prompt = buildPrompt(task, { projectId: config.projectId });
|
|
15
|
+
const args = ['--print', '--dangerously-skip-permissions', ...config.claudeArgs, prompt];
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const proc = spawn('claude', args, {
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
env: process.env,
|
|
20
|
+
});
|
|
21
|
+
proc.on('close', (code) => {
|
|
22
|
+
if (code === 0 || code === null) {
|
|
23
|
+
resolve();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Non-zero exit is logged but not fatal — task status drives decisions
|
|
27
|
+
resolve();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
proc.on('error', (err) => {
|
|
31
|
+
if (err.code === 'ENOENT') {
|
|
32
|
+
reject(new Error('claude not found in PATH.\n' +
|
|
33
|
+
'Install Claude Code: npm install -g @anthropic-ai/claude-code'));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
reject(err);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=claude-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-runner.js","sourceRoot":"","sources":["../../src/infra/claude-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,OAAO,YAAY;IACvB;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAC,IAAU,EAAE,MAA0B;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,gCAAgC,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAEzF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;gBACjC,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAChC,OAAO,EAAE,CAAC;gBACZ,CAAC;qBAAM,CAAC;oBACN,uEAAuE;oBACvE,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACrD,MAAM,CAAC,IAAI,KAAK,CACd,6BAA6B;wBAC7B,+DAA+D,CAChE,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { OrchestratorConfig } from '../core/types.js';
|
|
2
|
+
export declare function loadConfig(overrides?: Partial<OrchestratorConfig>): OrchestratorConfig;
|
|
3
|
+
export declare function validateConfig(config: OrchestratorConfig): asserts config is OrchestratorConfig & {
|
|
4
|
+
projectId: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function saveConfig(config: Partial<OrchestratorConfig>): void;
|
|
7
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/infra/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAc3D,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,kBAAkB,CAI1F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAkBvH;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAGpE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
const CONFIG_FILE = '.gm-orchestrator.json';
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
baseUrl: 'http://localhost:3000',
|
|
6
|
+
projectId: '',
|
|
7
|
+
timeoutMs: 15 * 60 * 1000,
|
|
8
|
+
pauseMs: 2_000,
|
|
9
|
+
maxRetries: 1,
|
|
10
|
+
claudeArgs: [],
|
|
11
|
+
dryRun: false,
|
|
12
|
+
};
|
|
13
|
+
export function loadConfig(overrides = {}) {
|
|
14
|
+
const fileConfig = readFileConfig();
|
|
15
|
+
const envConfig = readEnvConfig();
|
|
16
|
+
return { ...DEFAULTS, ...fileConfig, ...envConfig, ...overrides };
|
|
17
|
+
}
|
|
18
|
+
export function validateConfig(config) {
|
|
19
|
+
const errors = [];
|
|
20
|
+
if (!config.projectId) {
|
|
21
|
+
errors.push('projectId is required.\n' +
|
|
22
|
+
' Options: --project <id> | GM_PROJECT_ID env | .gm-orchestrator.json');
|
|
23
|
+
}
|
|
24
|
+
if (config.timeoutMs < 10_000) {
|
|
25
|
+
errors.push('timeoutMs must be at least 10000 (10 seconds)');
|
|
26
|
+
}
|
|
27
|
+
if (errors.length) {
|
|
28
|
+
errors.forEach((e) => console.error(`❌ ${e}`));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function saveConfig(config) {
|
|
33
|
+
const path = resolve(process.cwd(), CONFIG_FILE);
|
|
34
|
+
writeFileSync(path, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
35
|
+
}
|
|
36
|
+
// ── Readers ───────────────────────────────────────────────────────────────
|
|
37
|
+
function readFileConfig() {
|
|
38
|
+
const path = resolve(process.cwd(), CONFIG_FILE);
|
|
39
|
+
if (!existsSync(path))
|
|
40
|
+
return {};
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
console.warn(`Warning: could not parse ${CONFIG_FILE}`);
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function readEnvConfig() {
|
|
50
|
+
const cfg = {};
|
|
51
|
+
if (process.env['GM_BASE_URL'])
|
|
52
|
+
cfg.baseUrl = process.env['GM_BASE_URL'];
|
|
53
|
+
if (process.env['GM_PROJECT_ID'])
|
|
54
|
+
cfg.projectId = process.env['GM_PROJECT_ID'];
|
|
55
|
+
if (process.env['GM_API_KEY'])
|
|
56
|
+
cfg.apiKey = process.env['GM_API_KEY'];
|
|
57
|
+
if (process.env['GM_TIMEOUT_MS'])
|
|
58
|
+
cfg.timeoutMs = Number(process.env['GM_TIMEOUT_MS']);
|
|
59
|
+
return cfg;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/infra/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { GraphMemoryPort, Task, TaskStatus, Epic, EpicStatus } from '../core/types.js';
|
|
2
|
+
interface ClientOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class GraphMemoryClient implements GraphMemoryPort {
|
|
8
|
+
private readonly base;
|
|
9
|
+
private readonly headers;
|
|
10
|
+
constructor({ baseUrl, projectId, apiKey }: ClientOptions);
|
|
11
|
+
listTasks({ status, tag, limit, }?: {
|
|
12
|
+
status?: TaskStatus;
|
|
13
|
+
tag?: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
}): Promise<Task[]>;
|
|
16
|
+
getTask(taskId: string): Promise<Task>;
|
|
17
|
+
moveTask(taskId: string, status: TaskStatus): Promise<void>;
|
|
18
|
+
updateTask(taskId: string, fields: Partial<Task>): Promise<void>;
|
|
19
|
+
getEpic(epicId: string): Promise<Epic>;
|
|
20
|
+
listEpics({ status, limit, }?: {
|
|
21
|
+
status?: EpicStatus;
|
|
22
|
+
limit?: number;
|
|
23
|
+
}): Promise<Epic[]>;
|
|
24
|
+
moveEpic(epicId: string, status: EpicStatus): Promise<void>;
|
|
25
|
+
private get;
|
|
26
|
+
private post;
|
|
27
|
+
private put;
|
|
28
|
+
private patch;
|
|
29
|
+
private req;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=gm-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gm-client.d.ts","sourceRoot":"","sources":["../../src/infra/gm-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,UAAU,EACX,MAAM,kBAAkB,CAAC;AAE1B,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,iBAAkB,YAAW,eAAe;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAErC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa;IAUnD,SAAS,CAAC,EACd,MAAM,EACN,GAAG,EACH,KAAW,GACZ,GAAE;QAAE,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAQzE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,SAAS,CAAC,EACd,MAAM,EACN,KAAU,GACX,GAAE;QAAE,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAO3D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAMnD,GAAG;YAIH,IAAI;YAIJ,GAAG;YAIH,KAAK;YAIL,GAAG;CAclB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export class GraphMemoryClient {
|
|
2
|
+
base;
|
|
3
|
+
headers;
|
|
4
|
+
constructor({ baseUrl, projectId, apiKey }) {
|
|
5
|
+
this.base = `${baseUrl}/api/projects/${projectId}`;
|
|
6
|
+
this.headers = {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
// ── Tasks ─────────────────────────────────────────────────────────────
|
|
12
|
+
async listTasks({ status, tag, limit = 100, } = {}) {
|
|
13
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
14
|
+
if (status)
|
|
15
|
+
params.set('status', status);
|
|
16
|
+
if (tag)
|
|
17
|
+
params.set('tag', tag);
|
|
18
|
+
const data = await this.get(`/tasks?${params}`);
|
|
19
|
+
return data.results ?? [];
|
|
20
|
+
}
|
|
21
|
+
async getTask(taskId) {
|
|
22
|
+
return this.get(`/tasks/${taskId}`);
|
|
23
|
+
}
|
|
24
|
+
async moveTask(taskId, status) {
|
|
25
|
+
await this.post(`/tasks/${taskId}/move`, { status });
|
|
26
|
+
}
|
|
27
|
+
async updateTask(taskId, fields) {
|
|
28
|
+
await this.put(`/tasks/${taskId}`, fields);
|
|
29
|
+
}
|
|
30
|
+
// ── Epics ─────────────────────────────────────────────────────────────
|
|
31
|
+
async getEpic(epicId) {
|
|
32
|
+
return this.get(`/epics/${epicId}`);
|
|
33
|
+
}
|
|
34
|
+
async listEpics({ status, limit = 50, } = {}) {
|
|
35
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
36
|
+
if (status)
|
|
37
|
+
params.set('status', status);
|
|
38
|
+
const data = await this.get(`/epics?${params}`);
|
|
39
|
+
return data.results ?? [];
|
|
40
|
+
}
|
|
41
|
+
async moveEpic(epicId, status) {
|
|
42
|
+
await this.put(`/epics/${epicId}`, { status });
|
|
43
|
+
}
|
|
44
|
+
// ── HTTP ──────────────────────────────────────────────────────────────
|
|
45
|
+
async get(path) {
|
|
46
|
+
return this.req('GET', path);
|
|
47
|
+
}
|
|
48
|
+
async post(path, body) {
|
|
49
|
+
return this.req('POST', path, body);
|
|
50
|
+
}
|
|
51
|
+
async put(path, body) {
|
|
52
|
+
return this.req('PUT', path, body);
|
|
53
|
+
}
|
|
54
|
+
async patch(path, body) {
|
|
55
|
+
return this.req('PATCH', path, body);
|
|
56
|
+
}
|
|
57
|
+
async req(method, path, body) {
|
|
58
|
+
const res = await fetch(`${this.base}${path}`, {
|
|
59
|
+
method,
|
|
60
|
+
headers: this.headers,
|
|
61
|
+
body: body !== undefined ? JSON.stringify(body) : null,
|
|
62
|
+
});
|
|
63
|
+
if (!res.ok) {
|
|
64
|
+
const text = await res.text().catch(() => '');
|
|
65
|
+
throw new Error(`GraphMemory ${method} ${path} → HTTP ${res.status}: ${text}`);
|
|
66
|
+
}
|
|
67
|
+
return res.json();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=gm-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gm-client.js","sourceRoot":"","sources":["../../src/infra/gm-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GMServerProject {
|
|
2
|
+
id: string;
|
|
3
|
+
taskCount: number;
|
|
4
|
+
epicCount: number;
|
|
5
|
+
}
|
|
6
|
+
export interface GMServer {
|
|
7
|
+
url: string;
|
|
8
|
+
port: number;
|
|
9
|
+
projects: GMServerProject[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Auto-discover GraphMemory servers on localhost ports 3000–3010.
|
|
13
|
+
* Scans all ports in parallel and returns responding servers.
|
|
14
|
+
*/
|
|
15
|
+
export declare function discoverServers(): Promise<GMServer[]>;
|
|
16
|
+
//# sourceMappingURL=gm-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gm-discovery.d.ts","sourceRoot":"","sources":["../../src/infra/gm-discovery.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AA6CD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAe3D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// ─── GraphMemory Server Discovery ─────────────────────────────────────────
|
|
2
|
+
// Scans localhost ports 3000–3010 to find running GraphMemory instances.
|
|
3
|
+
const PORT_START = 3000;
|
|
4
|
+
const PORT_END = 3010;
|
|
5
|
+
const TIMEOUT_MS = 500;
|
|
6
|
+
/**
|
|
7
|
+
* Probe a single port for a running GraphMemory server.
|
|
8
|
+
* Tries GET /api/projects first; falls back to GET /api/health.
|
|
9
|
+
*/
|
|
10
|
+
async function probePort(port) {
|
|
11
|
+
const base = `http://127.0.0.1:${port}`;
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetch(`${base}/api/projects`, {
|
|
14
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
15
|
+
});
|
|
16
|
+
if (res.ok) {
|
|
17
|
+
const data = (await res.json());
|
|
18
|
+
return {
|
|
19
|
+
url: base,
|
|
20
|
+
port,
|
|
21
|
+
projects: data.results ?? [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// /api/projects failed — try health endpoint
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const res = await fetch(`${base}/api/health`, {
|
|
30
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
31
|
+
});
|
|
32
|
+
if (res.ok) {
|
|
33
|
+
return { url: base, port, projects: [] };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// not a GM server on this port
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Auto-discover GraphMemory servers on localhost ports 3000–3010.
|
|
43
|
+
* Scans all ports in parallel and returns responding servers.
|
|
44
|
+
*/
|
|
45
|
+
export async function discoverServers() {
|
|
46
|
+
const ports = Array.from({ length: PORT_END - PORT_START + 1 }, (_, i) => PORT_START + i);
|
|
47
|
+
const results = await Promise.allSettled(ports.map(probePort));
|
|
48
|
+
return results
|
|
49
|
+
.filter((r) => r.status === 'fulfilled')
|
|
50
|
+
.map((r) => r.value)
|
|
51
|
+
.filter((server) => server !== null);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=gm-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gm-discovery.js","sourceRoot":"","sources":["../../src/infra/gm-discovery.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,yEAAyE;AAczE,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;;GAGG;AACH,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,MAAM,IAAI,GAAG,oBAAoB,IAAI,EAAE,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,eAAe,EAAE;YAC9C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC;SACxC,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoC,CAAC;YACnE,OAAO;gBACL,GAAG,EAAE,IAAI;gBACT,IAAI;gBACJ,QAAQ,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;aAC7B,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,aAAa,EAAE;YAC5C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC;SACxC,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CACtB,EAAE,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,CAAC,EAAE,EACrC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,GAAG,CAAC,CACzB,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IAE/D,OAAO,OAAO;SACX,MAAM,CACL,CAAC,CAAC,EAAgD,EAAE,CAClD,CAAC,CAAC,MAAM,KAAK,WAAW,CAC3B;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;SACnB,MAAM,CAAC,CAAC,MAAM,EAAsB,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Task } from '../core/types.js';
|
|
2
|
+
export interface Logger {
|
|
3
|
+
info(msg: string): void;
|
|
4
|
+
success(msg: string): void;
|
|
5
|
+
warn(msg: string): void;
|
|
6
|
+
error(msg: string): void;
|
|
7
|
+
skip(msg: string): void;
|
|
8
|
+
section(msg: string): void;
|
|
9
|
+
task(task: Task): void;
|
|
10
|
+
}
|
|
11
|
+
export declare const consoleLogger: Logger;
|
|
12
|
+
export declare const silentLogger: Logger;
|
|
13
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/infra/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AA0BD,eAAO,MAAM,aAAa,EAAE,MAe3B,CAAC;AAIF,eAAO,MAAM,YAAY,EAAE,MAQ1B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ── Console implementation ────────────────────────────────────────────────
|
|
2
|
+
const C = {
|
|
3
|
+
reset: '\x1b[0m',
|
|
4
|
+
bold: '\x1b[1m',
|
|
5
|
+
dim: '\x1b[2m',
|
|
6
|
+
red: '\x1b[31m',
|
|
7
|
+
green: '\x1b[32m',
|
|
8
|
+
yellow: '\x1b[33m',
|
|
9
|
+
cyan: '\x1b[36m',
|
|
10
|
+
magenta: '\x1b[35m',
|
|
11
|
+
};
|
|
12
|
+
function ts() {
|
|
13
|
+
return `${C.dim}${new Date().toTimeString().slice(0, 8)}${C.reset}`;
|
|
14
|
+
}
|
|
15
|
+
const PRIORITY_COLOR = {
|
|
16
|
+
critical: C.red,
|
|
17
|
+
high: C.yellow,
|
|
18
|
+
medium: C.cyan,
|
|
19
|
+
low: C.dim,
|
|
20
|
+
};
|
|
21
|
+
export const consoleLogger = {
|
|
22
|
+
info: (msg) => console.log(`${ts()} ${C.cyan}●${C.reset} ${msg}`),
|
|
23
|
+
success: (msg) => console.log(`${ts()} ${C.green}✓${C.reset} ${msg}`),
|
|
24
|
+
warn: (msg) => console.log(`${ts()} ${C.yellow}⚠${C.reset} ${msg}`),
|
|
25
|
+
error: (msg) => console.log(`${ts()} ${C.red}✗${C.reset} ${msg}`),
|
|
26
|
+
skip: (msg) => console.log(`${ts()} ${C.dim}→ ${msg}${C.reset}`),
|
|
27
|
+
section: (msg) => console.log(`\n${C.bold}${C.magenta}━━ ${msg} ━━${C.reset}`),
|
|
28
|
+
task: (task) => {
|
|
29
|
+
const pc = PRIORITY_COLOR[task.priority] ?? C.reset;
|
|
30
|
+
console.log(`${ts()} ${pc}▶${C.reset} [${task.priority.padEnd(8)}] ${task.title}`);
|
|
31
|
+
console.log(`${C.dim} id: ${task.id}${C.reset}`);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
// ── Silent logger for tests ───────────────────────────────────────────────
|
|
35
|
+
export const silentLogger = {
|
|
36
|
+
info: () => { },
|
|
37
|
+
success: () => { },
|
|
38
|
+
warn: () => { },
|
|
39
|
+
error: () => { },
|
|
40
|
+
skip: () => { },
|
|
41
|
+
section: () => { },
|
|
42
|
+
task: () => { },
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/infra/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.d.ts","sourceRoot":"","sources":["../../../src/infra/notifications/desktop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE,qBAAa,eAAgB,YAAW,gBAAgB;IAChD,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class DesktopNotifier {
|
|
2
|
+
async send(payload) {
|
|
3
|
+
const notifier = await import('node-notifier');
|
|
4
|
+
notifier.default.notify({
|
|
5
|
+
title: payload.title,
|
|
6
|
+
message: payload.body,
|
|
7
|
+
sound: true,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
async test() {
|
|
11
|
+
await this.send({
|
|
12
|
+
event: 'test',
|
|
13
|
+
title: 'gm-orchestrator connected',
|
|
14
|
+
body: 'Desktop notifications are working.',
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.js","sourceRoot":"","sources":["../../../src/infra/notifications/desktop.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,eAAe;IAC1B,KAAK,CAAC,IAAI,CAAC,OAA4B;QACrC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC/C,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,2BAA2B;YAClC,IAAI,EAAE,oCAAoC;SAC3C,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Logger } from '../logger.js';
|
|
2
|
+
import type { NotificationConfig, NotificationPayload } from './types.js';
|
|
3
|
+
export type { NotificationConfig, NotificationPayload, NotificationPort } from './types.js';
|
|
4
|
+
export interface NotificationDispatcher {
|
|
5
|
+
dispatch(payload: NotificationPayload): Promise<void>;
|
|
6
|
+
testAll(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createNotifier(config: NotificationConfig, logger: Logger): NotificationDispatcher;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAoB,MAAM,YAAY,CAAC;AAK5F,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,MAAM,GACb,sBAAsB,CAwCxB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { TelegramNotifier } from './telegram.js';
|
|
2
|
+
import { WebhookNotifier } from './webhook.js';
|
|
3
|
+
import { DesktopNotifier } from './desktop.js';
|
|
4
|
+
export function createNotifier(config, logger) {
|
|
5
|
+
const channels = [];
|
|
6
|
+
if (config.telegram?.enabled) {
|
|
7
|
+
channels.push({ name: 'telegram', port: new TelegramNotifier(config.telegram) });
|
|
8
|
+
}
|
|
9
|
+
if (config.webhook?.enabled) {
|
|
10
|
+
channels.push({ name: 'webhook', port: new WebhookNotifier(config.webhook) });
|
|
11
|
+
}
|
|
12
|
+
if (config.desktop?.enabled) {
|
|
13
|
+
channels.push({ name: 'desktop', port: new DesktopNotifier() });
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
async dispatch(payload) {
|
|
17
|
+
if (channels.length === 0)
|
|
18
|
+
return;
|
|
19
|
+
const results = await Promise.allSettled(channels.map(({ port }) => port.send(payload)));
|
|
20
|
+
results.forEach((result, i) => {
|
|
21
|
+
if (result.status === 'rejected') {
|
|
22
|
+
const ch = channels[i];
|
|
23
|
+
logger.warn(`Notification [${ch.name}] failed: ${result.reason}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
async testAll() {
|
|
28
|
+
for (const { name, port } of channels) {
|
|
29
|
+
try {
|
|
30
|
+
await port.test();
|
|
31
|
+
logger.success(`Notification [${name}] test OK`);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
logger.warn(`Notification [${name}] test failed: ${err}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/notifications/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAS/C,MAAM,UAAU,cAAc,CAC5B,MAA0B,EAC1B,MAAc;IAEd,MAAM,QAAQ,GAAoD,EAAE,CAAC;IAErE,IAAI,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,eAAe,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAA4B;YACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAElC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAC/C,CAAC;YAEF,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,IAAI,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,OAAO;YACX,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;oBAClB,MAAM,CAAC,OAAO,CAAC,iBAAiB,IAAI,WAAW,CAAC,CAAC;gBACnD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,CAAC,iBAAiB,IAAI,kBAAkB,GAAG,EAAE,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NotificationPayload, NotificationPort, TelegramConfig } from './types.js';
|
|
2
|
+
export declare class TelegramNotifier implements NotificationPort {
|
|
3
|
+
private readonly apiUrl;
|
|
4
|
+
private readonly chatId;
|
|
5
|
+
constructor(config: TelegramConfig);
|
|
6
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
7
|
+
test(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=telegram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../../src/infra/notifications/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAWxF,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,cAAc;IAK5B,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const EVENT_EMOJI = {
|
|
2
|
+
task_done: '✅',
|
|
3
|
+
task_failed: '❌',
|
|
4
|
+
sprint_complete: '🏁',
|
|
5
|
+
epic_complete: '🎯',
|
|
6
|
+
error: '🚨',
|
|
7
|
+
test: '🔔',
|
|
8
|
+
};
|
|
9
|
+
export class TelegramNotifier {
|
|
10
|
+
apiUrl;
|
|
11
|
+
chatId;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.apiUrl = `https://api.telegram.org/bot${config.botToken}/sendMessage`;
|
|
14
|
+
this.chatId = config.chatId;
|
|
15
|
+
}
|
|
16
|
+
async send(payload) {
|
|
17
|
+
const emoji = EVENT_EMOJI[payload.event] ?? '📋';
|
|
18
|
+
const text = `${emoji} *${payload.title}*\n\n${payload.body}`;
|
|
19
|
+
const res = await fetch(this.apiUrl, {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: { 'Content-Type': 'application/json' },
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
chat_id: this.chatId,
|
|
24
|
+
text,
|
|
25
|
+
parse_mode: 'Markdown',
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
const body = await res.text();
|
|
30
|
+
throw new Error(`Telegram API error ${res.status}: ${body}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async test() {
|
|
34
|
+
await this.send({
|
|
35
|
+
event: 'test',
|
|
36
|
+
title: 'gm-orchestrator connected',
|
|
37
|
+
body: '🔔 Telegram notifications are working.',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/infra/notifications/telegram.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAA2B;IAC1C,SAAS,EAAE,GAAG;IACd,WAAW,EAAE,GAAG;IAChB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,IAAI;IACnB,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;CACX,CAAC;AAEF,MAAM,OAAO,gBAAgB;IACV,MAAM,CAAS;IACf,MAAM,CAAS;IAEhC,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,+BAA+B,MAAM,CAAC,QAAQ,cAAc,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAA4B;QACrC,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QACjD,MAAM,IAAI,GAAG,GAAG,KAAK,KAAK,OAAO,CAAC,KAAK,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QAE9D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;YACnC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO,EAAE,IAAI,CAAC,MAAM;gBACpB,IAAI;gBACJ,UAAU,EAAE,UAAU;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,2BAA2B;YAClC,IAAI,EAAE,wCAAwC;SAC/C,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type NotificationEvent = 'task_done' | 'task_failed' | 'sprint_complete' | 'epic_complete' | 'error' | 'test';
|
|
2
|
+
export interface NotificationPayload {
|
|
3
|
+
event: NotificationEvent;
|
|
4
|
+
title: string;
|
|
5
|
+
body: string;
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface NotificationPort {
|
|
9
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
10
|
+
test(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export interface TelegramConfig {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
botToken: string;
|
|
15
|
+
chatId: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WebhookConfig {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
url: string;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export interface DesktopConfig {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface NotificationConfig {
|
|
26
|
+
telegram?: TelegramConfig;
|
|
27
|
+
webhook?: WebhookConfig;
|
|
28
|
+
desktop?: DesktopConfig;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/infra/notifications/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,aAAa,GACb,iBAAiB,GACjB,eAAe,GACf,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAID,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/infra/notifications/types.ts"],"names":[],"mappings":"AAAA,4EAA4E"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NotificationPayload, NotificationPort, WebhookConfig } from './types.js';
|
|
2
|
+
export declare class WebhookNotifier implements NotificationPort {
|
|
3
|
+
private readonly url;
|
|
4
|
+
private readonly headers;
|
|
5
|
+
constructor(config: WebhookConfig);
|
|
6
|
+
send(payload: NotificationPayload): Promise<void>;
|
|
7
|
+
test(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=webhook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../src/infra/notifications/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvF,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAErC,MAAM,EAAE,aAAa;IAQ3B,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}
|