@synergenius/flow-weaver-pack-weaver 0.9.7 → 0.9.9
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/dist/bot/agent-loop.d.ts +20 -0
- package/dist/bot/agent-loop.d.ts.map +1 -0
- package/dist/bot/agent-loop.js +331 -0
- package/dist/bot/agent-loop.js.map +1 -0
- package/dist/bot/agent-provider.d.ts.map +1 -1
- package/dist/bot/agent-provider.js +3 -2
- package/dist/bot/agent-provider.js.map +1 -1
- package/dist/bot/approvals.js +17 -8
- package/dist/bot/approvals.js.map +1 -1
- package/dist/bot/assistant-core.d.ts +17 -0
- package/dist/bot/assistant-core.d.ts.map +1 -1
- package/dist/bot/assistant-core.js +418 -60
- package/dist/bot/assistant-core.js.map +1 -1
- package/dist/bot/assistant-tools.d.ts +1 -1
- package/dist/bot/assistant-tools.d.ts.map +1 -1
- package/dist/bot/assistant-tools.js +283 -9
- package/dist/bot/assistant-tools.js.map +1 -1
- package/dist/bot/bot-agent-channel.d.ts.map +1 -1
- package/dist/bot/bot-agent-channel.js +2 -0
- package/dist/bot/bot-agent-channel.js.map +1 -1
- package/dist/bot/bot-manager.d.ts +4 -0
- package/dist/bot/bot-manager.d.ts.map +1 -1
- package/dist/bot/bot-manager.js +72 -27
- package/dist/bot/bot-manager.js.map +1 -1
- package/dist/bot/conversation-store.d.ts +6 -5
- package/dist/bot/conversation-store.d.ts.map +1 -1
- package/dist/bot/conversation-store.js +98 -42
- package/dist/bot/conversation-store.js.map +1 -1
- package/dist/bot/cost-store.d.ts +3 -0
- package/dist/bot/cost-store.d.ts.map +1 -1
- package/dist/bot/cost-store.js +21 -10
- package/dist/bot/cost-store.js.map +1 -1
- package/dist/bot/cost-tracker.d.ts.map +1 -1
- package/dist/bot/cost-tracker.js +14 -1
- package/dist/bot/cost-tracker.js.map +1 -1
- package/dist/bot/cron-parser.d.ts.map +1 -1
- package/dist/bot/cron-parser.js +2 -0
- package/dist/bot/cron-parser.js.map +1 -1
- package/dist/bot/cron-scheduler.d.ts.map +1 -1
- package/dist/bot/cron-scheduler.js +1 -0
- package/dist/bot/cron-scheduler.js.map +1 -1
- package/dist/bot/device-connection.d.ts +13 -0
- package/dist/bot/device-connection.d.ts.map +1 -0
- package/dist/bot/device-connection.js +102 -0
- package/dist/bot/device-connection.js.map +1 -0
- package/dist/bot/error-classifier.d.ts.map +1 -1
- package/dist/bot/error-classifier.js +5 -0
- package/dist/bot/error-classifier.js.map +1 -1
- package/dist/bot/file-lock.d.ts.map +1 -1
- package/dist/bot/file-lock.js +13 -3
- package/dist/bot/file-lock.js.map +1 -1
- package/dist/bot/file-watcher.d.ts.map +1 -1
- package/dist/bot/file-watcher.js +1 -0
- package/dist/bot/file-watcher.js.map +1 -1
- package/dist/bot/genesis-prompt-context.d.ts +5 -0
- package/dist/bot/genesis-prompt-context.d.ts.map +1 -1
- package/dist/bot/genesis-prompt-context.js +55 -0
- package/dist/bot/genesis-prompt-context.js.map +1 -1
- package/dist/bot/genesis-store.d.ts +4 -0
- package/dist/bot/genesis-store.d.ts.map +1 -1
- package/dist/bot/genesis-store.js +79 -12
- package/dist/bot/genesis-store.js.map +1 -1
- package/dist/bot/improve-loop.d.ts +46 -0
- package/dist/bot/improve-loop.d.ts.map +1 -0
- package/dist/bot/improve-loop.js +592 -0
- package/dist/bot/improve-loop.js.map +1 -0
- package/dist/bot/insight-engine.d.ts +12 -0
- package/dist/bot/insight-engine.d.ts.map +1 -0
- package/dist/bot/insight-engine.js +256 -0
- package/dist/bot/insight-engine.js.map +1 -0
- package/dist/bot/knowledge-store.d.ts.map +1 -1
- package/dist/bot/knowledge-store.js +4 -1
- package/dist/bot/knowledge-store.js.map +1 -1
- package/dist/bot/pipeline-runner.d.ts.map +1 -1
- package/dist/bot/pipeline-runner.js +12 -4
- package/dist/bot/pipeline-runner.js.map +1 -1
- package/dist/bot/project-model.d.ts +25 -0
- package/dist/bot/project-model.d.ts.map +1 -0
- package/dist/bot/project-model.js +372 -0
- package/dist/bot/project-model.js.map +1 -0
- package/dist/bot/response-formatter.js +2 -3
- package/dist/bot/response-formatter.js.map +1 -1
- package/dist/bot/run-store.d.ts.map +1 -1
- package/dist/bot/run-store.js +10 -2
- package/dist/bot/run-store.js.map +1 -1
- package/dist/bot/safe-path.d.ts +1 -1
- package/dist/bot/safe-path.d.ts.map +1 -1
- package/dist/bot/safe-path.js +20 -1
- package/dist/bot/safe-path.js.map +1 -1
- package/dist/bot/safety.d.ts +10 -2
- package/dist/bot/safety.d.ts.map +1 -1
- package/dist/bot/safety.js +45 -2
- package/dist/bot/safety.js.map +1 -1
- package/dist/bot/session-state.d.ts +4 -0
- package/dist/bot/session-state.d.ts.map +1 -1
- package/dist/bot/session-state.js +52 -9
- package/dist/bot/session-state.js.map +1 -1
- package/dist/bot/slash-commands.d.ts.map +1 -1
- package/dist/bot/slash-commands.js +109 -3
- package/dist/bot/slash-commands.js.map +1 -1
- package/dist/bot/steering-engine.d.ts +67 -0
- package/dist/bot/steering-engine.d.ts.map +1 -0
- package/dist/bot/steering-engine.js +198 -0
- package/dist/bot/steering-engine.js.map +1 -0
- package/dist/bot/step-executor.d.ts.map +1 -1
- package/dist/bot/step-executor.js +62 -25
- package/dist/bot/step-executor.js.map +1 -1
- package/dist/bot/system-prompt.d.ts.map +1 -1
- package/dist/bot/system-prompt.js +5 -2
- package/dist/bot/system-prompt.js.map +1 -1
- package/dist/bot/task-queue.d.ts +6 -1
- package/dist/bot/task-queue.d.ts.map +1 -1
- package/dist/bot/task-queue.js +43 -4
- package/dist/bot/task-queue.js.map +1 -1
- package/dist/bot/tool-registry.d.ts +1 -1
- package/dist/bot/tool-registry.d.ts.map +1 -1
- package/dist/bot/tool-registry.js +65 -4
- package/dist/bot/tool-registry.js.map +1 -1
- package/dist/bot/trust-calculator.d.ts +34 -0
- package/dist/bot/trust-calculator.d.ts.map +1 -0
- package/dist/bot/trust-calculator.js +67 -0
- package/dist/bot/trust-calculator.js.map +1 -0
- package/dist/bot/types.d.ts +97 -0
- package/dist/bot/types.d.ts.map +1 -1
- package/dist/bot/update-checker.d.ts +21 -0
- package/dist/bot/update-checker.d.ts.map +1 -0
- package/dist/bot/update-checker.js +129 -0
- package/dist/bot/update-checker.js.map +1 -0
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +11 -4
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/cli-bridge.d.ts +2 -0
- package/dist/cli-bridge.d.ts.map +1 -1
- package/dist/cli-bridge.js +3 -1
- package/dist/cli-bridge.js.map +1 -1
- package/dist/cli-handlers.d.ts +10 -1
- package/dist/cli-handlers.d.ts.map +1 -1
- package/dist/cli-handlers.js +141 -24
- package/dist/cli-handlers.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +749 -0
- package/dist/cli.js.map +1 -0
- package/dist/docs/weaver-config.md +15 -9
- package/dist/handlers/on-execution-completed.d.ts +11 -0
- package/dist/handlers/on-execution-completed.d.ts.map +1 -0
- package/dist/handlers/on-execution-completed.js +25 -0
- package/dist/handlers/on-execution-completed.js.map +1 -0
- package/dist/mcp-tools.d.ts.map +1 -1
- package/dist/mcp-tools.js +33 -0
- package/dist/mcp-tools.js.map +1 -1
- package/dist/node-types/genesis-approve.d.ts.map +1 -1
- package/dist/node-types/genesis-approve.js +28 -3
- package/dist/node-types/genesis-approve.js.map +1 -1
- package/dist/node-types/genesis-observe.d.ts.map +1 -1
- package/dist/node-types/genesis-observe.js +23 -13
- package/dist/node-types/genesis-observe.js.map +1 -1
- package/dist/node-types/genesis-propose.d.ts.map +1 -1
- package/dist/node-types/genesis-propose.js +8 -0
- package/dist/node-types/genesis-propose.js.map +1 -1
- package/dist/node-types/genesis-update-history.d.ts.map +1 -1
- package/dist/node-types/genesis-update-history.js +13 -0
- package/dist/node-types/genesis-update-history.js.map +1 -1
- package/dist/templates/weaver-template.d.ts +11 -0
- package/dist/templates/weaver-template.d.ts.map +1 -0
- package/dist/templates/weaver-template.js +53 -0
- package/dist/templates/weaver-template.js.map +1 -0
- package/dist/workflows/weaver-bot-session.d.ts +65 -0
- package/dist/workflows/weaver-bot-session.d.ts.map +1 -0
- package/dist/workflows/weaver-bot-session.js +68 -0
- package/dist/workflows/weaver-bot-session.js.map +1 -0
- package/dist/workflows/weaver.d.ts +24 -0
- package/dist/workflows/weaver.d.ts.map +1 -0
- package/dist/workflows/weaver.js +28 -0
- package/dist/workflows/weaver.js.map +1 -0
- package/flowweaver.manifest.json +28 -1
- package/package.json +6 -3
- package/src/bot/agent-provider.ts +3 -2
- package/src/bot/approvals.ts +16 -8
- package/src/bot/assistant-core.ts +420 -63
- package/src/bot/assistant-tools.ts +291 -9
- package/src/bot/bot-agent-channel.ts +2 -0
- package/src/bot/bot-manager.ts +70 -29
- package/src/bot/conversation-store.ts +87 -42
- package/src/bot/cost-store.ts +20 -9
- package/src/bot/cost-tracker.ts +13 -1
- package/src/bot/cron-parser.ts +1 -0
- package/src/bot/cron-scheduler.ts +1 -0
- package/src/bot/device-connection.ts +102 -0
- package/src/bot/error-classifier.ts +5 -0
- package/src/bot/file-lock.ts +12 -2
- package/src/bot/file-watcher.ts +1 -0
- package/src/bot/genesis-prompt-context.ts +61 -0
- package/src/bot/genesis-store.ts +68 -16
- package/src/bot/improve-loop.ts +651 -0
- package/src/bot/insight-engine.ts +273 -0
- package/src/bot/knowledge-store.ts +4 -1
- package/src/bot/pipeline-runner.ts +11 -6
- package/src/bot/project-model.ts +404 -0
- package/src/bot/response-formatter.ts +2 -3
- package/src/bot/run-store.ts +5 -2
- package/src/bot/safe-path.ts +20 -1
- package/src/bot/safety.ts +57 -3
- package/src/bot/session-state.ts +47 -7
- package/src/bot/slash-commands.ts +111 -3
- package/src/bot/steering-engine.ts +233 -0
- package/src/bot/step-executor.ts +66 -26
- package/src/bot/system-prompt.ts +5 -2
- package/src/bot/task-queue.ts +40 -4
- package/src/bot/tool-registry.ts +67 -5
- package/src/bot/trust-calculator.ts +87 -0
- package/src/bot/types.ts +104 -0
- package/src/bot/update-checker.ts +138 -0
- package/src/bot/weaver-tools.ts +10 -4
- package/src/cli-bridge.ts +4 -1
- package/src/cli-handlers.ts +150 -29
- package/src/handlers/on-execution-completed.ts +30 -0
- package/src/mcp-tools.ts +38 -0
- package/src/node-types/genesis-approve.ts +28 -3
- package/src/node-types/genesis-observe.ts +23 -12
- package/src/node-types/genesis-propose.ts +8 -0
- package/src/node-types/genesis-update-history.ts +12 -0
- package/src/ui/evolution-panel.tsx +96 -0
- package/src/ui/insights-widget.tsx +77 -0
|
@@ -14,38 +14,69 @@ import { c } from './ansi.js';
|
|
|
14
14
|
import { VERBOSE_TOOL_NAMES } from './tool-registry.js';
|
|
15
15
|
import { generateToolPromptSection, generateVerboseToolList } from './tool-registry.js';
|
|
16
16
|
import { CHARS_PER_TOKEN } from './safety.js';
|
|
17
|
-
const DEFAULT_SYSTEM_PROMPT = `You are Weaver
|
|
17
|
+
const DEFAULT_SYSTEM_PROMPT = `You are Weaver — a hands-on AI assistant for Flow Weaver projects.
|
|
18
18
|
|
|
19
|
-
You help
|
|
19
|
+
You help people build, validate, debug, and manage workflows. You can also spawn autonomous bot workers that execute tasks in the background.
|
|
20
|
+
|
|
21
|
+
## What you do
|
|
22
|
+
|
|
23
|
+
Tell me what you want to build or fix. I will:
|
|
24
|
+
1. Break it into steps
|
|
25
|
+
2. Use tools to read, write, validate, and test code
|
|
26
|
+
3. Spawn bots for longer tasks that run in the background
|
|
27
|
+
4. Track project health and surface insights proactively
|
|
28
|
+
5. Propose bot workflow improvements based on execution patterns
|
|
29
|
+
6. Report results — not plans
|
|
30
|
+
|
|
31
|
+
## How to respond
|
|
32
|
+
|
|
33
|
+
Be direct and helpful. Adapt to the user — explain more for beginners, less for experts.
|
|
34
|
+
When someone asks "what can you do", give a SHORT overview (5-6 lines max), not an exhaustive list. Mention /help for the full reference.
|
|
35
|
+
|
|
36
|
+
USE TOOLS to fulfill requests. Don't describe what you'd do — do it.
|
|
37
|
+
When asked to start a bot, call bot_spawn. For status, call bot_list. For tasks, call queue_add.
|
|
38
|
+
|
|
39
|
+
## Available tools
|
|
20
40
|
|
|
21
41
|
${generateToolPromptSection()}
|
|
22
|
-
USE TOOLS to fulfill requests. Don't describe what you'd do — actually do it.
|
|
23
|
-
When the user asks to "start a bot", call bot_spawn.
|
|
24
|
-
When they ask for status, call bot_list or bot_status.
|
|
25
|
-
When they ask to add tasks, call queue_add or queue_add_batch.
|
|
26
42
|
|
|
27
|
-
|
|
28
|
-
The user is a senior engineer — don't over-explain.
|
|
43
|
+
## Terminal output rules
|
|
29
44
|
|
|
30
|
-
|
|
31
|
-
- No **bold**,
|
|
32
|
-
- No emoji
|
|
33
|
-
- Use plain
|
|
34
|
-
-
|
|
35
|
-
- For lists, use simple dashes: - item
|
|
36
|
-
- For key-value pairs, use: key: value (one per line)
|
|
37
|
-
- Keep output scannable and clean
|
|
45
|
+
You are running in a terminal. Plain text only.
|
|
46
|
+
- No markdown: no **bold**, \`backticks\`, or |tables|
|
|
47
|
+
- No emoji
|
|
48
|
+
- Use plain dashes for lists, UPPERCASE or "quotes" for emphasis
|
|
49
|
+
- Keep responses concise and scannable
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
## Tool output handling
|
|
52
|
+
|
|
53
|
+
CRITICAL: These tools display their FULL output directly to the user:
|
|
41
54
|
${generateVerboseToolList()}
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
The user ALREADY SEES the complete output from these tools. After calling them:
|
|
56
|
+
- Do NOT list, enumerate, or walk through the output
|
|
57
|
+
- Do NOT restate what the diagram/description shows
|
|
58
|
+
- ONLY add a brief insight the user cannot see (e.g. "Notice the fan-out at step 5 — that's where parallelism happens")
|
|
59
|
+
- If the output speaks for itself, say nothing or just "There it is."
|
|
60
|
+
For all other tools, you may explain the result briefly.
|
|
61
|
+
|
|
62
|
+
## Personality
|
|
63
|
+
|
|
64
|
+
- Helpful, practical, no fluff
|
|
65
|
+
- Lead with the RESULT, not narration of what you did. Never start with "Let me...", "Found it.", "Now let me...", "Good, I have..."
|
|
66
|
+
- If something fails, say what went wrong and what you'll try next
|
|
67
|
+
- Never apologize for tool usage — tools are how you work
|
|
68
|
+
- When you don't know something, say so
|
|
44
69
|
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
## Project intelligence
|
|
71
|
+
|
|
72
|
+
You have access to project health, bot performance, failure patterns, cost trends, and evolution history.
|
|
73
|
+
Be proactive: when you see something relevant to what the user is doing, mention it.
|
|
74
|
+
At session start, briefly acknowledge the project state if there's something worth noting.
|
|
75
|
+
You can propose workflow improvements with genesis_propose when patterns suggest a structural fix.
|
|
76
|
+
If a bot workflow needs modification and isn't ejected yet, auto-eject it first.`;
|
|
47
77
|
export async function runAssistant(opts) {
|
|
48
78
|
const { provider, tools, executor, projectDir } = opts;
|
|
79
|
+
const isDebug = !!opts.debug;
|
|
49
80
|
const out = (s) => process.stderr.write(s);
|
|
50
81
|
// Pipe mode: if stdin is not a TTY, read all input as one message
|
|
51
82
|
if (!process.stdin.isTTY && !opts.inputMessages) {
|
|
@@ -54,8 +85,10 @@ export async function runAssistant(opts) {
|
|
|
54
85
|
chunks.push(typeof chunk === 'string' ? chunk : chunk.toString());
|
|
55
86
|
}
|
|
56
87
|
const pipeInput = chunks.join('').trim();
|
|
57
|
-
if (!pipeInput)
|
|
88
|
+
if (!pipeInput) {
|
|
89
|
+
process.stderr.write(' No input provided. Pipe a message: echo "describe my workflows" | flow-weaver weaver assistant\n');
|
|
58
90
|
return;
|
|
91
|
+
}
|
|
59
92
|
// Build system prompt for pipe mode
|
|
60
93
|
let systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
61
94
|
try {
|
|
@@ -68,6 +101,16 @@ export async function runAssistant(opts) {
|
|
|
68
101
|
}
|
|
69
102
|
}
|
|
70
103
|
catch { /* plan not available */ }
|
|
104
|
+
// Inject project intelligence (ambient awareness)
|
|
105
|
+
try {
|
|
106
|
+
const { ProjectModelStore } = await import('./project-model.js');
|
|
107
|
+
const pms = new ProjectModelStore(projectDir);
|
|
108
|
+
const model = await pms.getOrBuild();
|
|
109
|
+
if (model && (model.health.workflows.length > 0 || model.bots.length > 0)) {
|
|
110
|
+
systemPrompt += '\n\n## Project Intelligence\n\n' + pms.formatSummary(model);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch { /* project model not available yet */ }
|
|
71
114
|
// Run single message, print result, exit
|
|
72
115
|
await runAgentLoop(provider, tools, executor, [{ role: 'user', content: pipeInput }], {
|
|
73
116
|
systemPrompt, maxIterations: 20,
|
|
@@ -77,7 +120,7 @@ export async function runAssistant(opts) {
|
|
|
77
120
|
if (e.type === 'tool_call_start')
|
|
78
121
|
out(`\n ${c.cyan('◆')} ${e.name}\n`);
|
|
79
122
|
if (e.type === 'tool_call_result')
|
|
80
|
-
out(` ${c.dim('→')} ${(e.result ?? '').slice(0,
|
|
123
|
+
out(` ${c.dim('→')} ${(e.result ?? '').slice(0, 500)}\n`);
|
|
81
124
|
},
|
|
82
125
|
});
|
|
83
126
|
out('\n');
|
|
@@ -95,6 +138,83 @@ export async function runAssistant(opts) {
|
|
|
95
138
|
}
|
|
96
139
|
}
|
|
97
140
|
catch { /* plan not available */ }
|
|
141
|
+
// Load steering configuration
|
|
142
|
+
let steeringEngine;
|
|
143
|
+
try {
|
|
144
|
+
const { SteeringEngine, loadSteers } = await import('./steering-engine.js');
|
|
145
|
+
const steers = loadSteers(projectDir);
|
|
146
|
+
steeringEngine = new SteeringEngine(steers);
|
|
147
|
+
}
|
|
148
|
+
catch { /* steering not available */ }
|
|
149
|
+
// Inject project intelligence (ambient awareness)
|
|
150
|
+
try {
|
|
151
|
+
const { ProjectModelStore } = await import('./project-model.js');
|
|
152
|
+
const pms = new ProjectModelStore(projectDir);
|
|
153
|
+
const model = await pms.getOrBuild();
|
|
154
|
+
if (model && (model.health.workflows.length > 0 || model.bots.length > 0)) {
|
|
155
|
+
systemPrompt += '\n\n## Project Intelligence\n\n' + pms.formatSummary(model);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch { /* project model not available yet */ }
|
|
159
|
+
// Auto-context scan: on first-ever use, scan project and persist context in knowledge store
|
|
160
|
+
try {
|
|
161
|
+
const { KnowledgeStore } = await import('./knowledge-store.js');
|
|
162
|
+
const knowledge = new KnowledgeStore(projectDir);
|
|
163
|
+
const existing = knowledge.recall('project:context');
|
|
164
|
+
if (existing.length === 0) {
|
|
165
|
+
// First-ever scan — build project context
|
|
166
|
+
const fsMod = await import('node:fs');
|
|
167
|
+
const parts = [];
|
|
168
|
+
// Package info
|
|
169
|
+
const pkgPath = path.join(projectDir, 'package.json');
|
|
170
|
+
if (fsMod.existsSync(pkgPath)) {
|
|
171
|
+
try {
|
|
172
|
+
const pkg = JSON.parse(fsMod.readFileSync(pkgPath, 'utf-8'));
|
|
173
|
+
parts.push(`Project: ${pkg.name ?? 'unknown'} v${pkg.version ?? '0.0.0'}`);
|
|
174
|
+
if (pkg.description)
|
|
175
|
+
parts.push(`Description: ${pkg.description}`);
|
|
176
|
+
const deps = Object.keys(pkg.dependencies ?? {}).slice(0, 10);
|
|
177
|
+
if (deps.length > 0)
|
|
178
|
+
parts.push(`Key deps: ${deps.join(', ')}`);
|
|
179
|
+
}
|
|
180
|
+
catch { /* parse failed */ }
|
|
181
|
+
}
|
|
182
|
+
// Workflow scan
|
|
183
|
+
try {
|
|
184
|
+
const { execFileSync: scanExec } = await import('node:child_process');
|
|
185
|
+
const found = scanExec('npx', ['flow-weaver', 'find-workflows', '--json'], {
|
|
186
|
+
encoding: 'utf-8', cwd: projectDir, timeout: 10_000, stdio: ['pipe', 'pipe', 'pipe'],
|
|
187
|
+
});
|
|
188
|
+
const workflows = JSON.parse(found);
|
|
189
|
+
if (Array.isArray(workflows) && workflows.length > 0) {
|
|
190
|
+
parts.push(`Workflows (${workflows.length}): ${workflows.map((w) => w.name ?? w.file ?? 'unknown').join(', ')}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch { /* find-workflows failed */ }
|
|
194
|
+
// TypeScript config
|
|
195
|
+
const tsConfigPath = path.join(projectDir, 'tsconfig.json');
|
|
196
|
+
if (fsMod.existsSync(tsConfigPath))
|
|
197
|
+
parts.push('TypeScript: yes');
|
|
198
|
+
// Weaver config
|
|
199
|
+
const weaverConfigPath = path.join(projectDir, '.weaver.json');
|
|
200
|
+
if (fsMod.existsSync(weaverConfigPath)) {
|
|
201
|
+
try {
|
|
202
|
+
const wc = JSON.parse(fsMod.readFileSync(weaverConfigPath, 'utf-8'));
|
|
203
|
+
parts.push(`Weaver provider: ${typeof wc.provider === 'string' ? wc.provider : wc.provider?.name ?? 'auto'}`);
|
|
204
|
+
}
|
|
205
|
+
catch { /* parse failed */ }
|
|
206
|
+
}
|
|
207
|
+
if (parts.length > 0) {
|
|
208
|
+
knowledge.learn('project:context', parts.join('\n'), 'auto-scan');
|
|
209
|
+
systemPrompt += '\n\n## Project Context (auto-scanned)\n\n' + parts.join('\n');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Context already scanned — inject from knowledge store
|
|
214
|
+
systemPrompt += '\n\n## Project Context\n\n' + existing[0].value;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch { /* knowledge store not available */ }
|
|
98
218
|
// Persistent conversation store
|
|
99
219
|
const { ConversationStore } = await import('./conversation-store.js');
|
|
100
220
|
const store = new ConversationStore();
|
|
@@ -112,7 +232,7 @@ export async function runAssistant(opts) {
|
|
|
112
232
|
compressHistory(history);
|
|
113
233
|
}
|
|
114
234
|
else if (opts.newConversation) {
|
|
115
|
-
conversation = store.create(projectDir);
|
|
235
|
+
conversation = await store.create(projectDir);
|
|
116
236
|
}
|
|
117
237
|
else {
|
|
118
238
|
// Auto-resume most recent if within 1 hour, else create new
|
|
@@ -123,7 +243,7 @@ export async function runAssistant(opts) {
|
|
|
123
243
|
compressHistory(history);
|
|
124
244
|
}
|
|
125
245
|
else {
|
|
126
|
-
conversation = store.create(projectDir);
|
|
246
|
+
conversation = await store.create(projectDir);
|
|
127
247
|
}
|
|
128
248
|
}
|
|
129
249
|
// Resolve versions
|
|
@@ -137,23 +257,113 @@ export async function runAssistant(opts) {
|
|
|
137
257
|
try {
|
|
138
258
|
const fsMod = await import('node:fs');
|
|
139
259
|
const url = await import('node:url');
|
|
140
|
-
const packPkg = JSON.parse(fsMod.readFileSync(new url.URL('
|
|
260
|
+
const packPkg = JSON.parse(fsMod.readFileSync(new url.URL('../../package.json', import.meta.url), 'utf-8'));
|
|
141
261
|
weaverVersion = packPkg.version;
|
|
142
262
|
}
|
|
143
263
|
catch { /* not available */ }
|
|
144
|
-
// Welcome
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
264
|
+
// Welcome — detect cloud status from credentials
|
|
265
|
+
let cloudStatus = '';
|
|
266
|
+
let cloudPlan = '';
|
|
267
|
+
try {
|
|
268
|
+
const credPath = path.join(os.homedir(), '.fw', 'credentials.json');
|
|
269
|
+
const fsMod = await import('node:fs');
|
|
270
|
+
if (fsMod.existsSync(credPath)) {
|
|
271
|
+
const creds = JSON.parse(fsMod.readFileSync(credPath, 'utf-8'));
|
|
272
|
+
if (creds.token && creds.expiresAt > Date.now()) {
|
|
273
|
+
cloudPlan = creds.plan ?? 'connected';
|
|
274
|
+
cloudStatus = `Cloud: ${cloudPlan}`;
|
|
275
|
+
}
|
|
276
|
+
else if (creds.token) {
|
|
277
|
+
cloudStatus = 'Cloud: expired (run "fw login" to refresh)';
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
catch { /* credentials not available */ }
|
|
282
|
+
// Detect first-run: scan for existing workflows and conversation count
|
|
283
|
+
let workflowCount = 0;
|
|
284
|
+
let projectName = path.basename(projectDir);
|
|
285
|
+
let packageDesc = '';
|
|
286
|
+
let isFirstRun = !conversation.title;
|
|
287
|
+
try {
|
|
288
|
+
const fsMod = await import('node:fs');
|
|
289
|
+
const pkgPath = path.join(projectDir, 'package.json');
|
|
290
|
+
if (fsMod.existsSync(pkgPath)) {
|
|
291
|
+
const pkg = JSON.parse(fsMod.readFileSync(pkgPath, 'utf-8'));
|
|
292
|
+
projectName = pkg.name ?? projectName;
|
|
293
|
+
packageDesc = pkg.description ?? '';
|
|
294
|
+
}
|
|
295
|
+
const { execFileSync: fwExec } = await import('node:child_process');
|
|
296
|
+
try {
|
|
297
|
+
const found = fwExec('npx', ['flow-weaver', 'find-workflows', '--json'], {
|
|
298
|
+
encoding: 'utf-8', cwd: projectDir, timeout: 10_000, stdio: ['pipe', 'pipe', 'pipe'],
|
|
299
|
+
});
|
|
300
|
+
const parsed = JSON.parse(found);
|
|
301
|
+
workflowCount = Array.isArray(parsed) ? parsed.length : (parsed.count ?? 0);
|
|
302
|
+
}
|
|
303
|
+
catch { /* find-workflows not available */ }
|
|
148
304
|
}
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
305
|
+
catch { /* scan failed */ }
|
|
306
|
+
if (!isDebug) {
|
|
307
|
+
const header = [`weaver assistant v${weaverVersion}`, `flow-weaver v${fwVersion}`];
|
|
308
|
+
if (cloudStatus)
|
|
309
|
+
header.push(cloudStatus);
|
|
310
|
+
out(`\n ${c.bold(header[0])} ${c.dim(`· ${header.slice(1).join(' · ')}`)}\n`);
|
|
311
|
+
out(` ${c.dim(`Project: ${projectName}`)}\n`);
|
|
312
|
+
if (!cloudStatus) {
|
|
313
|
+
out(` ${c.dim('AI: Local (set ANTHROPIC_API_KEY or run "fw login" to connect)')}\n`);
|
|
314
|
+
}
|
|
315
|
+
if (conversation.title) {
|
|
316
|
+
const ago = Math.round((Date.now() - conversation.lastMessageAt) / 60000);
|
|
317
|
+
out(` ${c.dim(`Resuming: "${conversation.title}" (${conversation.messageCount} messages, ${ago}m ago). /new to start fresh`)}\n`);
|
|
318
|
+
}
|
|
319
|
+
else if (workflowCount === 0 && isFirstRun) {
|
|
320
|
+
out(` ${c.dim('Welcome! No workflows found yet.')}\n`);
|
|
321
|
+
out(` ${c.dim('Try: "create a hello world workflow" or "what can you do?"')}\n`);
|
|
322
|
+
}
|
|
323
|
+
else if (workflowCount > 0 && isFirstRun) {
|
|
324
|
+
out(` ${c.dim(`Found ${workflowCount} workflow${workflowCount !== 1 ? 's' : ''}. New conversation.`)}\n`);
|
|
325
|
+
out(` ${c.dim('Try: "validate my workflows" or "show project health"')}\n`);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
out(` ${c.dim('Type your request. /help for commands.')}\n`);
|
|
329
|
+
}
|
|
330
|
+
out('\n');
|
|
152
331
|
}
|
|
153
|
-
|
|
154
|
-
|
|
332
|
+
// Proactive session greeting with project status (for returning users with data)
|
|
333
|
+
if (!isDebug && !isFirstRun) {
|
|
334
|
+
try {
|
|
335
|
+
const { ProjectModelStore } = await import('./project-model.js');
|
|
336
|
+
const pms = new ProjectModelStore(projectDir);
|
|
337
|
+
const model = await pms.getOrBuild();
|
|
338
|
+
if (model && (model.health.workflows.length > 0 || model.bots.length > 0)) {
|
|
339
|
+
out(` ${c.dim(pms.formatSessionGreeting(model))}\n`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
catch { /* project model not available yet */ }
|
|
343
|
+
}
|
|
344
|
+
// Check for updates (cached, max once per 24h, non-blocking)
|
|
345
|
+
if (!isDebug) {
|
|
346
|
+
try {
|
|
347
|
+
const { checkForUpdates, formatUpdateNotification } = await import('./update-checker.js');
|
|
348
|
+
const updates = await checkForUpdates(projectDir);
|
|
349
|
+
const notification = formatUpdateNotification(updates);
|
|
350
|
+
if (notification) {
|
|
351
|
+
out(` ${c.yellow('⬆')} ${c.dim(notification.split('\n')[0])}\n`);
|
|
352
|
+
systemPrompt += `\n\n## Update Available\n\n${notification}\nMention this to the user if relevant.`;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch { /* update check failed — non-fatal */ }
|
|
356
|
+
}
|
|
357
|
+
// Inject first-run context into system prompt so the assistant adapts
|
|
358
|
+
if (workflowCount === 0 && isFirstRun) {
|
|
359
|
+
systemPrompt += '\n\n## First-Run Context\n\nThis is a NEW user with NO workflows yet. Be welcoming. Suggest creating their first workflow. If they describe what they want to build, offer to create it immediately. Do NOT assume they know Flow Weaver concepts — explain briefly as you go.';
|
|
360
|
+
if (packageDesc) {
|
|
361
|
+
systemPrompt += `\nProject description: "${packageDesc}". Use this to suggest a relevant first workflow.`;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else if (workflowCount > 0 && isFirstRun) {
|
|
365
|
+
systemPrompt += `\n\n## First Conversation Context\n\nThis user has ${workflowCount} existing workflow${workflowCount !== 1 ? 's' : ''} but this is their first conversation with you. Offer to validate, describe, or improve their workflows. Be helpful but don't assume they're a beginner.`;
|
|
155
366
|
}
|
|
156
|
-
out(` ${c.dim('Type your request. Ctrl+C to exit. /help for commands.')}\n\n`);
|
|
157
367
|
// Rich input with history, arrows, tab completion, slash commands
|
|
158
368
|
const { RichInput } = await import('./rich-input.js');
|
|
159
369
|
const { getSlashCompletions, handleSlashCommand } = await import('./slash-commands.js');
|
|
@@ -173,30 +383,77 @@ export async function runAssistant(opts) {
|
|
|
173
383
|
return () => Promise.resolve(opts.inputMessages[i++] ?? null);
|
|
174
384
|
})()
|
|
175
385
|
: () => richInput.getInput();
|
|
386
|
+
// Debug mode: collect tool calls and response text per turn
|
|
387
|
+
let debugToolCalls = [];
|
|
388
|
+
const debugStreamToolNames = new Map(); // id -> name for CLI provider tool tracking
|
|
389
|
+
let debugResponseText = '';
|
|
390
|
+
let debugInsightNudge;
|
|
391
|
+
let debugTurnCount = 0;
|
|
392
|
+
let lastStreamType = '';
|
|
176
393
|
const onStreamEvent = (event) => {
|
|
177
394
|
if (event.type === 'text_delta') {
|
|
178
|
-
|
|
395
|
+
if (lastStreamType === 'thinking_delta' && !isDebug)
|
|
396
|
+
out('\n\n');
|
|
397
|
+
if (isDebug) {
|
|
398
|
+
debugResponseText += event.text;
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
out(event.text);
|
|
402
|
+
}
|
|
179
403
|
}
|
|
180
404
|
else if (event.type === 'thinking_delta') {
|
|
181
|
-
|
|
405
|
+
if (!isDebug)
|
|
406
|
+
out(c.dim(event.text));
|
|
182
407
|
}
|
|
408
|
+
// Capture tool events from stream (CLI provider handles tools via MCP,
|
|
409
|
+
// so onToolEvent never fires — we catch them here instead)
|
|
410
|
+
if (isDebug) {
|
|
411
|
+
const e = event;
|
|
412
|
+
if (event.type === 'tool_use_start') {
|
|
413
|
+
debugStreamToolNames.set(String(e.id), String(e.name));
|
|
414
|
+
}
|
|
415
|
+
if (event.type === 'tool_result') {
|
|
416
|
+
debugToolCalls.push({
|
|
417
|
+
name: debugStreamToolNames.get(String(e.id)) ?? 'unknown',
|
|
418
|
+
args: {},
|
|
419
|
+
result: String(e.result ?? '').slice(0, 2000),
|
|
420
|
+
isError: !!e.isError,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
lastStreamType = event.type;
|
|
183
425
|
};
|
|
426
|
+
let currentToolName = '';
|
|
427
|
+
let currentToolArgs = {};
|
|
184
428
|
const onToolEvent = (event) => {
|
|
185
429
|
if (event.type === 'tool_call_start') {
|
|
186
|
-
|
|
187
|
-
|
|
430
|
+
currentToolName = event.name;
|
|
431
|
+
currentToolArgs = event.args ?? {};
|
|
432
|
+
if (!isDebug) {
|
|
433
|
+
const preview = toolPreview(event.name, event.args ?? {});
|
|
434
|
+
out(`\n ${c.cyan('◆')} ${event.name}${preview ? c.dim(`(${preview})`) : ''}\n`);
|
|
435
|
+
}
|
|
188
436
|
}
|
|
189
437
|
if (event.type === 'tool_call_result') {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
438
|
+
if (isDebug) {
|
|
439
|
+
debugToolCalls.push({
|
|
440
|
+
name: currentToolName,
|
|
441
|
+
args: currentToolArgs,
|
|
442
|
+
result: (event.result ?? '').slice(0, 2000),
|
|
443
|
+
isError: !!event.isError,
|
|
444
|
+
});
|
|
196
445
|
}
|
|
197
446
|
else {
|
|
198
|
-
const
|
|
199
|
-
|
|
447
|
+
const icon = event.isError ? c.red('✗') : c.dim('→');
|
|
448
|
+
const raw = event.result ?? '';
|
|
449
|
+
const isVerboseTool = VERBOSE_TOOL_NAMES.has(event.name);
|
|
450
|
+
if (isVerboseTool && raw.length > 150) {
|
|
451
|
+
out(` ${icon}\n${raw}\n`);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const result = raw.replace(/\n/g, ' ').slice(0, 200);
|
|
455
|
+
out(` ${icon} ${result}\n`);
|
|
456
|
+
}
|
|
200
457
|
}
|
|
201
458
|
}
|
|
202
459
|
};
|
|
@@ -209,7 +466,7 @@ export async function runAssistant(opts) {
|
|
|
209
466
|
conversationId: conversation.id,
|
|
210
467
|
onClear: () => { history.length = 0; },
|
|
211
468
|
onExit: () => { shouldExit = true; },
|
|
212
|
-
onNew: () => { history.length = 0; conversation = store.create(projectDir); },
|
|
469
|
+
onNew: async () => { history.length = 0; conversation = await store.create(projectDir); },
|
|
213
470
|
onVerbose: () => { out(` ${c.dim('Verbose toggling not yet wired to streaming.')}\n`); },
|
|
214
471
|
};
|
|
215
472
|
// Watch mode: monitor directory for file changes, auto-validate
|
|
@@ -229,7 +486,7 @@ export async function runAssistant(opts) {
|
|
|
229
486
|
const parsed = JSON.parse(result);
|
|
230
487
|
const errorCount = parsed.errorCount ?? parsed.errors?.length ?? 0;
|
|
231
488
|
if (errorCount > 0) {
|
|
232
|
-
out(`\n ${c.yellow('⚠')} ${filename}
|
|
489
|
+
out(`\n ${c.yellow('⚠')} ${opts.watchDir}/${filename}: ${errorCount} validation error(s). Ask me to fix them.\n`);
|
|
233
490
|
out(` ${c.dim('Type a message to fix, or ignore.')}\n`);
|
|
234
491
|
}
|
|
235
492
|
}
|
|
@@ -239,6 +496,8 @@ export async function runAssistant(opts) {
|
|
|
239
496
|
}
|
|
240
497
|
catch { /* watch not available */ }
|
|
241
498
|
}
|
|
499
|
+
// Track which insights have been nudged (by ID) to avoid repetition
|
|
500
|
+
const nudgedInsightIds = new Set();
|
|
242
501
|
// Main conversation loop
|
|
243
502
|
while (!shouldExit) {
|
|
244
503
|
const input = await getNextInput();
|
|
@@ -248,11 +507,32 @@ export async function runAssistant(opts) {
|
|
|
248
507
|
continue;
|
|
249
508
|
// Handle slash commands
|
|
250
509
|
if (input.startsWith('/')) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
510
|
+
if (isDebug) {
|
|
511
|
+
// Capture slash command output for debug JSON
|
|
512
|
+
let slashOutput = '';
|
|
513
|
+
const debugSlashCtx = { ...slashCtx, out: (s) => { slashOutput += s; } };
|
|
514
|
+
const handled = await handleSlashCommand(input, debugSlashCtx);
|
|
515
|
+
if (handled) {
|
|
516
|
+
debugTurnCount++;
|
|
517
|
+
// Strip ANSI codes for clean debug output
|
|
518
|
+
const clean = slashOutput.replace(/\x1b\[[0-9;]*m/g, '').trim();
|
|
519
|
+
process.stdout.write(JSON.stringify({
|
|
520
|
+
turn: debugTurnCount,
|
|
521
|
+
input,
|
|
522
|
+
slashCommand: true,
|
|
523
|
+
response: clean,
|
|
524
|
+
conversationId: conversation.id,
|
|
525
|
+
}) + '\n');
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
const handled = await handleSlashCommand(input, slashCtx);
|
|
531
|
+
if (handled)
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
if (!isDebug)
|
|
535
|
+
out(` ${c.dim('Unknown command. Type /help for available commands.')}\n\n`);
|
|
256
536
|
continue;
|
|
257
537
|
}
|
|
258
538
|
out('\n');
|
|
@@ -295,19 +575,97 @@ export async function runAssistant(opts) {
|
|
|
295
575
|
}
|
|
296
576
|
// Token-aware compression
|
|
297
577
|
compressHistory(history);
|
|
578
|
+
// Proactive insight surfacing — update system prompt for next turn
|
|
579
|
+
// Max 3 nudges per session to avoid being annoying
|
|
580
|
+
if (nudgedInsightIds.size < 3) {
|
|
581
|
+
try {
|
|
582
|
+
const { ProjectModelStore } = await import('./project-model.js');
|
|
583
|
+
const { InsightEngine } = await import('./insight-engine.js');
|
|
584
|
+
const pms = new ProjectModelStore(projectDir);
|
|
585
|
+
const model = await pms.getOrBuild();
|
|
586
|
+
const engine = new InsightEngine();
|
|
587
|
+
const insights = engine.analyze(model).filter(i => i.confidence >= 0.6);
|
|
588
|
+
if (insights.length > 0) {
|
|
589
|
+
// Skip insights already nudged (by ID) or mentioned in conversation
|
|
590
|
+
const unsurfaced = insights.filter(insight => !nudgedInsightIds.has(insight.id) &&
|
|
591
|
+
!history.some(m => m.role === 'assistant' &&
|
|
592
|
+
typeof m.content === 'string' &&
|
|
593
|
+
m.content.includes(insight.title)));
|
|
594
|
+
if (unsurfaced.length > 0) {
|
|
595
|
+
const top = unsurfaced[0];
|
|
596
|
+
nudgedInsightIds.add(top.id);
|
|
597
|
+
const nudge = `\n\n[PROACTIVE CONTEXT: ${top.title}. ${top.description}${top.suggestion ? ` Suggestion: ${top.suggestion}` : ''}. Mention this naturally if relevant, or bring it up if there's a lull.]`;
|
|
598
|
+
if (isDebug)
|
|
599
|
+
debugInsightNudge = nudge;
|
|
600
|
+
if (!systemPrompt.includes('[PROACTIVE CONTEXT:')) {
|
|
601
|
+
systemPrompt += nudge;
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
systemPrompt = systemPrompt.replace(/\n\n\[PROACTIVE CONTEXT:.*\]/s, nudge);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
// Remove stale nudge from system prompt
|
|
609
|
+
systemPrompt = systemPrompt.replace(/\n\n\[PROACTIVE CONTEXT:.*\]/s, '');
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
catch { /* insights not available */ }
|
|
614
|
+
}
|
|
615
|
+
// Check steering engine for time/event-based nudges
|
|
616
|
+
if (steeringEngine) {
|
|
617
|
+
const steerMsg = steeringEngine.check();
|
|
618
|
+
if (steerMsg) {
|
|
619
|
+
// Append to system prompt for next turn
|
|
620
|
+
if (systemPrompt.includes('[STEER') || systemPrompt.includes('[CONTEXT NOTE]') || systemPrompt.includes('[URGENT STEER]')) {
|
|
621
|
+
systemPrompt = systemPrompt.replace(/\n\n\[(CONTEXT NOTE|STEER|URGENT STEER)\].*$/s, '\n\n' + steerMsg);
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
systemPrompt += '\n\n' + steerMsg;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// Debug mode: emit structured NDJSON per turn
|
|
629
|
+
if (isDebug) {
|
|
630
|
+
debugTurnCount++;
|
|
631
|
+
const debugOutput = {
|
|
632
|
+
turn: debugTurnCount,
|
|
633
|
+
input,
|
|
634
|
+
toolCalls: debugToolCalls,
|
|
635
|
+
response: debugResponseText,
|
|
636
|
+
tokensUsed,
|
|
637
|
+
systemPromptLength: systemPrompt.length,
|
|
638
|
+
insightNudge: debugInsightNudge,
|
|
639
|
+
conversationId: conversation.id,
|
|
640
|
+
};
|
|
641
|
+
process.stdout.write(JSON.stringify(debugOutput) + '\n');
|
|
642
|
+
// Reset for next turn
|
|
643
|
+
debugToolCalls = [];
|
|
644
|
+
debugStreamToolNames.clear();
|
|
645
|
+
debugResponseText = '';
|
|
646
|
+
debugInsightNudge = undefined;
|
|
647
|
+
}
|
|
298
648
|
if (!result.success && result.summary) {
|
|
299
|
-
|
|
649
|
+
if (!isDebug)
|
|
650
|
+
out(`\n ${c.red(result.summary)}\n`);
|
|
300
651
|
}
|
|
301
652
|
}
|
|
302
653
|
catch (err) {
|
|
303
654
|
const msg = err instanceof Error ? err.message : String(err);
|
|
304
|
-
|
|
655
|
+
if (isDebug) {
|
|
656
|
+
process.stdout.write(JSON.stringify({ turn: ++debugTurnCount, error: msg, conversationId: conversation.id }) + '\n');
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
out(`\n ${c.red('Error:')} ${msg}\n`);
|
|
660
|
+
}
|
|
305
661
|
}
|
|
306
|
-
|
|
662
|
+
if (!isDebug)
|
|
663
|
+
out('\n');
|
|
307
664
|
}
|
|
308
665
|
watcher?.close();
|
|
309
666
|
richInput?.destroy();
|
|
310
|
-
|
|
667
|
+
if (!isDebug)
|
|
668
|
+
out(`\n ${c.dim('Goodbye.')}\n\n`);
|
|
311
669
|
}
|
|
312
670
|
function toolPreview(name, args) {
|
|
313
671
|
if (args.name)
|