network-ai 4.2.0 → 4.3.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/README.md +4 -3
- package/bin/cli.ts +299 -0
- package/dist/bin/cli.d.ts +11 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +326 -0
- package/dist/bin/cli.js.map +1 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/ci.yml)
|
|
6
6
|
[](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/codeql.yml)
|
|
7
|
-
[](https://github.com/jovanSAPFIONEER/Network-AI/releases)
|
|
8
8
|
[](https://www.npmjs.com/package/network-ai)
|
|
9
|
-
[](#testing)
|
|
10
|
+
[](#adapter-system)
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
[](https://socket.dev/npm/package/network-ai/overview)
|
|
13
13
|
[](https://nodejs.org)
|
|
14
14
|
[](https://typescriptlang.org)
|
|
15
15
|
[](https://clawhub.ai/skills/network-ai)
|
|
16
16
|
[](INTEGRATION_GUIDE.md)
|
|
17
|
+
[](https://glama.ai/mcp/servers/@jovanSAPFIONEER/network-ai)
|
|
17
18
|
|
|
18
19
|
Network-AI is a TypeScript/Node.js multi-agent orchestrator that adds coordination, guardrails, and governance to any AI agent stack.
|
|
19
20
|
|
package/bin/cli.ts
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* network-ai CLI — full in-process control over blackboard, auth, budget, and audit.
|
|
4
|
+
* Imports core classes directly (Option B: no server required).
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx network-ai <command> [options]
|
|
8
|
+
* network-ai <command> [options] (after npm install -g network-ai)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Command, Option } from 'commander';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import * as readline from 'readline';
|
|
15
|
+
|
|
16
|
+
import { LockedBlackboard } from '../lib/locked-blackboard';
|
|
17
|
+
import { AuthGuardian } from '../index';
|
|
18
|
+
import { FederatedBudget } from '../lib/federated-budget';
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
|
+
const pkg = require('../package.json') as { version: string; name: string };
|
|
22
|
+
|
|
23
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
function resolveData(opts: { data?: string }): string {
|
|
26
|
+
return path.resolve(opts.data ?? path.join(process.cwd(), 'data'));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function print(obj: unknown, asJson: boolean): void {
|
|
30
|
+
if (asJson) {
|
|
31
|
+
console.log(JSON.stringify(obj, null, 2));
|
|
32
|
+
} else if (typeof obj === 'string') {
|
|
33
|
+
console.log(obj);
|
|
34
|
+
} else {
|
|
35
|
+
console.log(JSON.stringify(obj, null, 2));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function die(msg: string): never {
|
|
40
|
+
console.error(`error: ${msg}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function tryParseJson(v: string): unknown {
|
|
45
|
+
try { return JSON.parse(v); } catch { return v; }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ── root program ──────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
const program = new Command();
|
|
51
|
+
|
|
52
|
+
program
|
|
53
|
+
.name('network-ai')
|
|
54
|
+
.description('Network-AI CLI — full control over blackboard, auth, budget, and audit')
|
|
55
|
+
.version(pkg.version, '-v, --version')
|
|
56
|
+
.enablePositionalOptions()
|
|
57
|
+
.addOption(new Option('--data <path>', 'path to data directory').default('./data'))
|
|
58
|
+
.addOption(new Option('--json', 'output raw JSON (useful for piping)'));
|
|
59
|
+
|
|
60
|
+
// ── bb (blackboard) ───────────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
const bb = program.command('bb').description('Blackboard operations');
|
|
63
|
+
|
|
64
|
+
bb.command('get <key>')
|
|
65
|
+
.description('Read a value from the blackboard')
|
|
66
|
+
.action((key: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
67
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
68
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
69
|
+
const entry = board.read(key);
|
|
70
|
+
if (!entry) die(`key not found: ${key}`);
|
|
71
|
+
print(g.json ? entry : entry.value, g.json);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
bb.command('set <key> <value>')
|
|
75
|
+
.description('Write a value to the blackboard')
|
|
76
|
+
.option('--agent <id>', 'source agent id', 'cli')
|
|
77
|
+
.option('--ttl <seconds>', 'TTL in seconds', (v) => parseInt(v, 10))
|
|
78
|
+
.action((key: string, value: string, opts: { agent: string; ttl?: number }, cmd: Command) => {
|
|
79
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
80
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
81
|
+
const entry = board.write(key, tryParseJson(value), opts.agent, opts.ttl);
|
|
82
|
+
print(g.json ? entry : `✓ set ${key}`, g.json);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
bb.command('delete <key>')
|
|
86
|
+
.description('Delete a key from the blackboard')
|
|
87
|
+
.action((key: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
88
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
89
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
90
|
+
const ok = board.delete(key);
|
|
91
|
+
if (!ok) die(`key not found: ${key}`);
|
|
92
|
+
print(g.json ? { deleted: key } : `✓ deleted ${key}`, g.json);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
bb.command('list')
|
|
96
|
+
.description('List all keys on the blackboard')
|
|
97
|
+
.action((_opts: Record<string, unknown>, cmd: Command) => {
|
|
98
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
99
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
100
|
+
const keys = board.listKeys();
|
|
101
|
+
print(g.json ? keys : keys.length ? keys.join('\n') : '(empty)', g.json);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
bb.command('snapshot')
|
|
105
|
+
.description('Dump full blackboard state as JSON')
|
|
106
|
+
.action((_opts: Record<string, unknown>, cmd: Command) => {
|
|
107
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
108
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
109
|
+
const snap: Record<string, unknown> = {};
|
|
110
|
+
for (const key of board.listKeys()) snap[key] = board.read(key);
|
|
111
|
+
console.log(JSON.stringify(snap, null, 2));
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
bb.command('propose <key> <value>')
|
|
115
|
+
.description('Propose a change and get back a change-id')
|
|
116
|
+
.option('--agent <id>', 'source agent id', 'cli')
|
|
117
|
+
.option('--ttl <seconds>', 'TTL in seconds', (v) => parseInt(v, 10))
|
|
118
|
+
.option('--priority <0-3>', 'priority: 0=low 1=normal 2=high 3=critical', (v) => parseInt(v, 10) as 0 | 1 | 2 | 3)
|
|
119
|
+
.action((key: string, value: string, opts: { agent: string; ttl?: number; priority?: 0 | 1 | 2 | 3 }, cmd: Command) => {
|
|
120
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
121
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
122
|
+
const changeId = board.propose(key, tryParseJson(value), opts.agent, opts.ttl, opts.priority);
|
|
123
|
+
print(g.json ? { changeId } : `change-id: ${changeId}`, g.json);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
bb.command('commit <changeId>')
|
|
127
|
+
.description('Validate and commit a proposed change')
|
|
128
|
+
.option('--agent <id>', 'validator agent id', 'cli')
|
|
129
|
+
.action((changeId: string, opts: { agent: string }, cmd: Command) => {
|
|
130
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
131
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
132
|
+
const valid = board.validate(changeId, opts.agent);
|
|
133
|
+
if (!valid) die(`change ${changeId} has conflicts — run 'bb abort' to cancel`);
|
|
134
|
+
const result = board.commit(changeId);
|
|
135
|
+
if (!result.success) die(`commit failed: ${result.message}`);
|
|
136
|
+
print(g.json ? result : `✓ committed ${changeId}: ${result.message}`, g.json);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
bb.command('abort <changeId>')
|
|
140
|
+
.description('Abort a pending proposed change')
|
|
141
|
+
.action((changeId: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
142
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
143
|
+
const board = new LockedBlackboard(resolveData(g));
|
|
144
|
+
const ok = board.abort(changeId);
|
|
145
|
+
if (!ok) die(`change not found: ${changeId}`);
|
|
146
|
+
print(g.json ? { aborted: changeId } : `✓ aborted ${changeId}`, g.json);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// ── auth ──────────────────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
const auth = program.command('auth').description('Permission and token operations');
|
|
152
|
+
|
|
153
|
+
auth.command('token <agentId>')
|
|
154
|
+
.description('Issue a permission token for an agent')
|
|
155
|
+
.option('--resource <type>', 'resource type to grant', 'blackboard')
|
|
156
|
+
.option('--justification <text>', 'justification text', 'CLI-issued token')
|
|
157
|
+
.option('--scope <scope>', 'permission scope')
|
|
158
|
+
.action(async (agentId: string, opts: { resource: string; justification: string; scope?: string }, cmd: Command) => {
|
|
159
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
160
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
161
|
+
const guardian = new AuthGuardian({ auditLogPath: auditPath });
|
|
162
|
+
guardian.registerAgentTrust({ agentId, trustLevel: 1, allowedResources: [opts.resource] });
|
|
163
|
+
const grant = await guardian.requestPermission(agentId, opts.resource, opts.justification, opts.scope);
|
|
164
|
+
if (g.json) {
|
|
165
|
+
print(grant, true);
|
|
166
|
+
} else {
|
|
167
|
+
console.log(`token: ${grant.grantToken ?? '(none)'}`);
|
|
168
|
+
console.log(`granted: ${grant.granted}`);
|
|
169
|
+
console.log(`expires: ${grant.expiresAt ?? 'never'}`);
|
|
170
|
+
if (!grant.granted && grant.reason) console.log(`reason: ${grant.reason}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
auth.command('revoke <token>')
|
|
175
|
+
.description('Revoke a permission token')
|
|
176
|
+
.action((token: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
177
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
178
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
179
|
+
const guardian = new AuthGuardian({ auditLogPath: auditPath });
|
|
180
|
+
guardian.revokeToken(token);
|
|
181
|
+
print(g.json ? { revoked: token } : `✓ revoked`, g.json);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
auth.command('check <token> <permission>')
|
|
185
|
+
.description('Check if a token grants a permission (exits 0=yes, 1=no)')
|
|
186
|
+
.action((token: string, permission: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
187
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
188
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
189
|
+
const guardian = new AuthGuardian({ auditLogPath: auditPath });
|
|
190
|
+
const valid = guardian.validateToken(token);
|
|
191
|
+
const violation = valid ? guardian.enforceRestrictions(token, { type: permission }) : 'invalid or expired token';
|
|
192
|
+
const allowed = valid && violation === null;
|
|
193
|
+
print(
|
|
194
|
+
g.json ? { allowed, permission, reason: violation ?? null } : (allowed ? `✓ allowed` : `✗ denied: ${violation}`),
|
|
195
|
+
g.json,
|
|
196
|
+
);
|
|
197
|
+
process.exit(allowed ? 0 : 1);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// ── budget ────────────────────────────────────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
const budgetCmd = program.command('budget').description('Token budget operations');
|
|
203
|
+
|
|
204
|
+
budgetCmd.command('status [agentId]')
|
|
205
|
+
.description('Show token budget status')
|
|
206
|
+
.option('--ceiling <n>', 'total token ceiling', (v) => parseInt(v, 10))
|
|
207
|
+
.action((agentId: string | undefined, opts: { ceiling?: number }, cmd: Command) => {
|
|
208
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
209
|
+
const ceiling = opts.ceiling ?? 100_000;
|
|
210
|
+
const fed = new FederatedBudget({ ceiling });
|
|
211
|
+
if (agentId) {
|
|
212
|
+
const spent = fed.getAgentSpent(agentId);
|
|
213
|
+
const snap = { agentId, spent, remaining: fed.remaining(), ceiling: fed.getCeiling() };
|
|
214
|
+
print(g.json ? snap : `agent: ${agentId}\nspent: ${snap.spent}\nremaining: ${snap.remaining}\nceiling: ${snap.ceiling}`, g.json);
|
|
215
|
+
} else {
|
|
216
|
+
const snap = { totalSpent: fed.getTotalSpent(), remaining: fed.remaining(), ceiling: fed.getCeiling(), byAgent: fed.getSpendLog() };
|
|
217
|
+
print(g.json ? snap : `total-spent: ${snap.totalSpent}\nremaining: ${snap.remaining}\nceiling: ${snap.ceiling}`, g.json);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
budgetCmd.command('set-ceiling <amount>')
|
|
222
|
+
.description('Update the token ceiling')
|
|
223
|
+
.action((amount: string, _opts: Record<string, unknown>, cmd: Command) => {
|
|
224
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
225
|
+
const n = parseInt(amount, 10);
|
|
226
|
+
if (isNaN(n) || n <= 0) die('amount must be a positive integer');
|
|
227
|
+
const fed = new FederatedBudget({ ceiling: n });
|
|
228
|
+
fed.setCeiling(n);
|
|
229
|
+
print(g.json ? { ceiling: n } : `✓ ceiling set to ${n}`, g.json);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ── audit ─────────────────────────────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
const auditCmd = program.command('audit').description('Audit log operations');
|
|
235
|
+
|
|
236
|
+
function getAuditLogPath(dataDir: string): string {
|
|
237
|
+
return path.join(dataDir, 'audit_log.jsonl');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
auditCmd.command('log')
|
|
241
|
+
.description('Print audit log entries')
|
|
242
|
+
.option('--limit <n>', 'show last N entries', (v) => parseInt(v, 10))
|
|
243
|
+
.action((opts: { limit?: number }, cmd: Command) => {
|
|
244
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
245
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
246
|
+
if (!fs.existsSync(logFile)) die(`audit log not found: ${logFile}`);
|
|
247
|
+
const lines = fs.readFileSync(logFile, 'utf-8').trim().split('\n').filter(Boolean);
|
|
248
|
+
const slice = opts.limit ? lines.slice(-opts.limit) : lines;
|
|
249
|
+
if (g.json) {
|
|
250
|
+
console.log(JSON.stringify(slice.map(l => { try { return JSON.parse(l); } catch { return l; } }), null, 2));
|
|
251
|
+
} else {
|
|
252
|
+
if (slice.length === 0) { console.log('(no entries)'); return; }
|
|
253
|
+
slice.forEach(l => console.log(l));
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
auditCmd.command('tail')
|
|
258
|
+
.description('Live-stream new audit log entries (Ctrl+C to stop)')
|
|
259
|
+
.action((_opts: Record<string, unknown>, cmd: Command) => {
|
|
260
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
261
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
262
|
+
if (!fs.existsSync(logFile)) die(`audit log not found: ${logFile}`);
|
|
263
|
+
let size = fs.statSync(logFile).size;
|
|
264
|
+
console.log(`tailing ${logFile} — Ctrl+C to stop`);
|
|
265
|
+
const interval = setInterval(() => {
|
|
266
|
+
try {
|
|
267
|
+
const newSize = fs.statSync(logFile).size;
|
|
268
|
+
if (newSize > size) {
|
|
269
|
+
const fd = fs.openSync(logFile, 'r');
|
|
270
|
+
const buf = Buffer.alloc(newSize - size);
|
|
271
|
+
fs.readSync(fd, buf, 0, buf.length, size);
|
|
272
|
+
fs.closeSync(fd);
|
|
273
|
+
buf.toString('utf-8').trim().split('\n').filter(Boolean).forEach(l => console.log(l));
|
|
274
|
+
size = newSize;
|
|
275
|
+
}
|
|
276
|
+
} catch { /* file may be briefly locked */ }
|
|
277
|
+
}, 500);
|
|
278
|
+
process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
auditCmd.command('clear')
|
|
282
|
+
.description('Clear the audit log (prompts for confirmation)')
|
|
283
|
+
.option('--yes', 'skip confirmation prompt')
|
|
284
|
+
.action(async (opts: { yes?: boolean }, cmd: Command) => {
|
|
285
|
+
const g = cmd.optsWithGlobals<{ data: string; json: boolean }>();
|
|
286
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
287
|
+
if (!opts.yes) {
|
|
288
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
289
|
+
const answer = await new Promise<string>(r => rl.question(`Clear ${logFile}? [y/N] `, r));
|
|
290
|
+
rl.close();
|
|
291
|
+
if (answer.toLowerCase() !== 'y') { console.log('Aborted.'); return; }
|
|
292
|
+
}
|
|
293
|
+
fs.writeFileSync(logFile, '');
|
|
294
|
+
print(g.json ? { cleared: logFile } : `✓ cleared ${logFile}`, g.json);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// ── parse ─────────────────────────────────────────────────────────────────────
|
|
298
|
+
|
|
299
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* network-ai CLI — full in-process control over blackboard, auth, budget, and audit.
|
|
4
|
+
* Imports core classes directly (Option B: no server required).
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx network-ai <command> [options]
|
|
8
|
+
* network-ai <command> [options] (after npm install -g network-ai)
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* network-ai CLI — full in-process control over blackboard, auth, budget, and audit.
|
|
5
|
+
* Imports core classes directly (Option B: no server required).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx network-ai <command> [options]
|
|
9
|
+
* network-ai <command> [options] (after npm install -g network-ai)
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const commander_1 = require("commander");
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const readline = __importStar(require("readline"));
|
|
49
|
+
const locked_blackboard_1 = require("../lib/locked-blackboard");
|
|
50
|
+
const index_1 = require("../index");
|
|
51
|
+
const federated_budget_1 = require("../lib/federated-budget");
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
53
|
+
const pkg = require('../package.json');
|
|
54
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
55
|
+
function resolveData(opts) {
|
|
56
|
+
return path.resolve(opts.data ?? path.join(process.cwd(), 'data'));
|
|
57
|
+
}
|
|
58
|
+
function print(obj, asJson) {
|
|
59
|
+
if (asJson) {
|
|
60
|
+
console.log(JSON.stringify(obj, null, 2));
|
|
61
|
+
}
|
|
62
|
+
else if (typeof obj === 'string') {
|
|
63
|
+
console.log(obj);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log(JSON.stringify(obj, null, 2));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function die(msg) {
|
|
70
|
+
console.error(`error: ${msg}`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
function tryParseJson(v) {
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(v);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return v;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ── root program ──────────────────────────────────────────────────────────────
|
|
82
|
+
const program = new commander_1.Command();
|
|
83
|
+
program
|
|
84
|
+
.name('network-ai')
|
|
85
|
+
.description('Network-AI CLI — full control over blackboard, auth, budget, and audit')
|
|
86
|
+
.version(pkg.version, '-v, --version')
|
|
87
|
+
.enablePositionalOptions()
|
|
88
|
+
.addOption(new commander_1.Option('--data <path>', 'path to data directory').default('./data'))
|
|
89
|
+
.addOption(new commander_1.Option('--json', 'output raw JSON (useful for piping)'));
|
|
90
|
+
// ── bb (blackboard) ───────────────────────────────────────────────────────────
|
|
91
|
+
const bb = program.command('bb').description('Blackboard operations');
|
|
92
|
+
bb.command('get <key>')
|
|
93
|
+
.description('Read a value from the blackboard')
|
|
94
|
+
.action((key, _opts, cmd) => {
|
|
95
|
+
const g = cmd.optsWithGlobals();
|
|
96
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
97
|
+
const entry = board.read(key);
|
|
98
|
+
if (!entry)
|
|
99
|
+
die(`key not found: ${key}`);
|
|
100
|
+
print(g.json ? entry : entry.value, g.json);
|
|
101
|
+
});
|
|
102
|
+
bb.command('set <key> <value>')
|
|
103
|
+
.description('Write a value to the blackboard')
|
|
104
|
+
.option('--agent <id>', 'source agent id', 'cli')
|
|
105
|
+
.option('--ttl <seconds>', 'TTL in seconds', (v) => parseInt(v, 10))
|
|
106
|
+
.action((key, value, opts, cmd) => {
|
|
107
|
+
const g = cmd.optsWithGlobals();
|
|
108
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
109
|
+
const entry = board.write(key, tryParseJson(value), opts.agent, opts.ttl);
|
|
110
|
+
print(g.json ? entry : `✓ set ${key}`, g.json);
|
|
111
|
+
});
|
|
112
|
+
bb.command('delete <key>')
|
|
113
|
+
.description('Delete a key from the blackboard')
|
|
114
|
+
.action((key, _opts, cmd) => {
|
|
115
|
+
const g = cmd.optsWithGlobals();
|
|
116
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
117
|
+
const ok = board.delete(key);
|
|
118
|
+
if (!ok)
|
|
119
|
+
die(`key not found: ${key}`);
|
|
120
|
+
print(g.json ? { deleted: key } : `✓ deleted ${key}`, g.json);
|
|
121
|
+
});
|
|
122
|
+
bb.command('list')
|
|
123
|
+
.description('List all keys on the blackboard')
|
|
124
|
+
.action((_opts, cmd) => {
|
|
125
|
+
const g = cmd.optsWithGlobals();
|
|
126
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
127
|
+
const keys = board.listKeys();
|
|
128
|
+
print(g.json ? keys : keys.length ? keys.join('\n') : '(empty)', g.json);
|
|
129
|
+
});
|
|
130
|
+
bb.command('snapshot')
|
|
131
|
+
.description('Dump full blackboard state as JSON')
|
|
132
|
+
.action((_opts, cmd) => {
|
|
133
|
+
const g = cmd.optsWithGlobals();
|
|
134
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
135
|
+
const snap = {};
|
|
136
|
+
for (const key of board.listKeys())
|
|
137
|
+
snap[key] = board.read(key);
|
|
138
|
+
console.log(JSON.stringify(snap, null, 2));
|
|
139
|
+
});
|
|
140
|
+
bb.command('propose <key> <value>')
|
|
141
|
+
.description('Propose a change and get back a change-id')
|
|
142
|
+
.option('--agent <id>', 'source agent id', 'cli')
|
|
143
|
+
.option('--ttl <seconds>', 'TTL in seconds', (v) => parseInt(v, 10))
|
|
144
|
+
.option('--priority <0-3>', 'priority: 0=low 1=normal 2=high 3=critical', (v) => parseInt(v, 10))
|
|
145
|
+
.action((key, value, opts, cmd) => {
|
|
146
|
+
const g = cmd.optsWithGlobals();
|
|
147
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
148
|
+
const changeId = board.propose(key, tryParseJson(value), opts.agent, opts.ttl, opts.priority);
|
|
149
|
+
print(g.json ? { changeId } : `change-id: ${changeId}`, g.json);
|
|
150
|
+
});
|
|
151
|
+
bb.command('commit <changeId>')
|
|
152
|
+
.description('Validate and commit a proposed change')
|
|
153
|
+
.option('--agent <id>', 'validator agent id', 'cli')
|
|
154
|
+
.action((changeId, opts, cmd) => {
|
|
155
|
+
const g = cmd.optsWithGlobals();
|
|
156
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
157
|
+
const valid = board.validate(changeId, opts.agent);
|
|
158
|
+
if (!valid)
|
|
159
|
+
die(`change ${changeId} has conflicts — run 'bb abort' to cancel`);
|
|
160
|
+
const result = board.commit(changeId);
|
|
161
|
+
if (!result.success)
|
|
162
|
+
die(`commit failed: ${result.message}`);
|
|
163
|
+
print(g.json ? result : `✓ committed ${changeId}: ${result.message}`, g.json);
|
|
164
|
+
});
|
|
165
|
+
bb.command('abort <changeId>')
|
|
166
|
+
.description('Abort a pending proposed change')
|
|
167
|
+
.action((changeId, _opts, cmd) => {
|
|
168
|
+
const g = cmd.optsWithGlobals();
|
|
169
|
+
const board = new locked_blackboard_1.LockedBlackboard(resolveData(g));
|
|
170
|
+
const ok = board.abort(changeId);
|
|
171
|
+
if (!ok)
|
|
172
|
+
die(`change not found: ${changeId}`);
|
|
173
|
+
print(g.json ? { aborted: changeId } : `✓ aborted ${changeId}`, g.json);
|
|
174
|
+
});
|
|
175
|
+
// ── auth ──────────────────────────────────────────────────────────────────────
|
|
176
|
+
const auth = program.command('auth').description('Permission and token operations');
|
|
177
|
+
auth.command('token <agentId>')
|
|
178
|
+
.description('Issue a permission token for an agent')
|
|
179
|
+
.option('--resource <type>', 'resource type to grant', 'blackboard')
|
|
180
|
+
.option('--justification <text>', 'justification text', 'CLI-issued token')
|
|
181
|
+
.option('--scope <scope>', 'permission scope')
|
|
182
|
+
.action(async (agentId, opts, cmd) => {
|
|
183
|
+
const g = cmd.optsWithGlobals();
|
|
184
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
185
|
+
const guardian = new index_1.AuthGuardian({ auditLogPath: auditPath });
|
|
186
|
+
guardian.registerAgentTrust({ agentId, trustLevel: 1, allowedResources: [opts.resource] });
|
|
187
|
+
const grant = await guardian.requestPermission(agentId, opts.resource, opts.justification, opts.scope);
|
|
188
|
+
if (g.json) {
|
|
189
|
+
print(grant, true);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log(`token: ${grant.grantToken ?? '(none)'}`);
|
|
193
|
+
console.log(`granted: ${grant.granted}`);
|
|
194
|
+
console.log(`expires: ${grant.expiresAt ?? 'never'}`);
|
|
195
|
+
if (!grant.granted && grant.reason)
|
|
196
|
+
console.log(`reason: ${grant.reason}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
auth.command('revoke <token>')
|
|
200
|
+
.description('Revoke a permission token')
|
|
201
|
+
.action((token, _opts, cmd) => {
|
|
202
|
+
const g = cmd.optsWithGlobals();
|
|
203
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
204
|
+
const guardian = new index_1.AuthGuardian({ auditLogPath: auditPath });
|
|
205
|
+
guardian.revokeToken(token);
|
|
206
|
+
print(g.json ? { revoked: token } : `✓ revoked`, g.json);
|
|
207
|
+
});
|
|
208
|
+
auth.command('check <token> <permission>')
|
|
209
|
+
.description('Check if a token grants a permission (exits 0=yes, 1=no)')
|
|
210
|
+
.action((token, permission, _opts, cmd) => {
|
|
211
|
+
const g = cmd.optsWithGlobals();
|
|
212
|
+
const auditPath = path.join(resolveData(g), 'audit_log.jsonl');
|
|
213
|
+
const guardian = new index_1.AuthGuardian({ auditLogPath: auditPath });
|
|
214
|
+
const valid = guardian.validateToken(token);
|
|
215
|
+
const violation = valid ? guardian.enforceRestrictions(token, { type: permission }) : 'invalid or expired token';
|
|
216
|
+
const allowed = valid && violation === null;
|
|
217
|
+
print(g.json ? { allowed, permission, reason: violation ?? null } : (allowed ? `✓ allowed` : `✗ denied: ${violation}`), g.json);
|
|
218
|
+
process.exit(allowed ? 0 : 1);
|
|
219
|
+
});
|
|
220
|
+
// ── budget ────────────────────────────────────────────────────────────────────
|
|
221
|
+
const budgetCmd = program.command('budget').description('Token budget operations');
|
|
222
|
+
budgetCmd.command('status [agentId]')
|
|
223
|
+
.description('Show token budget status')
|
|
224
|
+
.option('--ceiling <n>', 'total token ceiling', (v) => parseInt(v, 10))
|
|
225
|
+
.action((agentId, opts, cmd) => {
|
|
226
|
+
const g = cmd.optsWithGlobals();
|
|
227
|
+
const ceiling = opts.ceiling ?? 100_000;
|
|
228
|
+
const fed = new federated_budget_1.FederatedBudget({ ceiling });
|
|
229
|
+
if (agentId) {
|
|
230
|
+
const spent = fed.getAgentSpent(agentId);
|
|
231
|
+
const snap = { agentId, spent, remaining: fed.remaining(), ceiling: fed.getCeiling() };
|
|
232
|
+
print(g.json ? snap : `agent: ${agentId}\nspent: ${snap.spent}\nremaining: ${snap.remaining}\nceiling: ${snap.ceiling}`, g.json);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
const snap = { totalSpent: fed.getTotalSpent(), remaining: fed.remaining(), ceiling: fed.getCeiling(), byAgent: fed.getSpendLog() };
|
|
236
|
+
print(g.json ? snap : `total-spent: ${snap.totalSpent}\nremaining: ${snap.remaining}\nceiling: ${snap.ceiling}`, g.json);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
budgetCmd.command('set-ceiling <amount>')
|
|
240
|
+
.description('Update the token ceiling')
|
|
241
|
+
.action((amount, _opts, cmd) => {
|
|
242
|
+
const g = cmd.optsWithGlobals();
|
|
243
|
+
const n = parseInt(amount, 10);
|
|
244
|
+
if (isNaN(n) || n <= 0)
|
|
245
|
+
die('amount must be a positive integer');
|
|
246
|
+
const fed = new federated_budget_1.FederatedBudget({ ceiling: n });
|
|
247
|
+
fed.setCeiling(n);
|
|
248
|
+
print(g.json ? { ceiling: n } : `✓ ceiling set to ${n}`, g.json);
|
|
249
|
+
});
|
|
250
|
+
// ── audit ─────────────────────────────────────────────────────────────────────
|
|
251
|
+
const auditCmd = program.command('audit').description('Audit log operations');
|
|
252
|
+
function getAuditLogPath(dataDir) {
|
|
253
|
+
return path.join(dataDir, 'audit_log.jsonl');
|
|
254
|
+
}
|
|
255
|
+
auditCmd.command('log')
|
|
256
|
+
.description('Print audit log entries')
|
|
257
|
+
.option('--limit <n>', 'show last N entries', (v) => parseInt(v, 10))
|
|
258
|
+
.action((opts, cmd) => {
|
|
259
|
+
const g = cmd.optsWithGlobals();
|
|
260
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
261
|
+
if (!fs.existsSync(logFile))
|
|
262
|
+
die(`audit log not found: ${logFile}`);
|
|
263
|
+
const lines = fs.readFileSync(logFile, 'utf-8').trim().split('\n').filter(Boolean);
|
|
264
|
+
const slice = opts.limit ? lines.slice(-opts.limit) : lines;
|
|
265
|
+
if (g.json) {
|
|
266
|
+
console.log(JSON.stringify(slice.map(l => { try {
|
|
267
|
+
return JSON.parse(l);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return l;
|
|
271
|
+
} }), null, 2));
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
if (slice.length === 0) {
|
|
275
|
+
console.log('(no entries)');
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
slice.forEach(l => console.log(l));
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
auditCmd.command('tail')
|
|
282
|
+
.description('Live-stream new audit log entries (Ctrl+C to stop)')
|
|
283
|
+
.action((_opts, cmd) => {
|
|
284
|
+
const g = cmd.optsWithGlobals();
|
|
285
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
286
|
+
if (!fs.existsSync(logFile))
|
|
287
|
+
die(`audit log not found: ${logFile}`);
|
|
288
|
+
let size = fs.statSync(logFile).size;
|
|
289
|
+
console.log(`tailing ${logFile} — Ctrl+C to stop`);
|
|
290
|
+
const interval = setInterval(() => {
|
|
291
|
+
try {
|
|
292
|
+
const newSize = fs.statSync(logFile).size;
|
|
293
|
+
if (newSize > size) {
|
|
294
|
+
const fd = fs.openSync(logFile, 'r');
|
|
295
|
+
const buf = Buffer.alloc(newSize - size);
|
|
296
|
+
fs.readSync(fd, buf, 0, buf.length, size);
|
|
297
|
+
fs.closeSync(fd);
|
|
298
|
+
buf.toString('utf-8').trim().split('\n').filter(Boolean).forEach(l => console.log(l));
|
|
299
|
+
size = newSize;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
catch { /* file may be briefly locked */ }
|
|
303
|
+
}, 500);
|
|
304
|
+
process.on('SIGINT', () => { clearInterval(interval); process.exit(0); });
|
|
305
|
+
});
|
|
306
|
+
auditCmd.command('clear')
|
|
307
|
+
.description('Clear the audit log (prompts for confirmation)')
|
|
308
|
+
.option('--yes', 'skip confirmation prompt')
|
|
309
|
+
.action(async (opts, cmd) => {
|
|
310
|
+
const g = cmd.optsWithGlobals();
|
|
311
|
+
const logFile = getAuditLogPath(resolveData(g));
|
|
312
|
+
if (!opts.yes) {
|
|
313
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
314
|
+
const answer = await new Promise(r => rl.question(`Clear ${logFile}? [y/N] `, r));
|
|
315
|
+
rl.close();
|
|
316
|
+
if (answer.toLowerCase() !== 'y') {
|
|
317
|
+
console.log('Aborted.');
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
fs.writeFileSync(logFile, '');
|
|
322
|
+
print(g.json ? { cleared: logFile } : `✓ cleared ${logFile}`, g.json);
|
|
323
|
+
});
|
|
324
|
+
// ── parse ─────────────────────────────────────────────────────────────────────
|
|
325
|
+
program.parse(process.argv);
|
|
326
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "network-ai",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "AI agent orchestration framework for TypeScript/Node.js - 14 adapters (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw, A2A, Codex + streaming variants). Built-in security, swarm intelligence, real-time streaming, and agentic workflow patterns.",
|
|
3
|
+
"version": "4.3.0",
|
|
4
|
+
"description": "AI agent orchestration framework for TypeScript/Node.js - 14 adapters (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw, A2A, Codex + streaming variants). Built-in CLI, security, swarm intelligence, real-time streaming, and agentic workflow patterns.",
|
|
5
5
|
"homepage": "https://github.com/jovanSAPFIONEER/Network-AI#readme",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
+
"network-ai": "./dist/bin/cli.js",
|
|
9
10
|
"network-ai-server": "./dist/bin/mcp-server.js"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
"test:streaming": "npx ts-node test-streaming.ts",
|
|
30
31
|
"test:a2a": "npx ts-node test-a2a.ts",
|
|
31
32
|
"test:codex": "npx ts-node test-codex.ts",
|
|
33
|
+
"test:cli": "npx ts-node test-cli.ts",
|
|
32
34
|
"test:all": "npx ts-node run-tests.ts",
|
|
33
35
|
"setup": "npx ts-node setup.ts",
|
|
34
36
|
"setup:check": "npx ts-node setup.ts --check",
|
|
@@ -103,5 +105,8 @@
|
|
|
103
105
|
"SKILL.md",
|
|
104
106
|
"LICENSE",
|
|
105
107
|
"socket.json"
|
|
106
|
-
]
|
|
108
|
+
],
|
|
109
|
+
"dependencies": {
|
|
110
|
+
"commander": "^13.1.0"
|
|
111
|
+
}
|
|
107
112
|
}
|