@intent-systems/nexus 2026.1.5-3 → 2026.1.5-5

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.
Files changed (144) hide show
  1. package/dist/agents/agent-id.js +41 -0
  2. package/dist/agents/auth-profiles.js +114 -25
  3. package/dist/agents/identity-state.js +79 -0
  4. package/dist/agents/model-auth.js +1 -0
  5. package/dist/agents/model-fallback.js +15 -9
  6. package/dist/agents/model-selection.js +1 -1
  7. package/dist/agents/models-config.js +17 -11
  8. package/dist/agents/pi-embedded-runner.js +101 -9
  9. package/dist/agents/sandbox.js +12 -3
  10. package/dist/agents/skill-runner.js +29 -4
  11. package/dist/agents/skill-usage.js +114 -11
  12. package/dist/agents/skills-status.js +4 -4
  13. package/dist/agents/skills.js +18 -7
  14. package/dist/agents/subagent-registry.js +25 -11
  15. package/dist/agents/system-prompt.js +16 -0
  16. package/dist/agents/tool-policy.js +19 -3
  17. package/dist/agents/tools/browser-tool.js +5 -2
  18. package/dist/agents/tools/image-tool.js +93 -8
  19. package/dist/agents/tools/sessions-announce-target.js +5 -1
  20. package/dist/agents/workspace.js +55 -46
  21. package/dist/auto-reply/command-detection.js +2 -1
  22. package/dist/auto-reply/reply/directive-handling.js +153 -28
  23. package/dist/auto-reply/reply/directives.js +17 -2
  24. package/dist/auto-reply/reply/model-selection.js +8 -3
  25. package/dist/auto-reply/reply/queue.js +2 -2
  26. package/dist/auto-reply/reply.js +1 -1
  27. package/dist/auto-reply/thinking.js +15 -0
  28. package/dist/browser/chrome.js +1 -1
  29. package/dist/browser/client.js +2 -0
  30. package/dist/browser/config.js +6 -2
  31. package/dist/browser/pw-tools-core.js +3 -0
  32. package/dist/browser/routes/agent.js +14 -0
  33. package/dist/canvas-host/server.js +1 -1
  34. package/dist/capabilities/detector.js +245 -0
  35. package/dist/capabilities/registry.js +99 -0
  36. package/dist/channels/location.js +44 -0
  37. package/dist/channels/web/index.js +2 -0
  38. package/dist/cli/cloud-cli.js +12 -7
  39. package/dist/cli/credential-cli.js +139 -17
  40. package/dist/cli/gateway-cli.js +1 -1
  41. package/dist/cli/log-cli.js +25 -0
  42. package/dist/cli/pairing-cli.js +1 -1
  43. package/dist/cli/program.js +58 -6
  44. package/dist/cli/run-main.js +1 -1
  45. package/dist/cli/skills-cli.js +144 -21
  46. package/dist/cli/skills-hub-cli.js +59 -29
  47. package/dist/cli/tool-connector-cli.js +99 -24
  48. package/dist/cli/upstream-sync-cli.js +253 -96
  49. package/dist/cli/usage-cli.js +14 -0
  50. package/dist/commands/auth-choice-options.js +6 -1
  51. package/dist/commands/auth-choice.js +157 -5
  52. package/dist/commands/bootstrap-preset.js +10 -6
  53. package/dist/commands/capabilities.js +33 -6
  54. package/dist/commands/claude-md.js +3 -2
  55. package/dist/commands/config-view.js +1 -1
  56. package/dist/commands/configure.js +4 -4
  57. package/dist/commands/credential.js +497 -36
  58. package/dist/commands/cursor-rules.js +39 -19
  59. package/dist/commands/doctor.js +5 -4
  60. package/dist/commands/identity.js +28 -31
  61. package/dist/commands/init.js +15 -18
  62. package/dist/commands/log.js +134 -0
  63. package/dist/commands/models/fallbacks.js +1 -1
  64. package/dist/commands/models/image-fallbacks.js +1 -1
  65. package/dist/commands/models/list.js +1 -1
  66. package/dist/commands/models/scan.js +1 -1
  67. package/dist/commands/onboard-auth.js +27 -2
  68. package/dist/commands/onboard-eve-identity.js +7 -8
  69. package/dist/commands/onboard-non-interactive.js +4 -2
  70. package/dist/commands/onboard-quickstart.js +18 -11
  71. package/dist/commands/quest-state.js +271 -0
  72. package/dist/commands/quest.js +53 -13
  73. package/dist/commands/reset.js +1 -1
  74. package/dist/commands/sessions-ingest.js +5 -4
  75. package/dist/commands/setup.js +4 -2
  76. package/dist/commands/skills-manifest.js +2 -2
  77. package/dist/commands/status.js +179 -61
  78. package/dist/commands/suggestions.js +1 -1
  79. package/dist/commands/usage-tracking.js +32 -0
  80. package/dist/commands/usage-upload.js +6 -1
  81. package/dist/config/defaults.js +1 -3
  82. package/dist/config/includes.js +5 -7
  83. package/dist/config/io.js +88 -16
  84. package/dist/config/legacy.js +4 -2
  85. package/dist/config/paths.js +16 -0
  86. package/dist/config/sessions.js +9 -5
  87. package/dist/config/zod-schema.js +4 -3
  88. package/dist/control-plane/broker/broker.js +1022 -0
  89. package/dist/control-plane/compaction.js +282 -0
  90. package/dist/control-plane/factory.js +31 -0
  91. package/dist/control-plane/index.js +10 -0
  92. package/dist/control-plane/odu/agents.js +192 -0
  93. package/dist/control-plane/odu/interaction-tools.js +208 -0
  94. package/dist/control-plane/odu/prompt-loader.js +95 -0
  95. package/dist/control-plane/odu/runtime.js +479 -0
  96. package/dist/control-plane/odu/types.js +6 -0
  97. package/dist/control-plane/odu-control-plane.js +316 -0
  98. package/dist/control-plane/single-agent.js +249 -0
  99. package/dist/control-plane/types.js +11 -0
  100. package/dist/credentials/store.js +449 -0
  101. package/dist/gateway/server-browser.js +5 -4
  102. package/dist/gateway/server-methods/cron.js +11 -1
  103. package/dist/gateway/server.js +14 -7
  104. package/dist/infra/bonjour.js +1 -1
  105. package/dist/infra/event-log.js +8 -2
  106. package/dist/infra/path-env.js +1 -2
  107. package/dist/infra/provider-usage.auth.js +5 -3
  108. package/dist/infra/provider-usage.fetch.claude.js +16 -6
  109. package/dist/infra/provider-usage.fetch.minimax.js +8 -3
  110. package/dist/infra/provider-usage.js +9 -5
  111. package/dist/infra/restart.js +2 -2
  112. package/dist/infra/usage-settings.js +78 -0
  113. package/dist/infra/usage-suggestions.js +17 -5
  114. package/dist/infra/usage-upload.js +38 -1
  115. package/dist/infra/voicewake.js +2 -2
  116. package/dist/logging/redact.js +109 -0
  117. package/dist/markdown/fences.js +58 -0
  118. package/dist/media/image-ops.js +3 -1
  119. package/dist/memory/embeddings.js +146 -0
  120. package/dist/memory/index.js +3 -0
  121. package/dist/memory/internal.js +163 -0
  122. package/dist/pairing/pairing-store.js +218 -0
  123. package/dist/plugins/cli.js +42 -0
  124. package/dist/plugins/discovery.js +253 -0
  125. package/dist/plugins/install.js +181 -0
  126. package/dist/plugins/loader.js +290 -0
  127. package/dist/plugins/registry.js +105 -0
  128. package/dist/plugins/status.js +29 -0
  129. package/dist/plugins/tools.js +39 -0
  130. package/dist/plugins/types.js +1 -0
  131. package/dist/providers/github-copilot-auth.js +1 -1
  132. package/dist/routing/resolve-route.js +144 -0
  133. package/dist/routing/session-key.js +65 -0
  134. package/dist/sessions/send-policy.js +5 -5
  135. package/dist/slack/monitor.js +22 -1
  136. package/dist/telegram/reaction-level.js +2 -1
  137. package/dist/utils/provider-utils.js +28 -0
  138. package/dist/utils.js +4 -3
  139. package/dist/wizard/onboarding.js +29 -7
  140. package/package.json +4 -29
  141. package/patches/@mariozechner__pi-ai.patch +215 -0
  142. package/patches/playwright-core@1.57.0.patch +13 -0
  143. package/patches/qrcode-terminal.patch +12 -0
  144. package/scripts/postinstall.js +202 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Interaction Agent Tools
3
+ *
4
+ * Creates tools for IAs to delegate to EAs and manage specialist agents.
5
+ * Ported from magic-toolbox/agentkit/tools/interaction-tools.ts
6
+ */
7
+ import { listAgentSessions, loadSessionMetadata, } from "../../config/sessions.js";
8
+ /**
9
+ * Create all interaction agent tools
10
+ *
11
+ * Returns tool definitions in the format expected by pi-coding-agent
12
+ */
13
+ export function createInteractionTools(_context) {
14
+ return [
15
+ {
16
+ name: "list_my_agents",
17
+ description: "List all agents you can message: your own specialist agents (by short name) and external agents that have contacted you (by full name).",
18
+ input_schema: {
19
+ type: "object",
20
+ properties: {
21
+ limit: {
22
+ type: "number",
23
+ description: "Maximum number of agents to return (default: 20)",
24
+ },
25
+ },
26
+ },
27
+ },
28
+ {
29
+ name: "send_message_to_agent",
30
+ description: 'Send a message to an EA. If task_name matches an existing EA, it will be resumed with full history. If not, a new EA will be created with that name. Use priority to control urgency: "urgent"/"high" will interrupt running EA immediately, "normal" will queue the message.',
31
+ input_schema: {
32
+ type: "object",
33
+ properties: {
34
+ task_name: {
35
+ type: "string",
36
+ description: 'Unique descriptive name for the EA (e.g., "magic-toolbox-worktrees", "merge-feature-branches")',
37
+ },
38
+ task: {
39
+ type: "string",
40
+ description: "Task description or message for the EA",
41
+ },
42
+ priority: {
43
+ type: "string",
44
+ enum: ["normal", "high", "urgent"],
45
+ description: 'Message priority: "normal" = queue (default), "high"/"urgent" = interrupt running EA immediately. Use high/urgent when: user says "stop/wait", new info invalidates current work, critical correction needed.',
46
+ default: "normal",
47
+ },
48
+ },
49
+ required: ["task_name", "task"],
50
+ },
51
+ },
52
+ {
53
+ name: "inspect_agent",
54
+ description: "Get detailed info about a specific agent (for tie-breaking when multiple agents might match)",
55
+ input_schema: {
56
+ type: "object",
57
+ properties: {
58
+ task_name: {
59
+ type: "string",
60
+ description: "The task_name of the EA to inspect",
61
+ },
62
+ },
63
+ required: ["task_name"],
64
+ },
65
+ },
66
+ ];
67
+ }
68
+ /**
69
+ * Handle tool invocation
70
+ *
71
+ * Called when a tool is invoked by the IA
72
+ */
73
+ export async function handleToolInvocation(toolName, args, context) {
74
+ const payload = args && typeof args === "object" ? args : {};
75
+ switch (toolName) {
76
+ case "list_my_agents":
77
+ return await handleListMyAgents(payload, context);
78
+ case "send_message_to_agent":
79
+ return await handleSendMessageToAgent(payload, context);
80
+ case "inspect_agent":
81
+ return await handleInspectAgent(payload, context);
82
+ default:
83
+ throw new Error(`Unknown tool: ${toolName}`);
84
+ }
85
+ }
86
+ /**
87
+ * Handle list_my_agents tool
88
+ */
89
+ async function handleListMyAgents(args, context) {
90
+ const limit = typeof args.limit === "number" && Number.isFinite(args.limit)
91
+ ? Math.max(1, Math.trunc(args.limit))
92
+ : 20;
93
+ // Get own EAs from session storage
94
+ // EAs are stored as sessions with agentType: "execution" and parentSession set
95
+ const agentId = context.agentId.replace("-ia", ""); // Convert 'toolbox-ia' to 'toolbox'
96
+ const allSessions = await listAgentSessions(agentId);
97
+ // Load metadata for each session to check agentType
98
+ const eaSessions = [];
99
+ for (const sessionKey of allSessions.slice(0, limit)) {
100
+ const metadata = await loadSessionMetadata(agentId, sessionKey);
101
+ if (metadata && metadata.agentType === "execution") {
102
+ eaSessions.push({
103
+ sessionKey,
104
+ metadata,
105
+ });
106
+ }
107
+ }
108
+ // Get external callers from broker
109
+ const externalAgentIds = context.broker.getExternalCallers(context.agentId);
110
+ // Format own EAs (show short names)
111
+ const ownFormatted = eaSessions
112
+ .map((ea) => {
113
+ const updated = ea.metadata.updated; // New format uses 'updated' (ISO string)
114
+ const lastActiveDate = updated
115
+ ? new Date(updated).toLocaleString()
116
+ : "Never";
117
+ const taskName = ea.sessionKey; // sessionKey is the task name
118
+ const displayName = ea.metadata.displayName || taskName;
119
+ const isActive = context.broker.isAgentActive(`${context.oduName}-ea-${taskName}`);
120
+ const status = isActive ? "🟢 active" : "⚪ idle";
121
+ return `• ${displayName} (${status})\n Last active: ${lastActiveDate}`;
122
+ })
123
+ .join("\n\n");
124
+ // Format external callers (show full names)
125
+ const externalFormatted = externalAgentIds.length > 0
126
+ ? externalAgentIds
127
+ .map((agentId) => {
128
+ const isActive = context.broker.isAgentActive(agentId);
129
+ const status = isActive ? "🟢 active" : "⚪ idle";
130
+ return `• ${agentId} (${status})\n External agent - has sent you messages`;
131
+ })
132
+ .join("\n\n")
133
+ : "";
134
+ // Build response
135
+ let text = "";
136
+ if (eaSessions.length > 0) {
137
+ text += `Your Specialist Agents (${eaSessions.length}):\n\n${ownFormatted}`;
138
+ }
139
+ if (externalFormatted) {
140
+ if (text)
141
+ text += "\n\n---\n\n";
142
+ text += `External Agents (${externalAgentIds.length}):\n\n${externalFormatted}`;
143
+ }
144
+ if (!text) {
145
+ text =
146
+ "No agents found. You can create a new one with send_message_to_agent.";
147
+ }
148
+ return text;
149
+ }
150
+ /**
151
+ * Handle send_message_to_agent tool
152
+ */
153
+ async function handleSendMessageToAgent(args, context) {
154
+ const taskName = typeof args.task_name === "string" ? args.task_name : "";
155
+ const task = typeof args.task === "string" ? args.task : "";
156
+ if (!taskName || !task) {
157
+ throw new Error("Invalid arguments: task_name and task are required.");
158
+ }
159
+ const priority = typeof args.priority === "string" ? args.priority : "normal";
160
+ // Convert task_name to fully-qualified EA agent ID
161
+ const eaId = `${context.oduName}-ea-${taskName}`;
162
+ // Send message via broker
163
+ await context.broker.send({
164
+ id: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
165
+ from: context.agentId,
166
+ to: eaId,
167
+ content: task,
168
+ priority: priority,
169
+ timestamp: Date.now(),
170
+ metadata: {
171
+ source: "ia",
172
+ taskName,
173
+ },
174
+ });
175
+ return `Message sent to ${taskName}. The EA will process the task and report back when complete.`;
176
+ }
177
+ /**
178
+ * Handle inspect_agent tool
179
+ */
180
+ async function handleInspectAgent(args, context) {
181
+ const taskName = typeof args.task_name === "string" ? args.task_name : "";
182
+ if (!taskName) {
183
+ throw new Error("Invalid arguments: task_name is required.");
184
+ }
185
+ const agentId = context.agentId.replace("-ia", ""); // Convert 'toolbox-ia' to 'toolbox'
186
+ // Load session metadata
187
+ const metadata = await loadSessionMetadata(agentId, taskName);
188
+ if (!metadata) {
189
+ return `EA not found: ${taskName}`;
190
+ }
191
+ const updated = metadata.updated; // New format uses 'updated' (ISO string)
192
+ const created = metadata.created; // New format uses 'created' (ISO string)
193
+ const lastActiveDate = updated ? new Date(updated).toLocaleString() : "Never";
194
+ const createdDate = created ? new Date(created).toLocaleString() : "Unknown";
195
+ const displayName = metadata.displayName || taskName;
196
+ // Check if agent is currently active
197
+ const eaId = `${context.oduName}-ea-${taskName}`;
198
+ const isActive = context.broker.isAgentActive(eaId);
199
+ const status = isActive ? "🟢 active" : "⚪ idle";
200
+ return `EA: ${displayName} (${status})
201
+
202
+ Task Name: ${taskName}
203
+ Created: ${createdDate}
204
+ Last Active: ${lastActiveDate}
205
+ Compactions: ${metadata.compactionCount || 0}
206
+
207
+ This EA specializes in: ${metadata.displayName || "general tasks"}`;
208
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Prompt Loader for ODU System Prompts
3
+ *
4
+ * Loads prompt templates from files and substitutes {{variable}} patterns.
5
+ * Similar to magic-toolbox/agentkit/prompts/loader.ts
6
+ */
7
+ import fs from "node:fs/promises";
8
+ import path from "node:path";
9
+ import { resolveUserPath } from "../../utils.js";
10
+ /**
11
+ * Cache for loaded prompts (performance optimization)
12
+ */
13
+ const promptCache = new Map();
14
+ /**
15
+ * Load a prompt template from file and substitute variables
16
+ *
17
+ * @param promptPath - Path to .md file (relative to nexus root, workspace, or absolute)
18
+ * @param variables - Variables to substitute (e.g., { oduName: "Toolbox", oduPurpose: "..." })
19
+ * @returns Loaded prompt with variables substituted
20
+ */
21
+ export async function loadPrompt(promptPath, variables = {}) {
22
+ // Resolve prompt path with precedence:
23
+ // 1. Absolute path (if provided)
24
+ // 2. Workspace prompts/ directory
25
+ // 3. Nexus bundled prompts/ directory
26
+ const resolvedPath = await resolvePromptPath(promptPath);
27
+ // Check cache first
28
+ const cacheKey = resolvedPath;
29
+ let template = promptCache.get(cacheKey);
30
+ if (!template) {
31
+ // Load from file
32
+ template = await fs.readFile(resolvedPath, "utf-8");
33
+ // Cache the template
34
+ promptCache.set(cacheKey, template);
35
+ }
36
+ // Substitute {{variable}} patterns
37
+ return substituteVariables(template, variables);
38
+ }
39
+ /**
40
+ * Resolve prompt path with precedence:
41
+ * 1. Absolute path (if provided)
42
+ * 2. Workspace prompts/ directory (if exists)
43
+ * 3. Nexus bundled prompts/ directory
44
+ *
45
+ * @param promptPath - Path to .md file (can be relative or absolute)
46
+ * @returns Absolute path to prompt file
47
+ */
48
+ async function resolvePromptPath(promptPath) {
49
+ // If absolute path, use directly
50
+ if (path.isAbsolute(promptPath)) {
51
+ return promptPath;
52
+ }
53
+ // Try workspace prompts/ directory first
54
+ const workspacePath = path.join(resolveUserPath("~/nexus/home"), "prompts", promptPath);
55
+ try {
56
+ await fs.access(workspacePath);
57
+ return workspacePath;
58
+ }
59
+ catch {
60
+ // Workspace path doesn't exist, try nexus bundled prompts
61
+ }
62
+ // Try nexus bundled prompts/ directory
63
+ // (Resolve relative to this file's directory)
64
+ const nexusRootPath = path.resolve(new URL(import.meta.url).pathname, "../../../..");
65
+ const bundledPath = path.join(nexusRootPath, "prompts", promptPath);
66
+ try {
67
+ await fs.access(bundledPath);
68
+ return bundledPath;
69
+ }
70
+ catch {
71
+ throw new Error(`Prompt file not found: ${promptPath} (tried workspace and bundled prompts)`);
72
+ }
73
+ }
74
+ /**
75
+ * Substitute {{variable}} patterns in template
76
+ *
77
+ * @param template - Template string with {{variable}} patterns
78
+ * @param variables - Variables to substitute
79
+ * @returns Template with variables substituted
80
+ */
81
+ function substituteVariables(template, variables) {
82
+ let result = template;
83
+ // Replace all {{variable}} patterns
84
+ for (const [key, value] of Object.entries(variables)) {
85
+ const pattern = new RegExp(`\\{\\{${key}\\}\\}`, "g");
86
+ result = result.replace(pattern, value);
87
+ }
88
+ return result;
89
+ }
90
+ /**
91
+ * Clear the prompt cache (useful for testing or hot-reloading)
92
+ */
93
+ export function clearPromptCache() {
94
+ promptCache.clear();
95
+ }