@notilens/notilens 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/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js ADDED
@@ -0,0 +1,416 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const config_1 = require("./config");
5
+ const state_1 = require("./state");
6
+ const notify_1 = require("./notify");
7
+ const VERSION = require('../package.json').version;
8
+ // ---- Arg helpers ----
9
+ /** Split args into positional (before first --flag) and the full list for flag parsing. */
10
+ function positionalArgs(args) {
11
+ const result = [];
12
+ for (const a of args) {
13
+ if (a.startsWith('--'))
14
+ break;
15
+ result.push(a);
16
+ }
17
+ return result;
18
+ }
19
+ function parseFlags(args) {
20
+ const flags = {
21
+ agent: '',
22
+ taskId: '',
23
+ type: '',
24
+ meta: {},
25
+ imageUrl: '',
26
+ openUrl: '',
27
+ downloadUrl: '',
28
+ tags: '',
29
+ isActionable: '',
30
+ confidenceScore: 0,
31
+ };
32
+ for (let i = 0; i < args.length; i++) {
33
+ switch (args[i]) {
34
+ case '--agent':
35
+ flags.agent = args[++i] ?? '';
36
+ break;
37
+ case '--task':
38
+ flags.taskId = args[++i] ?? '';
39
+ break;
40
+ case '--type':
41
+ flags.type = args[++i] ?? '';
42
+ break;
43
+ case '--image_url':
44
+ flags.imageUrl = args[++i] ?? '';
45
+ break;
46
+ case '--open_url':
47
+ flags.openUrl = args[++i] ?? '';
48
+ break;
49
+ case '--download_url':
50
+ flags.downloadUrl = args[++i] ?? '';
51
+ break;
52
+ case '--tags':
53
+ flags.tags = args[++i] ?? '';
54
+ break;
55
+ case '--is_actionable':
56
+ flags.isActionable = args[++i] ?? '';
57
+ break;
58
+ case '--confidence':
59
+ flags.confidenceScore = parseFloat(args[++i] ?? '0') || 0;
60
+ break;
61
+ case '--meta': {
62
+ const kv = args[++i] ?? '';
63
+ const eq = kv.indexOf('=');
64
+ if (eq !== -1)
65
+ flags.meta[kv.slice(0, eq)] = kv.slice(eq + 1);
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ if (!flags.agent) {
71
+ console.error('❌ --agent is required');
72
+ process.exit(1);
73
+ }
74
+ if (!flags.taskId) {
75
+ flags.taskId = `task_${Date.now()}`;
76
+ }
77
+ return flags;
78
+ }
79
+ // ---- Event type / actionable mapping ----
80
+ function getEventType(event) {
81
+ switch (event) {
82
+ case 'task.completed':
83
+ case 'response.generated':
84
+ case 'input.approved':
85
+ return 'success';
86
+ case 'task.failed':
87
+ case 'task.timeout':
88
+ case 'response.failed':
89
+ case 'validation.failed':
90
+ return 'urgent';
91
+ case 'task.error':
92
+ case 'task.terminated':
93
+ case 'guardrail.triggered':
94
+ return 'important';
95
+ case 'task.retrying':
96
+ case 'task.cancelled':
97
+ case 'input.required':
98
+ case 'input.rejected':
99
+ return 'warning';
100
+ default:
101
+ return 'info';
102
+ }
103
+ }
104
+ function getActionableDefault(event) {
105
+ return [
106
+ 'task.error', 'task.failed', 'task.timeout', 'task.retrying',
107
+ 'ai.response.failed', 'ai.validation.failed', 'ai.guardrail.triggered',
108
+ 'input.required', 'input.rejected',
109
+ ].includes(event);
110
+ }
111
+ function validateType(t) {
112
+ return ['info', 'success', 'warning', 'urgent', 'important'].includes(t)
113
+ ? t
114
+ : '';
115
+ }
116
+ // ---- Core send ----
117
+ async function sendNotify(event, title, message, flags) {
118
+ const conf = (0, config_1.getAgentConfig)(flags.agent);
119
+ if (!conf?.endpoint || !conf?.secret) {
120
+ console.error('❌ Agent not configured');
121
+ return;
122
+ }
123
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
124
+ const state = (0, state_1.readState)(stateFile);
125
+ const promptTokens = state.prompt_tokens ?? 0;
126
+ const completionTokens = state.completion_tokens ?? 0;
127
+ const meta = {
128
+ duration_ms: state.duration_ms ?? 0,
129
+ prompt_tokens: promptTokens,
130
+ completion_tokens: completionTokens,
131
+ total_tokens: promptTokens + completionTokens,
132
+ retry_count: state.retry_count ?? 0,
133
+ confidence_score: flags.confidenceScore,
134
+ loop_count: state.loop_count ?? 0,
135
+ ...flags.meta,
136
+ };
137
+ const finalType = validateType(flags.type) || getEventType(event);
138
+ const finalActionable = flags.isActionable !== ''
139
+ ? flags.isActionable === 'true'
140
+ : getActionableDefault(event);
141
+ const payload = {
142
+ event,
143
+ title,
144
+ message,
145
+ type: finalType,
146
+ agent: flags.agent,
147
+ task_id: flags.taskId,
148
+ meta,
149
+ image_url: flags.imageUrl,
150
+ open_url: flags.openUrl,
151
+ download_url: flags.downloadUrl,
152
+ tags: flags.tags,
153
+ is_actionable: finalActionable,
154
+ };
155
+ try {
156
+ await (0, notify_1.sendNotification)(conf.endpoint, conf.secret, payload);
157
+ await new Promise(r => setTimeout(r, 300)); // match bash sleep 0.3
158
+ }
159
+ catch {
160
+ // Silent fail — mirrors bash curl behaviour
161
+ }
162
+ }
163
+ // ---- Duration helper ----
164
+ function calcDuration(stateFile) {
165
+ const state = (0, state_1.readState)(stateFile);
166
+ return Date.now() - (state.start_time ?? 0);
167
+ }
168
+ // ---- Commands ----
169
+ async function main() {
170
+ const args = process.argv.slice(2);
171
+ const command = args[0];
172
+ const rest = args.slice(1);
173
+ switch (command) {
174
+ case 'add-agent': {
175
+ const [agent, transport, endpoint, secret] = rest;
176
+ if (!agent || !transport || !endpoint || !secret) {
177
+ console.error('Usage: notilens add-agent <agent> <transport> <endpoint> <secret>');
178
+ process.exit(1);
179
+ }
180
+ (0, config_1.addAgent)(agent, transport, endpoint, secret);
181
+ console.log(`✔ Agent '${agent}' added`);
182
+ break;
183
+ }
184
+ case 'task.start': {
185
+ const flags = parseFlags(rest);
186
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
187
+ (0, state_1.writeState)(stateFile, {
188
+ agent: flags.agent,
189
+ task: flags.taskId,
190
+ start_time: Date.now(),
191
+ retry_count: 0,
192
+ });
193
+ await sendNotify('task.started', `${flags.agent} | ${flags.taskId} started`, 'Task started', flags);
194
+ console.log(`▶️ Started: ${flags.agent} | ${flags.taskId}`);
195
+ break;
196
+ }
197
+ case 'task.in_progress': {
198
+ const flags = parseFlags(rest);
199
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
200
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile) });
201
+ await sendNotify('task.in_progress', `${flags.agent} | ${flags.taskId} running`, 'Task in progress', flags);
202
+ console.log(`⏳ In Progress: ${flags.agent} | ${flags.taskId}`);
203
+ break;
204
+ }
205
+ case 'task.stop': {
206
+ const flags = parseFlags(rest);
207
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
208
+ const dur = calcDuration(stateFile);
209
+ (0, state_1.updateState)(stateFile, { duration_ms: dur });
210
+ await sendNotify('task.stopped', `${flags.agent} | ${flags.taskId} stopped`, 'Task stopped', flags);
211
+ console.log(`⏹ Stopped: ${flags.agent} | ${flags.taskId} (${dur} ms)`);
212
+ break;
213
+ }
214
+ case 'task.retry': {
215
+ const flags = parseFlags(rest);
216
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
217
+ const state = (0, state_1.readState)(stateFile);
218
+ (0, state_1.updateState)(stateFile, {
219
+ duration_ms: calcDuration(stateFile),
220
+ retry_count: (state.retry_count ?? 0) + 1,
221
+ });
222
+ await sendNotify('task.retrying', `${flags.agent} | ${flags.taskId} retry`, 'Retrying task', flags);
223
+ console.log(`🔁 Retry: ${flags.agent} | ${flags.taskId}`);
224
+ break;
225
+ }
226
+ case 'task.loop': {
227
+ const pos = positionalArgs(rest);
228
+ const msg = pos[0] ?? '';
229
+ const flags = parseFlags(rest);
230
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
231
+ const state = (0, state_1.readState)(stateFile);
232
+ const loopCount = (state.loop_count ?? 0) + 1;
233
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), loop_count: loopCount });
234
+ await sendNotify('task.loop', `${flags.agent} | ${flags.taskId} loop #${loopCount}`, msg, flags);
235
+ console.log(`🔄 Loop (${loopCount}): ${flags.agent} | ${flags.taskId}`);
236
+ break;
237
+ }
238
+ case 'task.error': {
239
+ const pos = positionalArgs(rest);
240
+ const msg = pos[0] ?? '';
241
+ const flags = parseFlags(rest);
242
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
243
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), last_error: msg });
244
+ await sendNotify('task.error', `${flags.agent} | ${flags.taskId} error`, msg, flags);
245
+ console.error(`❌ Error: ${msg}`);
246
+ break;
247
+ }
248
+ case 'task.fail': {
249
+ const pos = positionalArgs(rest);
250
+ const msg = pos[0] ?? '';
251
+ const flags = parseFlags(rest);
252
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
253
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), failed: true });
254
+ await sendNotify('task.failed', `${flags.agent} | ${flags.taskId} failed`, msg, flags);
255
+ (0, state_1.deleteState)(stateFile);
256
+ console.log(`💥 Failed: ${flags.agent} | ${flags.taskId}`);
257
+ break;
258
+ }
259
+ case 'task.timeout': {
260
+ const pos = positionalArgs(rest);
261
+ const msg = pos[0] ?? '';
262
+ const flags = parseFlags(rest);
263
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
264
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), timeout: true });
265
+ await sendNotify('task.timeout', `${flags.agent} | ${flags.taskId} timeout`, msg, flags);
266
+ (0, state_1.deleteState)(stateFile);
267
+ console.log(`⏰ Timeout: ${flags.agent} | ${flags.taskId}`);
268
+ break;
269
+ }
270
+ case 'task.cancel': {
271
+ const pos = positionalArgs(rest);
272
+ const msg = pos[0] ?? '';
273
+ const flags = parseFlags(rest);
274
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
275
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), cancelled: true });
276
+ await sendNotify('task.cancelled', `${flags.agent} | ${flags.taskId} cancelled`, msg, flags);
277
+ (0, state_1.deleteState)(stateFile);
278
+ console.log(`🚫 Cancelled: ${flags.agent} | ${flags.taskId}`);
279
+ break;
280
+ }
281
+ case 'task.terminate': {
282
+ const pos = positionalArgs(rest);
283
+ const msg = pos[0] ?? '';
284
+ const flags = parseFlags(rest);
285
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
286
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile), terminated: true });
287
+ await sendNotify('task.terminated', `${flags.agent} | ${flags.taskId} terminated`, msg, flags);
288
+ (0, state_1.deleteState)(stateFile);
289
+ console.log(`⚠️ Terminated: ${flags.agent} | ${flags.taskId}`);
290
+ break;
291
+ }
292
+ case 'task.complete': {
293
+ const pos = positionalArgs(rest);
294
+ const msg = pos[0] ?? '';
295
+ const flags = parseFlags(rest);
296
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
297
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile) });
298
+ await sendNotify('task.completed', `${flags.agent} | ${flags.taskId} workflow`, msg, flags);
299
+ (0, state_1.deleteState)(stateFile);
300
+ console.log(`✅ Completed: ${flags.agent} | ${flags.taskId}`);
301
+ break;
302
+ }
303
+ case 'set.metrics': {
304
+ const pos = positionalArgs(rest);
305
+ const flags = parseFlags(rest);
306
+ const prompt = parseInt(pos[0] ?? '0') || 0;
307
+ const completion = parseInt(pos[1] ?? '0') || 0;
308
+ const conf = parseFloat(pos[2] ?? '0') || 0;
309
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
310
+ (0, state_1.updateState)(stateFile, { prompt_tokens: prompt, completion_tokens: completion });
311
+ if (conf)
312
+ flags.confidenceScore = conf;
313
+ console.log(`📊 Metrics set: tokens(${prompt}/${completion}) confidence(${conf})`);
314
+ break;
315
+ }
316
+ case 'ai.response.generate': {
317
+ const pos = positionalArgs(rest);
318
+ const msg = pos[0] ?? '';
319
+ const flags = parseFlags(rest);
320
+ await sendNotify('ai.response.generated', `${flags.agent} | ${flags.taskId} response`, msg, flags);
321
+ break;
322
+ }
323
+ case 'ai.response.fail': {
324
+ const pos = positionalArgs(rest);
325
+ const msg = pos[0] ?? '';
326
+ const flags = parseFlags(rest);
327
+ await sendNotify('ai.response.failed', `${flags.agent} | ${flags.taskId} response failed`, msg, flags);
328
+ break;
329
+ }
330
+ case 'input.required': {
331
+ const pos = positionalArgs(rest);
332
+ const msg = pos[0] ?? '';
333
+ const flags = parseFlags(rest);
334
+ await sendNotify('input.required', `${flags.agent} | ${flags.taskId} input required`, msg, flags);
335
+ break;
336
+ }
337
+ case 'input.approve': {
338
+ const pos = positionalArgs(rest);
339
+ const msg = pos[0] ?? '';
340
+ const flags = parseFlags(rest);
341
+ await sendNotify('input.approved', `${flags.agent} | ${flags.taskId} input approved`, msg, flags);
342
+ break;
343
+ }
344
+ case 'input.reject': {
345
+ const pos = positionalArgs(rest);
346
+ const msg = pos[0] ?? '';
347
+ const flags = parseFlags(rest);
348
+ await sendNotify('input.rejected', `${flags.agent} | ${flags.taskId} input rejected`, msg, flags);
349
+ break;
350
+ }
351
+ case 'emit': {
352
+ const pos = positionalArgs(rest);
353
+ const event = pos[0] ?? '';
354
+ const msg = pos[1] ?? '';
355
+ const flags = parseFlags(rest.slice(2));
356
+ const stateFile = (0, state_1.getStateFile)(flags.agent, flags.taskId);
357
+ (0, state_1.updateState)(stateFile, { duration_ms: calcDuration(stateFile) });
358
+ await sendNotify(event, `${flags.agent} | ${flags.taskId} ${event}`, msg, flags);
359
+ console.log(`📡 Event emitted: ${event}`);
360
+ break;
361
+ }
362
+ case 'version':
363
+ console.log(`NotiLens v${VERSION}`);
364
+ break;
365
+ default:
366
+ printUsage();
367
+ }
368
+ }
369
+ function printUsage() {
370
+ console.log(`Usage:
371
+ notilens add-agent <agent> <transport> <endpoint> <secret>
372
+
373
+ Core Commands:
374
+ notilens task.start --agent <agent> [--task <id>]
375
+ notilens task.in_progress --agent <agent> [--task <id>]
376
+ notilens task.stop --agent <agent> [--task <id>]
377
+ notilens task.retry --agent <agent> [--task <id>]
378
+ notilens task.loop "msg" --agent <agent>
379
+ notilens task.error "msg" --agent <agent> [--task <id>]
380
+ notilens task.fail "msg" --agent <agent> [--task <id>]
381
+ notilens task.timeout "msg" --agent <agent> [--task <id>]
382
+ notilens task.cancel "msg" --agent <agent> [--task <id>]
383
+ notilens task.terminate "msg" --agent <agent> [--task <id>]
384
+ notilens task.complete "msg" --agent <agent> [--task <id>]
385
+ notilens ai.response.generate "msg" --agent <agent>
386
+ notilens ai.response.fail "msg" --agent <agent>
387
+ notilens input.required "msg" --agent <agent>
388
+ notilens input.approve "msg" --agent <agent>
389
+ notilens input.reject "msg" --agent <agent>
390
+
391
+ Generic Event:
392
+ notilens emit <event> "msg" --agent <agent>
393
+
394
+ Metrics:
395
+ notilens set.metrics <prompt_tokens> <completion_tokens> [confidence] --agent <agent> [--task <id>]
396
+
397
+ Options:
398
+ --agent <agent>
399
+ --task <id>
400
+ --type success|warning|urgent|important|info
401
+ --meta key=value (repeatable)
402
+ --image_url <url>
403
+ --open_url <url>
404
+ --download_url <url>
405
+ --tags "tag1,tag2"
406
+ --is_actionable true|false
407
+ --confidence <0-100>
408
+
409
+ Other:
410
+ notilens version`);
411
+ }
412
+ main().catch(err => {
413
+ console.error(err.message);
414
+ process.exit(1);
415
+ });
416
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,6 @@
1
+ import { AgentConfig, NotiLensConfig } from './types';
2
+ export declare function readConfig(): NotiLensConfig;
3
+ export declare function writeConfig(config: NotiLensConfig): void;
4
+ export declare function getAgentConfig(agent: string): AgentConfig | null;
5
+ export declare function addAgent(agent: string, transport: string, endpoint: string, secret: string): void;
6
+ //# sourceMappingURL=config.d.ts.map
package/dist/config.js ADDED
@@ -0,0 +1,66 @@
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.readConfig = readConfig;
37
+ exports.writeConfig = writeConfig;
38
+ exports.getAgentConfig = getAgentConfig;
39
+ exports.addAgent = addAgent;
40
+ const fs = __importStar(require("fs"));
41
+ const os = __importStar(require("os"));
42
+ const path = __importStar(require("path"));
43
+ const CONFIG_FILE = path.join(os.homedir(), '.notilens_config.json');
44
+ function readConfig() {
45
+ if (!fs.existsSync(CONFIG_FILE))
46
+ return {};
47
+ try {
48
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
49
+ }
50
+ catch {
51
+ return {};
52
+ }
53
+ }
54
+ function writeConfig(config) {
55
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
56
+ }
57
+ function getAgentConfig(agent) {
58
+ const config = readConfig();
59
+ return config[agent] || null;
60
+ }
61
+ function addAgent(agent, transport, endpoint, secret) {
62
+ const config = readConfig();
63
+ config[agent] = { transport, endpoint, secret };
64
+ writeConfig(config);
65
+ }
66
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,3 @@
1
+ import { NotifyPayload } from './types';
2
+ export declare function sendNotification(endpoint: string, secret: string, payload: NotifyPayload): Promise<void>;
3
+ //# sourceMappingURL=notify.d.ts.map
package/dist/notify.js ADDED
@@ -0,0 +1,91 @@
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.sendNotification = sendNotification;
37
+ const https = __importStar(require("https"));
38
+ const http = __importStar(require("http"));
39
+ const VERSION = require('../package.json').version;
40
+ const MAX_RETRIES = 2;
41
+ const TIMEOUT_MS = 10000;
42
+ async function attempt(endpoint, secret, body) {
43
+ return new Promise((resolve, reject) => {
44
+ const url = new URL(endpoint);
45
+ const lib = url.protocol === 'https:' ? https : http;
46
+ const options = {
47
+ hostname: url.hostname,
48
+ port: url.port || (url.protocol === 'https:' ? 443 : 80),
49
+ path: url.pathname + url.search,
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ 'X-NOTILENS-KEY': secret,
54
+ 'User-Agent': `NotiLens-CLI/${VERSION}`,
55
+ 'Content-Length': Buffer.byteLength(body),
56
+ },
57
+ };
58
+ const req = lib.request(options, (res) => {
59
+ res.resume();
60
+ resolve();
61
+ });
62
+ const timer = setTimeout(() => {
63
+ req.destroy(new Error('Request timeout'));
64
+ }, TIMEOUT_MS);
65
+ req.on('error', (err) => {
66
+ clearTimeout(timer);
67
+ reject(err);
68
+ });
69
+ req.on('close', () => clearTimeout(timer));
70
+ req.write(body);
71
+ req.end();
72
+ });
73
+ }
74
+ async function sendNotification(endpoint, secret, payload) {
75
+ const body = JSON.stringify(payload);
76
+ let lastErr;
77
+ for (let i = 0; i <= MAX_RETRIES; i++) {
78
+ try {
79
+ await attempt(endpoint, secret, body);
80
+ return;
81
+ }
82
+ catch (err) {
83
+ lastErr = err;
84
+ if (i < MAX_RETRIES) {
85
+ await new Promise(r => setTimeout(r, 1000)); // 1s retry delay
86
+ }
87
+ }
88
+ }
89
+ throw lastErr;
90
+ }
91
+ //# sourceMappingURL=notify.js.map
@@ -0,0 +1,7 @@
1
+ import { TaskState } from './types';
2
+ export declare function getStateFile(agent: string, taskId: string): string;
3
+ export declare function readState(stateFile: string): TaskState;
4
+ export declare function writeState(stateFile: string, state: TaskState): void;
5
+ export declare function updateState(stateFile: string, updates: Partial<TaskState>): void;
6
+ export declare function deleteState(stateFile: string): void;
7
+ //# sourceMappingURL=state.d.ts.map
package/dist/state.js ADDED
@@ -0,0 +1,70 @@
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.getStateFile = getStateFile;
37
+ exports.readState = readState;
38
+ exports.writeState = writeState;
39
+ exports.updateState = updateState;
40
+ exports.deleteState = deleteState;
41
+ const fs = __importStar(require("fs"));
42
+ const os = __importStar(require("os"));
43
+ const path = __importStar(require("path"));
44
+ function getStateFile(agent, taskId) {
45
+ const user = os.userInfo().username;
46
+ return path.join(os.tmpdir(), `notilens_${user}_${agent}_${taskId}.json`);
47
+ }
48
+ function readState(stateFile) {
49
+ if (!fs.existsSync(stateFile))
50
+ return {};
51
+ try {
52
+ return JSON.parse(fs.readFileSync(stateFile, 'utf-8'));
53
+ }
54
+ catch {
55
+ return {};
56
+ }
57
+ }
58
+ function writeState(stateFile, state) {
59
+ fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
60
+ }
61
+ function updateState(stateFile, updates) {
62
+ const state = readState(stateFile);
63
+ writeState(stateFile, { ...state, ...updates });
64
+ }
65
+ function deleteState(stateFile) {
66
+ if (fs.existsSync(stateFile)) {
67
+ fs.unlinkSync(stateFile);
68
+ }
69
+ }
70
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1,51 @@
1
+ export interface AgentConfig {
2
+ transport: string;
3
+ endpoint: string;
4
+ secret: string;
5
+ }
6
+ export interface NotiLensConfig {
7
+ [agent: string]: AgentConfig;
8
+ }
9
+ export interface TaskState {
10
+ agent?: string;
11
+ task?: string;
12
+ start_time?: number;
13
+ retry_count?: number;
14
+ loop_count?: number;
15
+ duration_ms?: number;
16
+ prompt_tokens?: number;
17
+ completion_tokens?: number;
18
+ last_error?: string;
19
+ failed?: boolean;
20
+ timeout?: boolean;
21
+ cancelled?: boolean;
22
+ terminated?: boolean;
23
+ }
24
+ export interface NotifyPayload {
25
+ event: string;
26
+ title: string;
27
+ message: string;
28
+ type: string;
29
+ agent: string;
30
+ task_id: string;
31
+ meta: Record<string, unknown>;
32
+ image_url: string;
33
+ open_url: string;
34
+ download_url: string;
35
+ tags: string;
36
+ is_actionable: boolean;
37
+ }
38
+ export type NotificationType = 'info' | 'success' | 'warning' | 'urgent' | 'important';
39
+ export interface ParsedFlags {
40
+ agent: string;
41
+ taskId: string;
42
+ type: string;
43
+ meta: Record<string, string>;
44
+ imageUrl: string;
45
+ openUrl: string;
46
+ downloadUrl: string;
47
+ tags: string;
48
+ isActionable: string;
49
+ confidenceScore: number;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@notilens/notilens",
3
+ "version": "0.1.0",
4
+ "description": "NotiLens CLI — send AI agent task lifecycle notifications",
5
+ "keywords": ["notilens", "ai-agent", "notifications", "monitoring", "cli"],
6
+ "homepage": "https://www.notilens.com",
7
+ "author": "NotiLens",
8
+ "license": "MIT",
9
+ "main": "dist/cli.js",
10
+ "bin": {
11
+ "notilens": "dist/cli.js"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "prepublishOnly": "npm run build",
16
+ "dev": "ts-node src/cli.ts"
17
+ },
18
+ "engines": {
19
+ "node": ">=18.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.0.0",
23
+ "typescript": "^5.0.0"
24
+ }
25
+ }