@feilunxitong/arkit 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.
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * ModuleKit — 可组合可靠性模块
4
+ * Gene source: GenericAgent(模块化能力魔方)+ nuwa-skill(认知蒸馏)
5
+ * Stack minimal modules into composable reliability pipelines.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.LoggingModule = exports.RateLimitModule = exports.ModulePipeline = exports.ModuleBlockError = void 0;
9
+ class ModuleBlockError extends Error {
10
+ constructor(toolName, reason) {
11
+ super(`ARK ModulePipe blocked [${toolName}]: ${reason}`);
12
+ this.name = 'ModuleBlockError';
13
+ }
14
+ }
15
+ exports.ModuleBlockError = ModuleBlockError;
16
+ class ModulePipeline {
17
+ name;
18
+ modules = [];
19
+ totalCalls = 0;
20
+ blockedCalls = 0;
21
+ allowedCalls = 0;
22
+ constructor(name = 'default-pipeline') {
23
+ this.name = name;
24
+ }
25
+ add(module) {
26
+ this.modules.push(module);
27
+ this.modules.sort((a, b) => a.priority - b.priority);
28
+ return this;
29
+ }
30
+ remove(moduleName) {
31
+ const idx = this.modules.findIndex((m) => m.name === moduleName);
32
+ if (idx >= 0) {
33
+ this.modules.splice(idx, 1);
34
+ return true;
35
+ }
36
+ return false;
37
+ }
38
+ process(toolName, args) {
39
+ this.totalCalls++;
40
+ let context = {};
41
+ for (const module of this.modules) {
42
+ if (!module.enabled)
43
+ continue;
44
+ const result = module.process(toolName, args, context);
45
+ context = { ...context, ...(result.context ?? {}) };
46
+ if (result.action === 'block') {
47
+ this.blockedCalls++;
48
+ return {
49
+ action: 'block',
50
+ reason: `[${module.name}] ${result.reason}`,
51
+ context,
52
+ };
53
+ }
54
+ else if (result.action === 'warn') {
55
+ const warnings = context.warnings ?? [];
56
+ warnings.push(result.reason);
57
+ context.warnings = warnings;
58
+ }
59
+ }
60
+ this.allowedCalls++;
61
+ return { action: 'allow', reason: '', context };
62
+ }
63
+ wrap(toolFunc, toolName) {
64
+ const name = toolName ?? toolFunc.name;
65
+ const pipeline = this;
66
+ return function (...args) {
67
+ const argDict = {};
68
+ for (let i = 0; i < args.length; i++) {
69
+ argDict[`arg${i}`] = args[i];
70
+ }
71
+ const result = pipeline.process(name, argDict);
72
+ if (result.action === 'block') {
73
+ throw new ModuleBlockError(name, result.reason);
74
+ }
75
+ return toolFunc.apply(this, args);
76
+ };
77
+ }
78
+ get stats() {
79
+ return {
80
+ name: this.name,
81
+ modules: this.modules.length,
82
+ totalCalls: this.totalCalls,
83
+ blocked: this.blockedCalls,
84
+ allowed: this.allowedCalls,
85
+ blockRate: `${((this.blockedCalls / Math.max(this.totalCalls, 1)) * 100).toFixed(1)}%`,
86
+ moduleList: this.modules.map((m) => m.name),
87
+ };
88
+ }
89
+ }
90
+ exports.ModulePipeline = ModulePipeline;
91
+ // ─── Built-in Modules ───
92
+ class RateLimitModule {
93
+ name;
94
+ enabled = true;
95
+ priority = 100;
96
+ maxCallsPerMinute;
97
+ callTimestamps = [];
98
+ blocked = 0;
99
+ passed = 0;
100
+ constructor(maxCallsPerMinute = 60) {
101
+ this.maxCallsPerMinute = maxCallsPerMinute;
102
+ this.name = `rate-limit-${maxCallsPerMinute}pm`;
103
+ }
104
+ process(_toolName, _args, context) {
105
+ const now = Date.now();
106
+ this.callTimestamps = this.callTimestamps.filter((t) => now - t < 60_000);
107
+ if (this.callTimestamps.length >= this.maxCallsPerMinute) {
108
+ this.blocked++;
109
+ return {
110
+ action: 'block',
111
+ reason: `Rate limit: ${this.maxCallsPerMinute}/min exceeded`,
112
+ context,
113
+ };
114
+ }
115
+ this.callTimestamps.push(now);
116
+ this.passed++;
117
+ return { action: 'allow', reason: '', context };
118
+ }
119
+ get stats() {
120
+ return {
121
+ name: this.name,
122
+ enabled: this.enabled,
123
+ limit: `${this.maxCallsPerMinute}/min`,
124
+ blocked: this.blocked,
125
+ passed: this.passed,
126
+ activeInWindow: this.callTimestamps.length,
127
+ };
128
+ }
129
+ }
130
+ exports.RateLimitModule = RateLimitModule;
131
+ class LoggingModule {
132
+ name = 'logging';
133
+ enabled = true;
134
+ priority = 999;
135
+ log = [];
136
+ maxLogSize = 1000;
137
+ process(toolName, args, context) {
138
+ this.log.push({
139
+ timestamp: Date.now(),
140
+ tool: toolName,
141
+ argsKeys: Object.keys(args),
142
+ warnings: context.warnings ?? [],
143
+ });
144
+ if (this.log.length > this.maxLogSize) {
145
+ this.log = this.log.slice(-this.maxLogSize);
146
+ }
147
+ return { action: 'allow', reason: '', context };
148
+ }
149
+ get stats() {
150
+ return {
151
+ name: this.name,
152
+ enabled: this.enabled,
153
+ logSize: this.log.length,
154
+ };
155
+ }
156
+ }
157
+ exports.LoggingModule = LoggingModule;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * MultiAgentProtocol — 多Agent可靠性协议
3
+ * Gene source: PraisonAI (⭐8,104) + BMAD-METHOD
4
+ * Reliable inter-agent messaging: handshake, delivery guarantee, health checks.
5
+ */
6
+ type MessageStatus = 'pending' | 'delivered' | 'acknowledged' | 'failed' | 'timeout';
7
+ type AgentStatus = 'online' | 'busy' | 'degraded' | 'offline' | 'unknown';
8
+ interface AgentMessage {
9
+ messageId: string;
10
+ sender: string;
11
+ recipient: string;
12
+ content: Record<string, unknown>;
13
+ status: MessageStatus;
14
+ createdAt: number;
15
+ deliveredAt: number | null;
16
+ acknowledgedAt: number | null;
17
+ retryCount: number;
18
+ maxRetries: number;
19
+ ttlSeconds: number;
20
+ }
21
+ interface MultiAgentStats {
22
+ agentId: string;
23
+ messagesSent: number;
24
+ messagesDelivered: number;
25
+ messagesFailed: number;
26
+ totalRetries: number;
27
+ totalTimeouts: number;
28
+ totalHeartbeats: number;
29
+ activeMessages: number;
30
+ registeredAgents: number;
31
+ onlineAgents: number;
32
+ deliveryRate: string;
33
+ }
34
+ export declare class MultiAgentProtocol {
35
+ agentId: string;
36
+ heartbeatInterval: number;
37
+ private messages;
38
+ private agents;
39
+ private totalMessagesSent;
40
+ private totalMessagesDelivered;
41
+ private totalMessagesFailed;
42
+ private totalRetries;
43
+ private totalHeartbeats;
44
+ private totalTimeouts;
45
+ constructor(agentId: string, heartbeatInterval?: number);
46
+ registerAgent(agentId: string, initialStatus?: AgentStatus): boolean;
47
+ deregisterAgent(agentId: string): void;
48
+ sendMessage(recipient: string, content: Record<string, unknown>, maxRetries?: number, ttl?: number): AgentMessage;
49
+ private tryDeliver;
50
+ acknowledgeMessage(messageId: string): boolean;
51
+ retryMessage(messageId: string): boolean;
52
+ sendHeartbeat(status?: AgentStatus): void;
53
+ checkAgentHealth(agentId: string, maxAge?: number): AgentStatus;
54
+ getOnlineAgents(): string[];
55
+ collectGarbage(): void;
56
+ get stats(): MultiAgentStats;
57
+ get networkMap(): string;
58
+ }
59
+ export {};
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ /**
3
+ * MultiAgentProtocol — 多Agent可靠性协议
4
+ * Gene source: PraisonAI (⭐8,104) + BMAD-METHOD
5
+ * Reliable inter-agent messaging: handshake, delivery guarantee, health checks.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.MultiAgentProtocol = void 0;
9
+ function generateId() {
10
+ return Math.random().toString(36).slice(2, 14);
11
+ }
12
+ class MultiAgentProtocol {
13
+ agentId;
14
+ heartbeatInterval;
15
+ messages = new Map();
16
+ agents = new Map();
17
+ totalMessagesSent = 0;
18
+ totalMessagesDelivered = 0;
19
+ totalMessagesFailed = 0;
20
+ totalRetries = 0;
21
+ totalHeartbeats = 0;
22
+ totalTimeouts = 0;
23
+ constructor(agentId, heartbeatInterval = 5_000) {
24
+ this.agentId = agentId;
25
+ this.heartbeatInterval = heartbeatInterval;
26
+ }
27
+ registerAgent(agentId, initialStatus = 'online') {
28
+ if (!this.agents.has(agentId)) {
29
+ this.agents.set(agentId, {
30
+ agentId,
31
+ status: initialStatus,
32
+ lastSeen: Date.now(),
33
+ messageCount: 0,
34
+ errorCount: 0,
35
+ avgResponseMs: 0,
36
+ });
37
+ return true;
38
+ }
39
+ const agent = this.agents.get(agentId);
40
+ agent.status = 'online';
41
+ agent.lastSeen = Date.now();
42
+ return false;
43
+ }
44
+ deregisterAgent(agentId) {
45
+ const agent = this.agents.get(agentId);
46
+ if (agent) {
47
+ agent.status = 'offline';
48
+ }
49
+ }
50
+ sendMessage(recipient, content, maxRetries = 3, ttl = 30) {
51
+ const msg = {
52
+ messageId: generateId(),
53
+ sender: this.agentId,
54
+ recipient,
55
+ content,
56
+ status: 'pending',
57
+ createdAt: Date.now(),
58
+ deliveredAt: null,
59
+ acknowledgedAt: null,
60
+ retryCount: 0,
61
+ maxRetries,
62
+ ttlSeconds: ttl,
63
+ };
64
+ this.messages.set(msg.messageId, msg);
65
+ this.totalMessagesSent++;
66
+ this.tryDeliver(msg);
67
+ return msg;
68
+ }
69
+ tryDeliver(msg) {
70
+ const recipient = this.agents.get(msg.recipient);
71
+ if (recipient && recipient.status !== 'offline' && recipient.status !== 'unknown') {
72
+ msg.status = 'delivered';
73
+ msg.deliveredAt = Date.now();
74
+ this.totalMessagesDelivered++;
75
+ }
76
+ else {
77
+ msg.status = 'failed';
78
+ this.totalMessagesFailed++;
79
+ }
80
+ }
81
+ acknowledgeMessage(messageId) {
82
+ const msg = this.messages.get(messageId);
83
+ if (msg && msg.status === 'delivered') {
84
+ msg.status = 'acknowledged';
85
+ msg.acknowledgedAt = Date.now();
86
+ return true;
87
+ }
88
+ return false;
89
+ }
90
+ retryMessage(messageId) {
91
+ const msg = this.messages.get(messageId);
92
+ if (!msg)
93
+ return false;
94
+ if (msg.retryCount >= msg.maxRetries) {
95
+ msg.status = 'timeout';
96
+ this.totalTimeouts++;
97
+ return false;
98
+ }
99
+ msg.retryCount++;
100
+ this.totalRetries++;
101
+ this.tryDeliver(msg);
102
+ return true;
103
+ }
104
+ sendHeartbeat(status = 'online') {
105
+ const existing = this.agents.get(this.agentId);
106
+ if (!existing) {
107
+ this.agents.set(this.agentId, {
108
+ agentId: this.agentId,
109
+ status,
110
+ lastSeen: Date.now(),
111
+ messageCount: 0,
112
+ errorCount: 0,
113
+ avgResponseMs: 0,
114
+ });
115
+ }
116
+ else {
117
+ existing.status = status;
118
+ existing.lastSeen = Date.now();
119
+ }
120
+ this.totalHeartbeats++;
121
+ }
122
+ checkAgentHealth(agentId, maxAge = 15_000) {
123
+ const agent = this.agents.get(agentId);
124
+ if (!agent)
125
+ return 'unknown';
126
+ if (Date.now() - agent.lastSeen > maxAge) {
127
+ agent.status = 'offline';
128
+ return 'offline';
129
+ }
130
+ return agent.status;
131
+ }
132
+ getOnlineAgents() {
133
+ const now = Date.now();
134
+ const result = [];
135
+ for (const [id, agent] of this.agents) {
136
+ if (agent.status === 'online' && now - agent.lastSeen < 15_000) {
137
+ result.push(id);
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+ collectGarbage() {
143
+ const now = Date.now();
144
+ // Expire old messages
145
+ for (const [id, msg] of this.messages) {
146
+ if (now - msg.createdAt > msg.ttlSeconds * 1000) {
147
+ this.messages.delete(id);
148
+ }
149
+ }
150
+ // Mark stale agents offline
151
+ for (const [, agent] of this.agents) {
152
+ if (now - agent.lastSeen > 30_000) {
153
+ agent.status = 'offline';
154
+ }
155
+ }
156
+ }
157
+ get stats() {
158
+ return {
159
+ agentId: this.agentId,
160
+ messagesSent: this.totalMessagesSent,
161
+ messagesDelivered: this.totalMessagesDelivered,
162
+ messagesFailed: this.totalMessagesFailed,
163
+ totalRetries: this.totalRetries,
164
+ totalTimeouts: this.totalTimeouts,
165
+ totalHeartbeats: this.totalHeartbeats,
166
+ activeMessages: this.messages.size,
167
+ registeredAgents: this.agents.size,
168
+ onlineAgents: this.getOnlineAgents().length,
169
+ deliveryRate: `${((this.totalMessagesDelivered / Math.max(this.totalMessagesSent, 1)) * 100).toFixed(1)}%`,
170
+ };
171
+ }
172
+ get networkMap() {
173
+ const lines = [`🌐 ARK Multi-Agent Network: ${this.agentId}`];
174
+ const statusIcons = {
175
+ online: '🟢',
176
+ busy: '🟡',
177
+ degraded: '🟠',
178
+ offline: '🔴',
179
+ unknown: '⚪',
180
+ };
181
+ for (const [, agent] of this.agents) {
182
+ const icon = statusIcons[agent.status] ?? '❓';
183
+ const age = (Date.now() - agent.lastSeen) / 1000;
184
+ lines.push(` ${icon} ${agent.agentId} (seen ${age.toFixed(0)}s ago, ${agent.messageCount} msgs)`);
185
+ }
186
+ const s = this.stats;
187
+ lines.push(` ────`);
188
+ lines.push(` 📊 Delivery: ${s.deliveryRate} | Active msgs: ${s.activeMessages}`);
189
+ return lines.join('\n');
190
+ }
191
+ }
192
+ exports.MultiAgentProtocol = MultiAgentProtocol;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ProactiveGuard — 预测性失败检测
3
+ * Gene source: memU(意图捕获,⭐13,813)
4
+ * Predict potential failures before they happen by learning from patterns.
5
+ */
6
+ export declare class ProactiveBlockError extends Error {
7
+ toolName: string;
8
+ risk: number;
9
+ constructor(toolName: string, risk: number, reason: string);
10
+ }
11
+ interface ProactiveGuardStats {
12
+ name: string;
13
+ sensitivity: number;
14
+ patternsLearned: number;
15
+ predictionsMade: number;
16
+ blockedCalls: number;
17
+ allowedCalls: number;
18
+ accuracy: string;
19
+ historySize: number;
20
+ riskThreshold: number;
21
+ }
22
+ export declare class ProactiveGuard {
23
+ name: string;
24
+ sensitivity: number;
25
+ historySize: number;
26
+ private patterns;
27
+ private callHistory;
28
+ private predictions;
29
+ private correctPredictions;
30
+ private falsePositives;
31
+ private blockedCalls;
32
+ private allowedCalls;
33
+ private totalPatterns;
34
+ constructor(name?: string, sensitivity?: number, historySize?: number);
35
+ recordFailure(toolName: string, args: Record<string, unknown>, error: string): void;
36
+ recordSuccess(toolName: string, args: Record<string, unknown>): void;
37
+ private trimHistory;
38
+ predictRisk(toolName: string, args: Record<string, unknown>): number;
39
+ shouldBlock(toolName: string, args: Record<string, unknown>): [boolean, number, string];
40
+ recordPredictionOutcome(blocked: boolean, succeeded: boolean): void;
41
+ get accuracy(): number;
42
+ get stats(): ProactiveGuardStats;
43
+ get riskReport(): string;
44
+ }
45
+ export {};
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ /**
3
+ * ProactiveGuard — 预测性失败检测
4
+ * Gene source: memU(意图捕获,⭐13,813)
5
+ * Predict potential failures before they happen by learning from patterns.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.ProactiveGuard = exports.ProactiveBlockError = void 0;
9
+ class ProactiveBlockError extends Error {
10
+ toolName;
11
+ risk;
12
+ constructor(toolName, risk, reason) {
13
+ super(`ARK ProactiveGuard blocked [${toolName}]. Risk: ${(risk * 100).toFixed(0)}%. ${reason}`);
14
+ this.name = 'ProactiveBlockError';
15
+ this.toolName = toolName;
16
+ this.risk = risk;
17
+ }
18
+ }
19
+ exports.ProactiveBlockError = ProactiveBlockError;
20
+ function simpleHash(s) {
21
+ let hash = 0;
22
+ for (let i = 0; i < s.length; i++) {
23
+ const char = s.charCodeAt(i);
24
+ hash = ((hash << 5) - hash) + char;
25
+ hash |= 0;
26
+ }
27
+ return Math.abs(hash).toString(16).padStart(8, '0');
28
+ }
29
+ class ProactiveGuard {
30
+ name;
31
+ sensitivity;
32
+ historySize;
33
+ patterns = new Map();
34
+ callHistory = [];
35
+ predictions = 0;
36
+ correctPredictions = 0;
37
+ falsePositives = 0;
38
+ blockedCalls = 0;
39
+ allowedCalls = 0;
40
+ totalPatterns = 0;
41
+ constructor(name = 'proactive-guard', sensitivity = 0.3, historySize = 1000) {
42
+ this.name = name;
43
+ this.sensitivity = sensitivity;
44
+ this.historySize = historySize;
45
+ }
46
+ recordFailure(toolName, args, error) {
47
+ const sig = JSON.stringify(args, Object.keys(args).sort());
48
+ const key = `${toolName}::${simpleHash(sig).slice(0, 8)}`;
49
+ if (!this.patterns.has(key)) {
50
+ this.patterns.set(key, {
51
+ toolName,
52
+ paramSignature: sig,
53
+ failureCount: 0,
54
+ lastSeen: Date.now(),
55
+ errorSamples: [],
56
+ });
57
+ this.totalPatterns++;
58
+ }
59
+ const pattern = this.patterns.get(key);
60
+ pattern.failureCount++;
61
+ pattern.lastSeen = Date.now();
62
+ if (pattern.errorSamples.length < 5) {
63
+ pattern.errorSamples.push(error.slice(0, 100));
64
+ }
65
+ this.callHistory.push({
66
+ timestamp: Date.now(),
67
+ tool: toolName,
68
+ argsSig: sig.slice(0, 20),
69
+ success: false,
70
+ error: error.slice(0, 50),
71
+ });
72
+ this.trimHistory();
73
+ }
74
+ recordSuccess(toolName, args) {
75
+ const sig = JSON.stringify(args, Object.keys(args).sort());
76
+ this.callHistory.push({
77
+ timestamp: Date.now(),
78
+ tool: toolName,
79
+ argsSig: sig.slice(0, 20),
80
+ success: true,
81
+ });
82
+ this.trimHistory();
83
+ }
84
+ trimHistory() {
85
+ if (this.callHistory.length > this.historySize) {
86
+ this.callHistory = this.callHistory.slice(-this.historySize);
87
+ }
88
+ }
89
+ predictRisk(toolName, args) {
90
+ const sig = JSON.stringify(args, Object.keys(args).sort());
91
+ const key = `${toolName}::${simpleHash(sig).slice(0, 8)}`;
92
+ // 1. Exact pattern match
93
+ if (this.patterns.has(key)) {
94
+ const pattern = this.patterns.get(key);
95
+ const recent = this.callHistory
96
+ .slice(-20)
97
+ .filter((c) => !c.success && c.tool === toolName)
98
+ .length;
99
+ const freq = pattern.failureCount / Math.max(this.callHistory.length, 1);
100
+ const recency = 1 / (1 + (Date.now() - pattern.lastSeen) / 60_000);
101
+ return Math.min(1, freq * 0.7 + recency * 0.3);
102
+ }
103
+ // 2. Tool-level risk
104
+ const recentCalls = this.callHistory
105
+ .slice(-50)
106
+ .filter((c) => c.tool === toolName);
107
+ if (recentCalls.length > 0) {
108
+ const failRate = recentCalls.filter((c) => !c.success).length / recentCalls.length;
109
+ return failRate * 0.5;
110
+ }
111
+ // 3. Unknown operation → conservative (0 for no history)
112
+ if (this.callHistory.length === 0)
113
+ return 0;
114
+ // 4. Global trend
115
+ const globalRecent = this.callHistory.slice(-50);
116
+ const globalFailRate = globalRecent.filter((c) => !c.success).length /
117
+ Math.max(globalRecent.length, 1);
118
+ return globalFailRate * 0.3;
119
+ }
120
+ shouldBlock(toolName, args) {
121
+ const risk = this.predictRisk(toolName, args);
122
+ if (risk >= this.sensitivity) {
123
+ this.predictions++;
124
+ const sig = JSON.stringify(args, Object.keys(args).sort());
125
+ const key = `${toolName}::${simpleHash(sig).slice(0, 8)}`;
126
+ let reason = `High risk (${(risk * 100).toFixed(0)}%). Previous failures detected.`;
127
+ if (this.patterns.has(key)) {
128
+ const samples = this.patterns.get(key).errorSamples;
129
+ if (samples.length > 0) {
130
+ reason += ` Example: ${samples[0]}`;
131
+ }
132
+ }
133
+ return [true, risk, reason];
134
+ }
135
+ return [false, risk, ''];
136
+ }
137
+ recordPredictionOutcome(blocked, succeeded) {
138
+ if (blocked) {
139
+ this.blockedCalls++;
140
+ this.falsePositives++;
141
+ }
142
+ else {
143
+ this.allowedCalls++;
144
+ if (succeeded)
145
+ this.correctPredictions++;
146
+ }
147
+ }
148
+ get accuracy() {
149
+ const total = this.correctPredictions + this.falsePositives;
150
+ return total === 0 ? 1 : this.correctPredictions / total;
151
+ }
152
+ get stats() {
153
+ return {
154
+ name: this.name,
155
+ sensitivity: this.sensitivity,
156
+ patternsLearned: this.totalPatterns,
157
+ predictionsMade: this.predictions,
158
+ blockedCalls: this.blockedCalls,
159
+ allowedCalls: this.allowedCalls,
160
+ accuracy: `${(this.accuracy * 100).toFixed(1)}%`,
161
+ historySize: this.callHistory.length,
162
+ riskThreshold: this.sensitivity,
163
+ };
164
+ }
165
+ get riskReport() {
166
+ const lines = [
167
+ `🛡 ProactiveGuard: ${this.name}`,
168
+ ` Patterns: ${this.totalPatterns} | Blocked: ${this.blockedCalls} | Acc: ${(this.accuracy * 100).toFixed(1)}%`,
169
+ ];
170
+ if (this.patterns.size > 0) {
171
+ const sorted = [...this.patterns.values()]
172
+ .sort((a, b) => b.failureCount - a.failureCount)
173
+ .slice(0, 5);
174
+ lines.push(' Top Risk Patterns:');
175
+ for (const p of sorted) {
176
+ const sample = p.errorSamples[0] ?? '';
177
+ lines.push(` ⚠ ${p.toolName} (×${p.failureCount}) ${sample.slice(0, 60)}`);
178
+ }
179
+ }
180
+ return lines.join('\n');
181
+ }
182
+ }
183
+ exports.ProactiveGuard = ProactiveGuard;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * SchemaHub — Community Schema Registry
3
+ * v0.4.0: Community-driven schema ecosystem for agent tool validation.
4
+ *
5
+ * Philosophy:
6
+ * 1. Low friction — one TypeScript interface = one schema
7
+ * 2. Offline/online — local cache + remote hub
8
+ * 3. Versioned — semantic versions for every schema
9
+ * 4. Discoverable — search by category, tags, author
10
+ */
11
+ export interface SchemaMeta {
12
+ name: string;
13
+ version: string;
14
+ author: string;
15
+ category: string;
16
+ tags: string[];
17
+ description: string;
18
+ source: 'local' | 'remote';
19
+ downloads: number;
20
+ rating: number;
21
+ }
22
+ export declare const CATEGORIES: string[];
23
+ export interface ValidationError {
24
+ field: string;
25
+ message: string;
26
+ }
27
+ export declare function validateSchema(schemaName: string, data: unknown): {
28
+ valid: boolean;
29
+ errors: ValidationError[];
30
+ };
31
+ interface SchemaDef {
32
+ fields: Record<string, Record<string, unknown>>;
33
+ }
34
+ export declare const BUILTIN_SCHEMAS: Record<string, SchemaDef>;
35
+ export declare const BUILTIN_META: Record<string, SchemaMeta>;
36
+ export declare class SchemaHub {
37
+ private schemas;
38
+ private metas;
39
+ constructor(schemasDir?: string);
40
+ /** Register a schema definition with optional metadata */
41
+ register(name: string, schemaDef: SchemaDef, meta?: Partial<SchemaMeta>): void;
42
+ private registerBuiltins;
43
+ get(name: string): SchemaDef | undefined;
44
+ getMeta(name: string): SchemaMeta | undefined;
45
+ get available(): string[];
46
+ get categories(): string[];
47
+ search(options?: {
48
+ query?: string;
49
+ category?: string;
50
+ tags?: string[];
51
+ author?: string;
52
+ }): SchemaMeta[];
53
+ listByCategory(): Record<string, SchemaMeta[]>;
54
+ importDir(dirPath: string): number;
55
+ exportJSON(filePath: string): void;
56
+ exportMetaJSON(filePath: string): void;
57
+ validate(name: string, data: unknown): {
58
+ valid: boolean;
59
+ errors: ValidationError[];
60
+ };
61
+ get stats(): Record<string, unknown>;
62
+ toString(): string;
63
+ }
64
+ export {};