chainlesschain 0.37.10 → 0.37.12
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 +166 -10
- package/package.json +1 -1
- package/src/commands/a2a.js +374 -0
- package/src/commands/bi.js +240 -0
- package/src/commands/cowork.js +317 -0
- package/src/commands/economy.js +375 -0
- package/src/commands/evolution.js +398 -0
- package/src/commands/hmemory.js +273 -0
- package/src/commands/hook.js +260 -0
- package/src/commands/init.js +184 -0
- package/src/commands/lowcode.js +320 -0
- package/src/commands/plugin.js +55 -2
- package/src/commands/sandbox.js +366 -0
- package/src/commands/skill.js +254 -201
- package/src/commands/workflow.js +359 -0
- package/src/commands/zkp.js +277 -0
- package/src/index.js +44 -0
- package/src/lib/a2a-protocol.js +371 -0
- package/src/lib/agent-coordinator.js +273 -0
- package/src/lib/agent-economy.js +369 -0
- package/src/lib/app-builder.js +377 -0
- package/src/lib/bi-engine.js +299 -0
- package/src/lib/cowork/ab-comparator-cli.js +180 -0
- package/src/lib/cowork/code-knowledge-graph-cli.js +232 -0
- package/src/lib/cowork/debate-review-cli.js +144 -0
- package/src/lib/cowork/decision-kb-cli.js +153 -0
- package/src/lib/cowork/project-style-analyzer-cli.js +168 -0
- package/src/lib/cowork-adapter.js +106 -0
- package/src/lib/evolution-system.js +508 -0
- package/src/lib/hierarchical-memory.js +471 -0
- package/src/lib/hook-manager.js +387 -0
- package/src/lib/plugin-manager.js +118 -0
- package/src/lib/project-detector.js +53 -0
- package/src/lib/sandbox-v2.js +503 -0
- package/src/lib/service-container.js +183 -0
- package/src/lib/skill-loader.js +274 -0
- package/src/lib/workflow-engine.js +503 -0
- package/src/lib/zkp-engine.js +241 -0
- package/src/repl/agent-repl.js +117 -112
package/README.md
CHANGED
|
@@ -482,6 +482,162 @@ chainlesschain plugin summary # Installation summary
|
|
|
482
482
|
|
|
483
483
|
---
|
|
484
484
|
|
|
485
|
+
## Project Initialization & Collaboration
|
|
486
|
+
|
|
487
|
+
### `chainlesschain init`
|
|
488
|
+
|
|
489
|
+
Initialize a new ChainlessChain project.
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
chainlesschain init # Interactive project init
|
|
493
|
+
chainlesschain init --bare # Minimal project structure
|
|
494
|
+
chainlesschain init --template code-project --yes # Use template, skip prompts
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### `chainlesschain cowork <action>`
|
|
498
|
+
|
|
499
|
+
Multi-agent collaboration for code review and analysis.
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
chainlesschain cowork debate <file> # Multi-perspective code review
|
|
503
|
+
chainlesschain cowork compare <prompt> # A/B solution comparison
|
|
504
|
+
chainlesschain cowork analyze <path> # Code analysis (style/knowledge-graph/decisions)
|
|
505
|
+
chainlesschain cowork status # Show cowork status
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Phase 6: AI Core (Hooks, Workflow, Memory, A2A)
|
|
511
|
+
|
|
512
|
+
### `chainlesschain hook <action>`
|
|
513
|
+
|
|
514
|
+
Event hook management for extensibility.
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
chainlesschain hook list # List registered hooks
|
|
518
|
+
chainlesschain hook add --event PreToolUse --type sync --command "echo check"
|
|
519
|
+
chainlesschain hook remove <id> # Remove a hook
|
|
520
|
+
chainlesschain hook run PreToolUse # Execute hooks for event
|
|
521
|
+
chainlesschain hook stats # Hook execution statistics
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### `chainlesschain workflow <action>`
|
|
525
|
+
|
|
526
|
+
DAG-based workflow orchestration engine.
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
chainlesschain workflow create --name "pipeline" --stages '[...]'
|
|
530
|
+
chainlesschain workflow list # List workflows
|
|
531
|
+
chainlesschain workflow run <id> # Execute workflow
|
|
532
|
+
chainlesschain workflow status <id> # Check workflow status
|
|
533
|
+
chainlesschain workflow templates # List 5 built-in templates
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### `chainlesschain hmemory <action>`
|
|
537
|
+
|
|
538
|
+
Hierarchical memory system (working → short-term → long-term).
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
chainlesschain hmemory store "fact" --importance 0.8 # Store memory
|
|
542
|
+
chainlesschain hmemory recall --layer long-term # Recall memories
|
|
543
|
+
chainlesschain hmemory consolidate # Promote memories across layers
|
|
544
|
+
chainlesschain hmemory stats # Memory statistics
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### `chainlesschain a2a <action>`
|
|
548
|
+
|
|
549
|
+
Agent-to-Agent protocol for multi-agent collaboration.
|
|
550
|
+
|
|
551
|
+
```bash
|
|
552
|
+
chainlesschain a2a register --name "agent1" --capabilities '["code"]'
|
|
553
|
+
chainlesschain a2a list # List registered agents
|
|
554
|
+
chainlesschain a2a discover --capability code # Find agents by capability
|
|
555
|
+
chainlesschain a2a submit <agent> "task" # Submit task to agent
|
|
556
|
+
chainlesschain a2a status <task-id> # Check task status
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Phase 7: Security & Evolution
|
|
562
|
+
|
|
563
|
+
### `chainlesschain sandbox <action>`
|
|
564
|
+
|
|
565
|
+
Secure sandbox execution environment.
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
chainlesschain sandbox create --name "test" # Create sandbox
|
|
569
|
+
chainlesschain sandbox list # List sandboxes
|
|
570
|
+
chainlesschain sandbox exec <id> "command" # Execute in sandbox
|
|
571
|
+
chainlesschain sandbox audit <id> # View audit log
|
|
572
|
+
chainlesschain sandbox destroy <id> # Destroy sandbox
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### `chainlesschain evolution <action>`
|
|
576
|
+
|
|
577
|
+
Self-evolving AI capability assessment and learning.
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
chainlesschain evolution assess code-generation # Assess capability
|
|
581
|
+
chainlesschain evolution diagnose # Self-diagnosis
|
|
582
|
+
chainlesschain evolution learn --domain nlp # Incremental learning
|
|
583
|
+
chainlesschain evolution status # Evolution status
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## Phase 8: Blockchain & Enterprise Analytics
|
|
589
|
+
|
|
590
|
+
### `chainlesschain economy <action>`
|
|
591
|
+
|
|
592
|
+
Agent economy and micropayment system.
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
chainlesschain economy pay <from> <to> 100 # Agent micropayment
|
|
596
|
+
chainlesschain economy balance <agent> # Check balance
|
|
597
|
+
chainlesschain economy market list # Browse resource market
|
|
598
|
+
chainlesschain economy nft mint <agent> # Mint contribution NFT
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### `chainlesschain zkp <action>`
|
|
602
|
+
|
|
603
|
+
Zero-Knowledge Proof engine.
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
chainlesschain zkp compile --name "age-proof" # Compile ZKP circuit
|
|
607
|
+
chainlesschain zkp prove <circuit> --witness '{}' # Generate proof
|
|
608
|
+
chainlesschain zkp verify <circuit> <proof> # Verify proof
|
|
609
|
+
chainlesschain zkp list # List circuits
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### `chainlesschain bi <action>`
|
|
613
|
+
|
|
614
|
+
Business Intelligence with natural language queries.
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
chainlesschain bi query "show monthly revenue" # NL→SQL query
|
|
618
|
+
chainlesschain bi dashboard create --name "KPI" # Create dashboard
|
|
619
|
+
chainlesschain bi dashboard list # List dashboards
|
|
620
|
+
chainlesschain bi anomaly --metric sales # Z-score anomaly detection
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
## Phase 9: Low-Code Platform
|
|
626
|
+
|
|
627
|
+
### `chainlesschain lowcode <action>`
|
|
628
|
+
|
|
629
|
+
Visual low-code application builder.
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
chainlesschain lowcode create --name "app1" # Create app
|
|
633
|
+
chainlesschain lowcode list # List apps
|
|
634
|
+
chainlesschain lowcode components # List 15+ components
|
|
635
|
+
chainlesschain lowcode preview <id> # Preview app
|
|
636
|
+
chainlesschain lowcode publish <id> # Publish app
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
485
641
|
## Global Options
|
|
486
642
|
|
|
487
643
|
```bash
|
|
@@ -554,7 +710,7 @@ Configuration is stored at `~/.chainlesschain/config.json`. The CLI creates and
|
|
|
554
710
|
```bash
|
|
555
711
|
cd packages/cli
|
|
556
712
|
npm install
|
|
557
|
-
npm test # Run all tests (
|
|
713
|
+
npm test # Run all tests (1429 tests across 67 files)
|
|
558
714
|
npm run test:unit # Unit tests only
|
|
559
715
|
npm run test:integration # Integration tests
|
|
560
716
|
npm run test:e2e # End-to-end tests
|
|
@@ -562,15 +718,15 @@ npm run test:e2e # End-to-end tests
|
|
|
562
718
|
|
|
563
719
|
### Test Coverage
|
|
564
720
|
|
|
565
|
-
| Category | Files | Tests
|
|
566
|
-
| ------------------------ | ------ |
|
|
567
|
-
| Unit — lib modules |
|
|
568
|
-
| Unit — commands |
|
|
569
|
-
| Unit — runtime | 1 | 6
|
|
570
|
-
| Integration | 3 | 7
|
|
571
|
-
| E2E |
|
|
572
|
-
| Core packages (external) | — | 118
|
|
573
|
-
| **CLI Total** | **
|
|
721
|
+
| Category | Files | Tests | Status |
|
|
722
|
+
| ------------------------ | ------ | -------- | --------------- |
|
|
723
|
+
| Unit — lib modules | 44 | 892 | All passing |
|
|
724
|
+
| Unit — commands | 10 | 213 | All passing |
|
|
725
|
+
| Unit — runtime | 1 | 6 | All passing |
|
|
726
|
+
| Integration | 3 | 7 | All passing |
|
|
727
|
+
| E2E | 10 | 109 | All passing |
|
|
728
|
+
| Core packages (external) | — | 118 | All passing |
|
|
729
|
+
| **CLI Total** | **67** | **1429** | **All passing** |
|
|
574
730
|
|
|
575
731
|
## License
|
|
576
732
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A (Agent-to-Agent) Protocol commands
|
|
3
|
+
* chainlesschain a2a register|discover|submit|status|complete|fail|peers|cards|negotiate
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import ora from "ora";
|
|
8
|
+
import { logger } from "../lib/logger.js";
|
|
9
|
+
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
|
+
import {
|
|
11
|
+
registerCard,
|
|
12
|
+
updateCard,
|
|
13
|
+
discoverAgents,
|
|
14
|
+
sendTask,
|
|
15
|
+
completeTask,
|
|
16
|
+
failTask,
|
|
17
|
+
getTaskStatus,
|
|
18
|
+
negotiateCapability,
|
|
19
|
+
listPeers,
|
|
20
|
+
} from "../lib/a2a-protocol.js";
|
|
21
|
+
|
|
22
|
+
export function registerA2aCommand(program) {
|
|
23
|
+
const a2a = program
|
|
24
|
+
.command("a2a")
|
|
25
|
+
.description("A2A Protocol — agent-to-agent communication");
|
|
26
|
+
|
|
27
|
+
// a2a register <name>
|
|
28
|
+
a2a
|
|
29
|
+
.command("register")
|
|
30
|
+
.description("Register an agent card")
|
|
31
|
+
.argument("<name>", "Agent name")
|
|
32
|
+
.option("--description <desc>", "Agent description", "")
|
|
33
|
+
.option("--url <url>", "Agent endpoint URL", "")
|
|
34
|
+
.option("--capabilities <csv>", "Comma-separated capabilities", "")
|
|
35
|
+
.option("--skills <csv>", "Comma-separated skills", "")
|
|
36
|
+
.option("--json", "Output as JSON")
|
|
37
|
+
.action(async (name, options) => {
|
|
38
|
+
try {
|
|
39
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
40
|
+
if (!ctx.db) {
|
|
41
|
+
logger.error("Database not available");
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const db = ctx.db.getDatabase();
|
|
45
|
+
const card = registerCard(db, {
|
|
46
|
+
name,
|
|
47
|
+
description: options.description,
|
|
48
|
+
url: options.url,
|
|
49
|
+
capabilities: options.capabilities
|
|
50
|
+
? options.capabilities.split(",").map((s) => s.trim())
|
|
51
|
+
: [],
|
|
52
|
+
skills: options.skills
|
|
53
|
+
? options.skills.split(",").map((s) => s.trim())
|
|
54
|
+
: [],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (options.json) {
|
|
58
|
+
console.log(JSON.stringify(card, null, 2));
|
|
59
|
+
} else {
|
|
60
|
+
logger.success(
|
|
61
|
+
`Agent registered: ${chalk.cyan(card.name)} ${chalk.gray(card.id)}`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await shutdown();
|
|
66
|
+
} catch (err) {
|
|
67
|
+
logger.error(`Failed: ${err.message}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// a2a discover
|
|
73
|
+
a2a
|
|
74
|
+
.command("discover")
|
|
75
|
+
.description("Discover agents by capability or skill")
|
|
76
|
+
.option("--capability <name>", "Filter by capability")
|
|
77
|
+
.option("--skill <name>", "Filter by skill")
|
|
78
|
+
.option("--name <filter>", "Filter by name")
|
|
79
|
+
.option("--json", "Output as JSON")
|
|
80
|
+
.action(async (options) => {
|
|
81
|
+
try {
|
|
82
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
83
|
+
if (!ctx.db) {
|
|
84
|
+
logger.error("Database not available");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const db = ctx.db.getDatabase();
|
|
88
|
+
const agents = discoverAgents(db, {
|
|
89
|
+
capability: options.capability,
|
|
90
|
+
skill: options.skill,
|
|
91
|
+
name: options.name,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (options.json) {
|
|
95
|
+
console.log(JSON.stringify(agents, null, 2));
|
|
96
|
+
} else if (agents.length === 0) {
|
|
97
|
+
logger.info("No agents found matching criteria");
|
|
98
|
+
} else {
|
|
99
|
+
logger.log(chalk.bold(`Discovered ${agents.length} agents:\n`));
|
|
100
|
+
for (const a of agents) {
|
|
101
|
+
logger.log(` ${chalk.cyan(a.name)} ${chalk.gray(a.id)}`);
|
|
102
|
+
if (a.description) logger.log(` ${chalk.white(a.description)}`);
|
|
103
|
+
if (a.capabilities.length)
|
|
104
|
+
logger.log(
|
|
105
|
+
` Capabilities: ${chalk.yellow(a.capabilities.join(", "))}`,
|
|
106
|
+
);
|
|
107
|
+
if (a.skills.length)
|
|
108
|
+
logger.log(` Skills: ${chalk.yellow(a.skills.join(", "))}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
await shutdown();
|
|
113
|
+
} catch (err) {
|
|
114
|
+
logger.error(`Failed: ${err.message}`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// a2a submit <agent-id> <input>
|
|
120
|
+
a2a
|
|
121
|
+
.command("submit")
|
|
122
|
+
.description("Submit a task to an agent")
|
|
123
|
+
.argument("<agent-id>", "Target agent ID")
|
|
124
|
+
.argument("<input>", "Task input")
|
|
125
|
+
.option("--json", "Output as JSON")
|
|
126
|
+
.action(async (agentId, input, options) => {
|
|
127
|
+
try {
|
|
128
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
129
|
+
if (!ctx.db) {
|
|
130
|
+
logger.error("Database not available");
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
const db = ctx.db.getDatabase();
|
|
134
|
+
const result = sendTask(db, agentId, input);
|
|
135
|
+
|
|
136
|
+
if (options.json) {
|
|
137
|
+
console.log(JSON.stringify(result, null, 2));
|
|
138
|
+
} else {
|
|
139
|
+
logger.success(
|
|
140
|
+
`Task submitted: ${chalk.gray(result.taskId)} [${chalk.yellow(result.status)}]`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await shutdown();
|
|
145
|
+
} catch (err) {
|
|
146
|
+
logger.error(`Failed: ${err.message}`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// a2a status <task-id>
|
|
152
|
+
a2a
|
|
153
|
+
.command("status")
|
|
154
|
+
.description("Get task status")
|
|
155
|
+
.argument("<task-id>", "Task ID")
|
|
156
|
+
.option("--json", "Output as JSON")
|
|
157
|
+
.action(async (taskId, options) => {
|
|
158
|
+
try {
|
|
159
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
160
|
+
if (!ctx.db) {
|
|
161
|
+
logger.error("Database not available");
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
const db = ctx.db.getDatabase();
|
|
165
|
+
const task = getTaskStatus(db, taskId);
|
|
166
|
+
|
|
167
|
+
if (options.json) {
|
|
168
|
+
console.log(JSON.stringify(task, null, 2));
|
|
169
|
+
} else {
|
|
170
|
+
logger.log(chalk.bold("Task Status:\n"));
|
|
171
|
+
logger.log(` ID: ${chalk.gray(task.id)}`);
|
|
172
|
+
logger.log(` Agent: ${chalk.cyan(task.agent_id)}`);
|
|
173
|
+
logger.log(` Status: ${chalk.yellow(task.status)}`);
|
|
174
|
+
if (task.input)
|
|
175
|
+
logger.log(
|
|
176
|
+
` Input: ${chalk.white(task.input.substring(0, 100))}`,
|
|
177
|
+
);
|
|
178
|
+
if (task.output)
|
|
179
|
+
logger.log(
|
|
180
|
+
` Output: ${chalk.green(task.output.substring(0, 100))}`,
|
|
181
|
+
);
|
|
182
|
+
if (task.error) logger.log(` Error: ${chalk.red(task.error)}`);
|
|
183
|
+
if (task.history.length) {
|
|
184
|
+
logger.log(" History:");
|
|
185
|
+
for (const h of task.history) {
|
|
186
|
+
logger.log(
|
|
187
|
+
` ${chalk.gray(h.timestamp)} → ${chalk.yellow(h.status)}`,
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
await shutdown();
|
|
194
|
+
} catch (err) {
|
|
195
|
+
logger.error(`Failed: ${err.message}`);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// a2a complete <task-id> <output>
|
|
201
|
+
a2a
|
|
202
|
+
.command("complete")
|
|
203
|
+
.description("Mark a task as completed")
|
|
204
|
+
.argument("<task-id>", "Task ID")
|
|
205
|
+
.argument("<output>", "Task output")
|
|
206
|
+
.action(async (taskId, output) => {
|
|
207
|
+
try {
|
|
208
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
209
|
+
if (!ctx.db) {
|
|
210
|
+
logger.error("Database not available");
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
const db = ctx.db.getDatabase();
|
|
214
|
+
const result = completeTask(db, taskId, output);
|
|
215
|
+
logger.success(
|
|
216
|
+
`Task ${chalk.gray(taskId)} → ${chalk.green(result.status)}`,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
await shutdown();
|
|
220
|
+
} catch (err) {
|
|
221
|
+
logger.error(`Failed: ${err.message}`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// a2a fail <task-id> <error>
|
|
227
|
+
a2a
|
|
228
|
+
.command("fail")
|
|
229
|
+
.description("Mark a task as failed")
|
|
230
|
+
.argument("<task-id>", "Task ID")
|
|
231
|
+
.argument("<error>", "Error message")
|
|
232
|
+
.action(async (taskId, error) => {
|
|
233
|
+
try {
|
|
234
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
235
|
+
if (!ctx.db) {
|
|
236
|
+
logger.error("Database not available");
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
const db = ctx.db.getDatabase();
|
|
240
|
+
const result = failTask(db, taskId, error);
|
|
241
|
+
logger.success(
|
|
242
|
+
`Task ${chalk.gray(taskId)} → ${chalk.red(result.status)}`,
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
await shutdown();
|
|
246
|
+
} catch (err) {
|
|
247
|
+
logger.error(`Failed: ${err.message}`);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// a2a peers
|
|
253
|
+
a2a
|
|
254
|
+
.command("peers")
|
|
255
|
+
.description("List all registered agents")
|
|
256
|
+
.option("--json", "Output as JSON")
|
|
257
|
+
.action(async (options) => {
|
|
258
|
+
try {
|
|
259
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
260
|
+
if (!ctx.db) {
|
|
261
|
+
logger.error("Database not available");
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
const db = ctx.db.getDatabase();
|
|
265
|
+
const peers = listPeers(db);
|
|
266
|
+
|
|
267
|
+
if (options.json) {
|
|
268
|
+
console.log(JSON.stringify(peers, null, 2));
|
|
269
|
+
} else if (peers.length === 0) {
|
|
270
|
+
logger.info("No agents registered. Use 'a2a register' to add one.");
|
|
271
|
+
} else {
|
|
272
|
+
logger.log(chalk.bold(`${peers.length} registered agents:\n`));
|
|
273
|
+
for (const p of peers) {
|
|
274
|
+
const statusColor =
|
|
275
|
+
p.status === "active" ? chalk.green : chalk.gray;
|
|
276
|
+
logger.log(
|
|
277
|
+
` ${chalk.cyan(p.name)} ${chalk.gray(p.id)} ${statusColor(p.status)}`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
await shutdown();
|
|
283
|
+
} catch (err) {
|
|
284
|
+
logger.error(`Failed: ${err.message}`);
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// a2a cards
|
|
290
|
+
a2a
|
|
291
|
+
.command("cards")
|
|
292
|
+
.description("List all agent cards with details")
|
|
293
|
+
.option("--json", "Output as JSON")
|
|
294
|
+
.action(async (options) => {
|
|
295
|
+
try {
|
|
296
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
297
|
+
if (!ctx.db) {
|
|
298
|
+
logger.error("Database not available");
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
const db = ctx.db.getDatabase();
|
|
302
|
+
const peers = listPeers(db);
|
|
303
|
+
|
|
304
|
+
if (options.json) {
|
|
305
|
+
console.log(JSON.stringify(peers, null, 2));
|
|
306
|
+
} else if (peers.length === 0) {
|
|
307
|
+
logger.info("No agent cards registered.");
|
|
308
|
+
} else {
|
|
309
|
+
logger.log(chalk.bold(`${peers.length} agent cards:\n`));
|
|
310
|
+
for (const p of peers) {
|
|
311
|
+
logger.log(` ${chalk.cyan(p.name)} ${chalk.gray(p.id)}`);
|
|
312
|
+
if (p.description) logger.log(` Description: ${p.description}`);
|
|
313
|
+
if (p.url) logger.log(` URL: ${chalk.blue(p.url)}`);
|
|
314
|
+
logger.log(` Auth: ${p.auth_type}`);
|
|
315
|
+
if (p.capabilities.length)
|
|
316
|
+
logger.log(
|
|
317
|
+
` Capabilities: ${chalk.yellow(p.capabilities.join(", "))}`,
|
|
318
|
+
);
|
|
319
|
+
if (p.skills.length)
|
|
320
|
+
logger.log(` Skills: ${chalk.yellow(p.skills.join(", "))}`);
|
|
321
|
+
logger.log("");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
await shutdown();
|
|
326
|
+
} catch (err) {
|
|
327
|
+
logger.error(`Failed: ${err.message}`);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// a2a negotiate <agent-id> <capabilities>
|
|
333
|
+
a2a
|
|
334
|
+
.command("negotiate")
|
|
335
|
+
.description("Check if an agent supports required capabilities")
|
|
336
|
+
.argument("<agent-id>", "Agent ID")
|
|
337
|
+
.argument("<capabilities>", "Comma-separated required capabilities")
|
|
338
|
+
.option("--json", "Output as JSON")
|
|
339
|
+
.action(async (agentId, capabilities, options) => {
|
|
340
|
+
try {
|
|
341
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
342
|
+
if (!ctx.db) {
|
|
343
|
+
logger.error("Database not available");
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
const db = ctx.db.getDatabase();
|
|
347
|
+
const required = capabilities.split(",").map((s) => s.trim());
|
|
348
|
+
const result = negotiateCapability(db, agentId, required);
|
|
349
|
+
|
|
350
|
+
if (options.json) {
|
|
351
|
+
console.log(JSON.stringify(result, null, 2));
|
|
352
|
+
} else {
|
|
353
|
+
if (result.compatible) {
|
|
354
|
+
logger.success("Agent is fully compatible");
|
|
355
|
+
} else {
|
|
356
|
+
logger.warn("Agent is not fully compatible");
|
|
357
|
+
}
|
|
358
|
+
if (result.supported.length) {
|
|
359
|
+
logger.log(
|
|
360
|
+
` Supported: ${chalk.green(result.supported.join(", "))}`,
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
if (result.missing.length) {
|
|
364
|
+
logger.log(` Missing: ${chalk.red(result.missing.join(", "))}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
await shutdown();
|
|
369
|
+
} catch (err) {
|
|
370
|
+
logger.error(`Failed: ${err.message}`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|