@nex-ai/nex 0.1.28 → 0.1.30
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 +25 -8
- package/dist/agent/message-router.d.ts +26 -0
- package/dist/agent/message-router.js +114 -0
- package/dist/agent/message-router.js.map +1 -0
- package/dist/agent/orchestrate.d.ts +26 -0
- package/dist/agent/orchestrate.js +87 -0
- package/dist/agent/orchestrate.js.map +1 -0
- package/dist/agent/providers/types.d.ts +5 -0
- package/dist/agent/providers/types.js +2 -0
- package/dist/agent/providers/types.js.map +1 -0
- package/dist/agent/queues.d.ts +1 -0
- package/dist/agent/queues.js +3 -0
- package/dist/agent/queues.js.map +1 -1
- package/dist/agent/templates.js +10 -3
- package/dist/agent/templates.js.map +1 -1
- package/dist/agent/tick-manager.d.ts +20 -0
- package/dist/agent/tick-manager.js +50 -0
- package/dist/agent/tick-manager.js.map +1 -0
- package/dist/commands/dispatch.d.ts +5 -0
- package/dist/commands/dispatch.js +120 -0
- package/dist/commands/dispatch.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +11 -19
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/setup.js +9 -11
- package/dist/commands/setup.js.map +1 -1
- package/dist/index.js +90 -22
- package/dist/index.js.map +1 -1
- package/dist/lib/claude-code-installer.d.ts +8 -0
- package/dist/lib/claude-code-installer.js +76 -0
- package/dist/lib/claude-code-installer.js.map +1 -0
- package/dist/lib/errors.js +1 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/installers.d.ts +4 -0
- package/dist/lib/installers.js +8 -4
- package/dist/lib/installers.js.map +1 -1
- package/dist/lib/nex-mcp-config.d.ts +11 -4
- package/dist/lib/nex-mcp-config.js +15 -8
- package/dist/lib/nex-mcp-config.js.map +1 -1
- package/dist/plugin/auto-capture.js +1 -0
- package/dist/plugin/auto-capture.js.map +1 -1
- package/dist/plugin/auto-register.d.ts +1 -1
- package/dist/plugin/auto-register.js +13 -8
- package/dist/plugin/auto-register.js.map +1 -1
- package/dist/plugin/config.d.ts +7 -16
- package/dist/plugin/config.js +16 -36
- package/dist/plugin/config.js.map +1 -1
- package/dist/plugin/nex-client.js +1 -1
- package/dist/plugin/nex-client.js.map +1 -1
- package/dist/plugin/shared.d.ts +1 -0
- package/dist/plugin/shared.js +134 -4
- package/dist/plugin/shared.js.map +1 -1
- package/dist/tui/app.js +10 -105
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components/agent-roster.d.ts +7 -0
- package/dist/tui/components/agent-roster.js +66 -0
- package/dist/tui/components/agent-roster.js.map +1 -0
- package/dist/tui/register-views.js +7 -1
- package/dist/tui/register-views.js.map +1 -1
- package/dist/tui/services/agent-service.d.ts +2 -0
- package/dist/tui/services/agent-service.js +5 -0
- package/dist/tui/services/agent-service.js.map +1 -1
- package/dist/tui/slash-commands.d.ts +2 -0
- package/dist/tui/slash-commands.js +151 -8
- package/dist/tui/slash-commands.js.map +1 -1
- package/dist/tui/views/stream.d.ts +19 -0
- package/dist/tui/views/stream.js +343 -0
- package/dist/tui/views/stream.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/nex-crm/nex-as-a-skill)
|
|
5
5
|
[](https://discord.gg/gjSySC3PzV)
|
|
6
6
|
|
|
7
|
-
Turn all your AI agent conversations into a unified knowledge graph. Supports Claude Code, Codex, OpenClaw, Cursor, OpenCode, etc. Adds additional context from Email, Meetings, Slack, HubSpot, Salesforce.
|
|
7
|
+
Turn all your AI agent conversations into a unified knowledge graph with proactive context surfacing. Supports Claude Code, Codex, OpenClaw, Cursor, OpenCode, etc. Adds additional context from Email, Meetings, Slack, HubSpot, Salesforce.
|
|
8
8
|
|
|
9
9
|
<a href="https://discord.gg/gjSySC3PzV"><img src="https://img.shields.io/badge/Join%20our%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Join our Discord" /></a>
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ Talk to the team, share feedback, and connect with other developers building AI
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
# Install globally
|
|
19
|
-
|
|
19
|
+
npm install -g @nex-ai/nex
|
|
20
20
|
|
|
21
21
|
# Or run directly (no install)
|
|
22
22
|
npx @nex-ai/nex ask "who is Maria?"
|
|
@@ -102,9 +102,9 @@ nex graph # Open the workspace graph in your browser
|
|
|
102
102
|
- Installs the full 6-layer hierarchy for each detected platform: hooks → plugins → agents → workflows → rules → MCP
|
|
103
103
|
- Scans current directory and ingests new/changed files into Nex
|
|
104
104
|
- Creates `.nex.toml` project config with commented defaults
|
|
105
|
-
-
|
|
105
|
+
- Stores config in `~/.nex/config.json`
|
|
106
106
|
|
|
107
|
-
**Single install**: `
|
|
107
|
+
**Single install**: `npm install -g @nex-ai/nex` bundles everything — hooks, adapters, platform plugins, slash commands, rules, and MCP server. No separate packages needed.
|
|
108
108
|
|
|
109
109
|
**Integration hierarchy** (per platform): Hooks > Custom plugins > Custom agents/modes > Workflows > Rules > MCP. Each platform gets every layer it supports.
|
|
110
110
|
|
|
@@ -120,8 +120,8 @@ Per-project settings file created by `nex setup`. All fields are optional.
|
|
|
120
120
|
# enabled = true # Master kill switch for all hooks
|
|
121
121
|
|
|
122
122
|
[hooks.recall]
|
|
123
|
-
# enabled = true #
|
|
124
|
-
# debounce_ms =
|
|
123
|
+
# enabled = true # Proactive context on every prompt
|
|
124
|
+
# debounce_ms = 10000
|
|
125
125
|
|
|
126
126
|
[hooks.capture]
|
|
127
127
|
# enabled = true # Auto-capture on conversation stop
|
|
@@ -135,7 +135,7 @@ Per-project settings file created by `nex setup`. All fields are optional.
|
|
|
135
135
|
# enabled = true
|
|
136
136
|
# extensions = [".md", ".txt", ".csv", ".json", ".yaml", ".yml"]
|
|
137
137
|
# ignore_dirs = ["node_modules", ".git", "dist", "build", "__pycache__"]
|
|
138
|
-
# max_files =
|
|
138
|
+
# max_files = 1000
|
|
139
139
|
# max_file_size = 100000
|
|
140
140
|
# depth = 2
|
|
141
141
|
|
|
@@ -208,7 +208,14 @@ nex list-job create "enterprise contacts in EMEA"
|
|
|
208
208
|
|
|
209
209
|
### File Scanning
|
|
210
210
|
|
|
211
|
-
On session start, Nex automatically scans project files and ingests changed content.
|
|
211
|
+
On session start, Nex automatically scans project files and ingests changed content using concurrent workers (5 parallel requests). After ingestion, compounding intelligence jobs are triggered automatically to generate patterns and playbook rules.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
nex scan # Scan current directory (up to 1000 files)
|
|
215
|
+
nex scan --max-files 500 # Limit files per scan
|
|
216
|
+
nex scan --force # Re-scan all files (ignore manifest)
|
|
217
|
+
nex scan --dry-run # Preview what would be scanned
|
|
218
|
+
```
|
|
212
219
|
|
|
213
220
|
**Default text-based extensions:** `.md`, `.txt`, `.csv`, `.json`, `.yaml`, `.yml`
|
|
214
221
|
|
|
@@ -216,6 +223,16 @@ On session start, Nex automatically scans project files and ingests changed cont
|
|
|
216
223
|
|
|
217
224
|
Configure via `.nex.toml` `[scan]` section or environment variables (`NEX_SCAN_ENABLED`, `NEX_SCAN_EXTENSIONS`, etc.).
|
|
218
225
|
|
|
226
|
+
### Proactive Context
|
|
227
|
+
|
|
228
|
+
Nex surfaces relevant knowledge graph context on every prompt — not just questions. When you say "fix the migration script" or "deploy to staging", the system automatically injects entity insights, knowledge insights, and playbook patterns from your knowledge graph.
|
|
229
|
+
|
|
230
|
+
Context is injected as `<nex-context>` blocks that AI agents use naturally without explicitly referencing the source. Only trivial inputs (yes/ok/lgtm) are skipped.
|
|
231
|
+
|
|
232
|
+
### Transcript Capture
|
|
233
|
+
|
|
234
|
+
At session end, the full conversation transcript is automatically ingested into the knowledge graph. This captures complete decision trails, code discussions, and debugging sessions — not just the last message.
|
|
235
|
+
|
|
219
236
|
### Config & Sessions
|
|
220
237
|
|
|
221
238
|
```bash
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageRouter: routes incoming messages to the best-fit agent
|
|
3
|
+
* using TaskRouter for skill scoring and thread-detection heuristics
|
|
4
|
+
* for follow-up messages.
|
|
5
|
+
*/
|
|
6
|
+
export interface RoutingResult {
|
|
7
|
+
primary: string;
|
|
8
|
+
collaborators: string[];
|
|
9
|
+
isFollowUp: boolean;
|
|
10
|
+
teamLeadAware: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class MessageRouter {
|
|
13
|
+
private router;
|
|
14
|
+
private recentThreads;
|
|
15
|
+
private FOLLOWUP_WINDOW_MS;
|
|
16
|
+
registerAgent(slug: string, expertise: string[]): void;
|
|
17
|
+
unregisterAgent(slug: string): void;
|
|
18
|
+
recordAgentActivity(agentSlug: string): void;
|
|
19
|
+
route(message: string, availableAgents: Array<{
|
|
20
|
+
slug: string;
|
|
21
|
+
expertise: string[];
|
|
22
|
+
}>): RoutingResult;
|
|
23
|
+
private detectFollowUp;
|
|
24
|
+
/** Extract skill keywords from a message using pattern matching. */
|
|
25
|
+
extractSkills(message: string): string[];
|
|
26
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageRouter: routes incoming messages to the best-fit agent
|
|
3
|
+
* using TaskRouter for skill scoring and thread-detection heuristics
|
|
4
|
+
* for follow-up messages.
|
|
5
|
+
*/
|
|
6
|
+
import { TaskRouter } from '../orchestration/router.js';
|
|
7
|
+
export class MessageRouter {
|
|
8
|
+
router = new TaskRouter();
|
|
9
|
+
recentThreads = new Map();
|
|
10
|
+
FOLLOWUP_WINDOW_MS = 30_000;
|
|
11
|
+
registerAgent(slug, expertise) {
|
|
12
|
+
this.router.registerAgent(slug, expertise.map((e) => ({ name: e, description: e, proficiency: 0.8 })));
|
|
13
|
+
}
|
|
14
|
+
unregisterAgent(slug) {
|
|
15
|
+
this.router.unregisterAgent(slug);
|
|
16
|
+
}
|
|
17
|
+
recordAgentActivity(agentSlug) {
|
|
18
|
+
this.recentThreads.set(agentSlug, { agentSlug, lastActivity: Date.now() });
|
|
19
|
+
}
|
|
20
|
+
route(message, availableAgents) {
|
|
21
|
+
// Step 1: Thread detection
|
|
22
|
+
const followUp = this.detectFollowUp(message);
|
|
23
|
+
if (followUp) {
|
|
24
|
+
return { primary: followUp, collaborators: [], isFollowUp: true, teamLeadAware: false };
|
|
25
|
+
}
|
|
26
|
+
// Step 2: Extract skills from message using keyword patterns
|
|
27
|
+
const requiredSkills = this.extractSkills(message);
|
|
28
|
+
// No recognized skills → route to team-lead for triage
|
|
29
|
+
if (requiredSkills.length === 0) {
|
|
30
|
+
return { primary: 'team-lead', collaborators: [], isFollowUp: false, teamLeadAware: false };
|
|
31
|
+
}
|
|
32
|
+
// Step 3: Register agents (ensure current state) and score
|
|
33
|
+
for (const agent of availableAgents) {
|
|
34
|
+
this.registerAgent(agent.slug, agent.expertise);
|
|
35
|
+
}
|
|
36
|
+
const task = {
|
|
37
|
+
id: `route-${Date.now()}`,
|
|
38
|
+
title: message,
|
|
39
|
+
description: message,
|
|
40
|
+
requiredSkills,
|
|
41
|
+
priority: 'medium',
|
|
42
|
+
status: 'pending',
|
|
43
|
+
createdAt: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
const capable = this.router.findCapableAgents(task);
|
|
46
|
+
if (capable.length === 0) {
|
|
47
|
+
return { primary: 'team-lead', collaborators: [], isFollowUp: false, teamLeadAware: false };
|
|
48
|
+
}
|
|
49
|
+
const primary = capable[0].agentSlug;
|
|
50
|
+
const collaborators = capable
|
|
51
|
+
.slice(1)
|
|
52
|
+
.filter((c) => c.score > 0.5)
|
|
53
|
+
.map((c) => c.agentSlug);
|
|
54
|
+
return {
|
|
55
|
+
primary,
|
|
56
|
+
collaborators,
|
|
57
|
+
isFollowUp: false,
|
|
58
|
+
teamLeadAware: primary !== 'team-lead',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
detectFollowUp(message) {
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const followUpPatterns = /^(also|and |too |that |it |the results|those |these |this |what about|how about|can you also)/i;
|
|
64
|
+
if (!followUpPatterns.test(message.trim()))
|
|
65
|
+
return null;
|
|
66
|
+
// Find most recent active thread within window
|
|
67
|
+
let mostRecent = null;
|
|
68
|
+
for (const [, ctx] of this.recentThreads) {
|
|
69
|
+
if (now - ctx.lastActivity <= this.FOLLOWUP_WINDOW_MS) {
|
|
70
|
+
if (!mostRecent || ctx.lastActivity > mostRecent.lastActivity) {
|
|
71
|
+
mostRecent = ctx;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return mostRecent?.agentSlug ?? null;
|
|
76
|
+
}
|
|
77
|
+
/** Extract skill keywords from a message using pattern matching. */
|
|
78
|
+
extractSkills(message) {
|
|
79
|
+
const skillPatterns = [
|
|
80
|
+
{
|
|
81
|
+
pattern: /\b(research|investigate|analyze|analysis|competitor)\b/i,
|
|
82
|
+
skills: ['market-research', 'competitive-analysis'],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
pattern: /\b(leads?|prospect|outreach|prospecting|pipeline)\b/i,
|
|
86
|
+
skills: ['prospecting', 'outreach'],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
pattern: /\b(enrich|validate|data quality|fill in|complete)\b/i,
|
|
90
|
+
skills: ['data-enrichment', 'validation'],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
pattern: /\b(seo|keyword|search visibility|ranking|content)\b/i,
|
|
94
|
+
skills: ['seo', 'content-analysis'],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
pattern: /\b(customer|success|health|renewal|churn|retention)\b/i,
|
|
98
|
+
skills: ['relationship-management', 'health-scoring'],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
pattern: /\b(code|bug|fix|implement|build|deploy|test)\b/i,
|
|
102
|
+
skills: ['general', 'planning'],
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
const skills = [];
|
|
106
|
+
for (const { pattern, skills: matchedSkills } of skillPatterns) {
|
|
107
|
+
if (pattern.test(message)) {
|
|
108
|
+
skills.push(...matchedSkills);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return [...new Set(skills)];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=message-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-router.js","sourceRoot":"","sources":["../../src/agent/message-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Objective-first delegation: Team-Lead decomposes objectives
|
|
3
|
+
* and routes sub-tasks to specialist agents via steer messages.
|
|
4
|
+
*
|
|
5
|
+
* Uses the orchestration TaskRouter for skill matching and
|
|
6
|
+
* MessageQueues for non-blocking delegation.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentConfig } from './types.js';
|
|
9
|
+
import type { MessageQueues } from './queues.js';
|
|
10
|
+
/** Extract actionable sub-tasks from the Team-Lead's response text. */
|
|
11
|
+
export declare function extractSubTasks(response: string): Array<{
|
|
12
|
+
action: string;
|
|
13
|
+
skills: string[];
|
|
14
|
+
}>;
|
|
15
|
+
export interface Specialist {
|
|
16
|
+
config: AgentConfig;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Delegate sub-tasks to specialist agents.
|
|
20
|
+
* Non-blocking: sends steer messages to matching specialists
|
|
21
|
+
* so they pick up work on their next tick.
|
|
22
|
+
*/
|
|
23
|
+
export declare function delegateToSpecialists(response: string, specialists: Specialist[], queues: MessageQueues): Array<{
|
|
24
|
+
agentSlug: string;
|
|
25
|
+
task: string;
|
|
26
|
+
}>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Objective-first delegation: Team-Lead decomposes objectives
|
|
3
|
+
* and routes sub-tasks to specialist agents via steer messages.
|
|
4
|
+
*
|
|
5
|
+
* Uses the orchestration TaskRouter for skill matching and
|
|
6
|
+
* MessageQueues for non-blocking delegation.
|
|
7
|
+
*/
|
|
8
|
+
import { TaskRouter } from '../orchestration/router.js';
|
|
9
|
+
import { getAgentService } from '../tui/services/agent-service.js';
|
|
10
|
+
/** Map agent expertise strings to SkillDeclarations for the router. */
|
|
11
|
+
function expertiseToSkills(expertise) {
|
|
12
|
+
return expertise.map(e => ({
|
|
13
|
+
name: e,
|
|
14
|
+
description: e,
|
|
15
|
+
proficiency: 0.8,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
/** Extract actionable sub-tasks from the Team-Lead's response text. */
|
|
19
|
+
export function extractSubTasks(response) {
|
|
20
|
+
const subTasks = [];
|
|
21
|
+
// Skill keyword mapping — matches action words to required expertise
|
|
22
|
+
const skillPatterns = [
|
|
23
|
+
{ pattern: /\b(research|investigate|analyze|analysis)\b/i, skills: ['research', 'market-research', 'competitive-analysis'] },
|
|
24
|
+
{ pattern: /\b(find leads|generate leads|prospect|outreach|prospecting)\b/i, skills: ['prospecting', 'enrichment', 'outreach'] },
|
|
25
|
+
{ pattern: /\b(enrich|validate|fill in|complete data|data quality)\b/i, skills: ['data-enrichment', 'research', 'validation'] },
|
|
26
|
+
{ pattern: /\b(seo|keyword|search visibility|content.?analysis|ranking)\b/i, skills: ['seo', 'content-analysis', 'keyword-research'] },
|
|
27
|
+
{ pattern: /\b(customer success|health score|renewal|churn|retention)\b/i, skills: ['relationship-management', 'health-scoring', 'renewal-tracking'] },
|
|
28
|
+
];
|
|
29
|
+
// Split response into sentences and look for action-oriented ones
|
|
30
|
+
const sentences = response.split(/[.!?\n]+/).map(s => s.trim()).filter(Boolean);
|
|
31
|
+
for (const sentence of sentences) {
|
|
32
|
+
for (const { pattern, skills } of skillPatterns) {
|
|
33
|
+
if (pattern.test(sentence)) {
|
|
34
|
+
// Avoid duplicates
|
|
35
|
+
if (!subTasks.some(t => t.action === sentence)) {
|
|
36
|
+
subTasks.push({ action: sentence, skills });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return subTasks;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Delegate sub-tasks to specialist agents.
|
|
45
|
+
* Non-blocking: sends steer messages to matching specialists
|
|
46
|
+
* so they pick up work on their next tick.
|
|
47
|
+
*/
|
|
48
|
+
export function delegateToSpecialists(response, specialists, queues) {
|
|
49
|
+
if (specialists.length === 0)
|
|
50
|
+
return [];
|
|
51
|
+
const subTasks = extractSubTasks(response);
|
|
52
|
+
if (subTasks.length === 0)
|
|
53
|
+
return [];
|
|
54
|
+
// Build a router with registered specialists
|
|
55
|
+
const router = new TaskRouter();
|
|
56
|
+
for (const spec of specialists) {
|
|
57
|
+
router.registerAgent(spec.config.slug, expertiseToSkills(spec.config.expertise));
|
|
58
|
+
}
|
|
59
|
+
const delegated = [];
|
|
60
|
+
for (const subTask of subTasks) {
|
|
61
|
+
const taskDef = {
|
|
62
|
+
id: `delegate-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
63
|
+
title: subTask.action,
|
|
64
|
+
description: subTask.action,
|
|
65
|
+
requiredSkills: subTask.skills,
|
|
66
|
+
priority: 'medium',
|
|
67
|
+
status: 'pending',
|
|
68
|
+
createdAt: Date.now(),
|
|
69
|
+
};
|
|
70
|
+
const best = router.findBestAgent(taskDef);
|
|
71
|
+
if (best && best.score > 0.1) {
|
|
72
|
+
// Steer the specialist with the sub-task
|
|
73
|
+
queues.steer(best.agentSlug, `[TEAM-LEAD DELEGATION] ${subTask.action}`);
|
|
74
|
+
delegated.push({ agentSlug: best.agentSlug, task: subTask.action });
|
|
75
|
+
// Ensure specialist agent tick loop is running
|
|
76
|
+
try {
|
|
77
|
+
const agentService = getAgentService();
|
|
78
|
+
agentService.ensureRunning(best.agentSlug);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// AgentService may not be initialized yet — delegation still succeeds via queue
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return delegated;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=orchestrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../../src/agent/orchestrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/agent/providers/types.ts"],"names":[],"mappings":""}
|
package/dist/agent/queues.d.ts
CHANGED
package/dist/agent/queues.js
CHANGED
|
@@ -40,5 +40,8 @@ export class MessageQueues {
|
|
|
40
40
|
const q = this.followUpQueues.get(agentSlug);
|
|
41
41
|
return q !== undefined && q.length > 0;
|
|
42
42
|
}
|
|
43
|
+
hasMessages(agentSlug) {
|
|
44
|
+
return this.hasSteer(agentSlug) || this.hasFollowUp(agentSlug);
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
47
|
//# sourceMappingURL=queues.js.map
|
package/dist/agent/queues.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queues.js","sourceRoot":"","sources":["../../src/agent/queues.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,aAAa;IAChB,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,cAAc,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,QAAQ,CAAC,GAA0B,EAAE,SAAiB;QAC5D,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;YACP,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,SAAiB,EAAE,OAAe;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ,CAAC,SAAiB,EAAE,OAAe;QACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,aAAa,CAAC,SAAiB;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"queues.js","sourceRoot":"","sources":["../../src/agent/queues.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,aAAa;IAChB,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,cAAc,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,QAAQ,CAAC,GAA0B,EAAE,SAAiB;QAC5D,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;YACP,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,SAAiB,EAAE,OAAe;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ,CAAC,SAAiB,EAAE,OAAe;QACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,aAAa,CAAC,SAAiB;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC;CACF"}
|
package/dist/agent/templates.js
CHANGED
|
@@ -37,10 +37,17 @@ export const templates = {
|
|
|
37
37
|
heartbeatCron: '0 */8 * * *',
|
|
38
38
|
tools: ['nex_search', 'nex_ask', 'nex_record_list', 'nex_record_get', 'nex_remember'],
|
|
39
39
|
},
|
|
40
|
+
'team-lead': {
|
|
41
|
+
name: 'Team Lead',
|
|
42
|
+
expertise: ['general', 'research', 'analysis', 'communication', 'planning', 'orchestration'],
|
|
43
|
+
personality: 'You are the Team Lead — the primary interface between the human and the specialist agents. You understand objectives, break them into tasks, delegate to the right specialists, and synthesize results. When the user says what they want, you figure out the path to get there using the context graph and available agents. You always respond first, then coordinate behind the scenes.',
|
|
44
|
+
heartbeatCron: 'manual',
|
|
45
|
+
tools: ['nex_search', 'nex_ask', 'nex_remember', 'nex_record_list', 'nex_record_get', 'nex_record_create', 'nex_record_update'],
|
|
46
|
+
},
|
|
40
47
|
'founding-agent': {
|
|
41
|
-
name: '
|
|
42
|
-
expertise: ['general', 'research', 'analysis', 'communication', 'planning'],
|
|
43
|
-
personality: 'Versatile and proactive. Your first AI team member — handles everything from research to outreach until specialized agents are added.',
|
|
48
|
+
name: 'Team Lead',
|
|
49
|
+
expertise: ['general', 'research', 'analysis', 'communication', 'planning', 'orchestration'],
|
|
50
|
+
personality: 'Versatile and proactive. Your first AI team member — handles everything from research to outreach until specialized agents are added. Delegates to specialists when they exist.',
|
|
44
51
|
heartbeatCron: 'daily',
|
|
45
52
|
tools: ['nex_search', 'nex_ask', 'nex_remember', 'nex_record_list', 'nex_record_get', 'nex_record_create', 'nex_record_update'],
|
|
46
53
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/agent/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,SAAS,GAA8C;IAClE,WAAW,EAAE;QACX,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,CAAC;QAC1D,WAAW,EAAE,2DAA2D;QACxE,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,CAAC;KACpE;IACD,UAAU,EAAE;QACV,IAAI,EAAE,gBAAgB;QACtB,SAAS,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC;QACpD,WAAW,EAAE,mDAAmD;QAChE,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,CAAC;KAC9E;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,CAAC,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC;QACxD,WAAW,EAAE,6CAA6C;QAC1D,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,cAAc,CAAC;KACxF;IACD,UAAU,EAAE;QACV,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC;QACxE,WAAW,EAAE,oDAAoD;QACjE,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC;KACjD;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,CAAC,yBAAyB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC;QAC5E,WAAW,EAAE,uDAAuD;QACpE,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,CAAC;KACtF;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/agent/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,SAAS,GAA8C;IAClE,WAAW,EAAE;QACX,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,CAAC;QAC1D,WAAW,EAAE,2DAA2D;QACxE,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,CAAC;KACpE;IACD,UAAU,EAAE;QACV,IAAI,EAAE,gBAAgB;QACtB,SAAS,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC;QACpD,WAAW,EAAE,mDAAmD;QAChE,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,CAAC;KAC9E;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,CAAC,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC;QACxD,WAAW,EAAE,6CAA6C;QAC1D,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,cAAc,CAAC;KACxF;IACD,UAAU,EAAE;QACV,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC;QACxE,WAAW,EAAE,oDAAoD;QACjE,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC;KACjD;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,CAAC,yBAAyB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC;QAC5E,WAAW,EAAE,uDAAuD;QACpE,aAAa,EAAE,aAAa;QAC5B,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,CAAC;KACtF;IACD,WAAW,EAAE;QACX,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,CAAC;QAC5F,WAAW,EAAE,4XAA4X;QACzY,aAAa,EAAE,QAAQ;QACvB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,CAAC;KAChI;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,CAAC;QAC5F,WAAW,EAAE,iLAAiL;QAC9L,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,mBAAmB,CAAC;KAChI;CACF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TickManager: drives agent loops on a fixed interval.
|
|
3
|
+
* Each agent gets its own setInterval; ticks are skipped
|
|
4
|
+
* when the agent is idle with no queued work.
|
|
5
|
+
*/
|
|
6
|
+
export declare class TickManager {
|
|
7
|
+
private intervals;
|
|
8
|
+
private tickRateMs;
|
|
9
|
+
constructor(tickRateMs?: number);
|
|
10
|
+
startLoop(slug: string, loop: {
|
|
11
|
+
getState(): {
|
|
12
|
+
phase: string;
|
|
13
|
+
};
|
|
14
|
+
start(): void;
|
|
15
|
+
tick(): Promise<void>;
|
|
16
|
+
}, hasWork: () => boolean): void;
|
|
17
|
+
stopLoop(slug: string): void;
|
|
18
|
+
isRunning(slug: string): boolean;
|
|
19
|
+
stopAll(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TickManager: drives agent loops on a fixed interval.
|
|
3
|
+
* Each agent gets its own setInterval; ticks are skipped
|
|
4
|
+
* when the agent is idle with no queued work.
|
|
5
|
+
*/
|
|
6
|
+
export class TickManager {
|
|
7
|
+
intervals = new Map();
|
|
8
|
+
tickRateMs;
|
|
9
|
+
constructor(tickRateMs = 500) {
|
|
10
|
+
this.tickRateMs = tickRateMs;
|
|
11
|
+
}
|
|
12
|
+
startLoop(slug, loop, hasWork) {
|
|
13
|
+
if (this.intervals.has(slug))
|
|
14
|
+
return; // idempotent
|
|
15
|
+
const interval = setInterval(async () => {
|
|
16
|
+
const state = loop.getState();
|
|
17
|
+
// Only tick if there's pending work
|
|
18
|
+
if ((state.phase === 'done' || state.phase === 'error' || state.phase === 'idle') &&
|
|
19
|
+
!hasWork()) {
|
|
20
|
+
return; // idle skip
|
|
21
|
+
}
|
|
22
|
+
if (state.phase === 'done' || state.phase === 'error') {
|
|
23
|
+
loop.start(); // reset to idle
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
await loop.tick();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
/* swallow tick errors */
|
|
30
|
+
}
|
|
31
|
+
}, this.tickRateMs);
|
|
32
|
+
this.intervals.set(slug, interval);
|
|
33
|
+
}
|
|
34
|
+
stopLoop(slug) {
|
|
35
|
+
const interval = this.intervals.get(slug);
|
|
36
|
+
if (interval) {
|
|
37
|
+
clearInterval(interval);
|
|
38
|
+
this.intervals.delete(slug);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
isRunning(slug) {
|
|
42
|
+
return this.intervals.has(slug);
|
|
43
|
+
}
|
|
44
|
+
stopAll() {
|
|
45
|
+
for (const [slug] of this.intervals) {
|
|
46
|
+
this.stopLoop(slug);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=tick-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tick-manager.js","sourceRoot":"","sources":["../../src/agent/tick-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,WAAW;IACd,SAAS,GAAG,IAAI,GAAG,EAA0C,CAAC;IAC9D,UAAU,CAAS;IAE3B,YAAY,UAAU,GAAG,GAAG;QAC1B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,SAAS,CACP,IAAY,EACZ,IAA6E,EAC7E,OAAsB;QAEtB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,aAAa;QAEnD,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,oCAAoC;YACpC,IACE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC;gBAC7E,CAAC,OAAO,EAAE,EACV,CAAC;gBACD,OAAO,CAAC,YAAY;YACtB,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;gBACtD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB;YAChC,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,aAAa,CAAC,QAAQ,CAAC,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,OAAO;QACL,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -28,6 +28,11 @@ export interface CommandContext {
|
|
|
28
28
|
* The TUI and CLI can both call this to execute commands without stdout side effects.
|
|
29
29
|
*/
|
|
30
30
|
export declare function dispatch(input: string, ctx?: CommandContext): Promise<CommandResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Dispatch from pre-tokenized args (e.g. process.argv).
|
|
33
|
+
* Use this when the shell has already handled quoting/splitting.
|
|
34
|
+
*/
|
|
35
|
+
export declare function dispatchTokens(tokens: string[], ctx?: CommandContext): Promise<CommandResult>;
|
|
31
36
|
/** All registered command names, for autocomplete. */
|
|
32
37
|
export declare const commandNames: string[];
|
|
33
38
|
/** Help entries for each command, with category and description. */
|