@cnrai/pave 0.3.32 → 0.3.34
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/MARKETPLACE.md +406 -0
- package/README.md +218 -21
- package/build-binary.js +591 -0
- package/build-npm.js +537 -0
- package/build.js +230 -0
- package/check-binary.js +26 -0
- package/deploy.sh +95 -0
- package/index.js +5775 -0
- package/lib/agent-registry.js +1037 -0
- package/lib/args-parser.js +837 -0
- package/lib/blessed-widget-patched.js +93 -0
- package/lib/cli-markdown.js +590 -0
- package/lib/compaction.js +153 -0
- package/lib/duration.js +94 -0
- package/lib/hash.js +22 -0
- package/lib/marketplace.js +866 -0
- package/lib/memory-config.js +166 -0
- package/lib/skill-manager.js +891 -0
- package/lib/soul.js +31 -0
- package/lib/tool-output-formatter.js +180 -0
- package/package.json +35 -33
- package/start-pave.sh +149 -0
- package/status.js +271 -0
- package/test/abort-stream.test.js +445 -0
- package/test/agent-auto-compaction.test.js +552 -0
- package/test/agent-comm-abort.test.js +95 -0
- package/test/agent-comm.test.js +598 -0
- package/test/agent-inbox.test.js +576 -0
- package/test/agent-init.test.js +264 -0
- package/test/agent-interrupt.test.js +314 -0
- package/test/agent-lifecycle.test.js +520 -0
- package/test/agent-log-files.test.js +349 -0
- package/test/agent-mode.manual-test.js +392 -0
- package/test/agent-parsing.test.js +228 -0
- package/test/agent-post-stream-idle.test.js +762 -0
- package/test/agent-registry.test.js +359 -0
- package/test/agent-rm.test.js +442 -0
- package/test/agent-spawn.test.js +933 -0
- package/test/agent-status-api.test.js +624 -0
- package/test/agent-update.test.js +435 -0
- package/test/args-parser.test.js +391 -0
- package/test/auto-compaction-chat.manual-test.js +227 -0
- package/test/auto-compaction.test.js +941 -0
- package/test/build-config.test.js +120 -0
- package/test/build-npm.test.js +388 -0
- package/test/chat-command.test.js +137 -0
- package/test/chat-leading-lines.test.js +159 -0
- package/test/config-flag.test.js +272 -0
- package/test/cursor-drift.test.js +135 -0
- package/test/debug-require.js +23 -0
- package/test/dir-migration.test.js +323 -0
- package/test/duration.test.js +229 -0
- package/test/ghostty-term.test.js +202 -0
- package/test/http500-backoff.test.js +854 -0
- package/test/integration.test.js +86 -0
- package/test/memory-guard-env.test.js +220 -0
- package/test/pr233-fixes.test.js +259 -0
- package/test/run-agent-init.js +297 -0
- package/test/run-all.js +64 -0
- package/test/run-config-flag.js +159 -0
- package/test/run-cursor-drift.js +82 -0
- package/test/run-session-path.js +154 -0
- package/test/run-tests.js +643 -0
- package/test/sandbox-redirect.test.js +202 -0
- package/test/session-path.test.js +132 -0
- package/test/shebang-strip.test.js +241 -0
- package/test/soul-reinject.test.js +1027 -0
- package/test/soul-reread.test.js +281 -0
- package/test/tool-output-formatter.test.js +486 -0
- package/test/tool-output-gating.test.js +143 -0
- package/test/tool-states.test.js +167 -0
- package/test/tools-flag.test.js +65 -0
- package/test/tui-attach.test.js +1255 -0
- package/test/tui-compaction.test.js +354 -0
- package/test/tui-wrap.test.js +568 -0
- package/test-binary.js +52 -0
- package/test-binary2.js +36 -0
- package/LICENSE +0 -21
- package/pave.js +0 -2
- package/sandbox/SandboxRunner.js +0 -1
- package/sandbox/pave-run.js +0 -2
- package/sandbox/permission.js +0 -1
- package/sandbox/utils/yaml.js +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for comprehensive tool state handling
|
|
3
|
+
* Addresses Copilot feedback on missing pending_confirmation state
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
describe('Tool State Handling', () => {
|
|
7
|
+
let mockStdout;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
mockStdout = jest.spyOn(process.stdout, 'write').mockImplementation();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
mockStdout.mockRestore();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const TOOL_COLORS = {
|
|
18
|
+
yellow: '\x1b[33m',
|
|
19
|
+
cyan: '\x1b[36m',
|
|
20
|
+
dim: '\x1b[2m',
|
|
21
|
+
reset: '\x1b[0m',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
test('should handle completed tool state', () => {
|
|
25
|
+
const showTools = true;
|
|
26
|
+
const json = false;
|
|
27
|
+
const _noStream = false;
|
|
28
|
+
const status = 'completed';
|
|
29
|
+
const _toolName = 'bash';
|
|
30
|
+
|
|
31
|
+
if (showTools && !json) {
|
|
32
|
+
if (status === 'completed') {
|
|
33
|
+
process.stdout.write(' Tool completed');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
expect(mockStdout).toHaveBeenCalledWith(' Tool completed');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should handle error tool state', () => {
|
|
41
|
+
const showTools = true;
|
|
42
|
+
const json = false;
|
|
43
|
+
const _noStream = false;
|
|
44
|
+
const status = 'error';
|
|
45
|
+
const _toolName = 'bash';
|
|
46
|
+
|
|
47
|
+
if (showTools && !json) {
|
|
48
|
+
if (status === 'error') {
|
|
49
|
+
process.stdout.write('L Tool error');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
expect(mockStdout).toHaveBeenCalledWith('L Tool error');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('should handle pending_confirmation tool state', () => {
|
|
57
|
+
const showTools = true;
|
|
58
|
+
const json = false;
|
|
59
|
+
const _noStream = false;
|
|
60
|
+
const status = 'pending_confirmation';
|
|
61
|
+
const toolName = 'bash';
|
|
62
|
+
|
|
63
|
+
if (showTools && !json) {
|
|
64
|
+
if (status === 'pending_confirmation') {
|
|
65
|
+
const confirmationMsg = `\n${TOOL_COLORS.yellow}S${TOOL_COLORS.reset} ${TOOL_COLORS.cyan}${toolName}${TOOL_COLORS.reset} ${TOOL_COLORS.dim}pending confirmation...${TOOL_COLORS.reset}\n`;
|
|
66
|
+
process.stdout.write(confirmationMsg);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('S'));
|
|
71
|
+
expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('pending confirmation'));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('should handle running tool state only once per tool', () => {
|
|
75
|
+
const showTools = true;
|
|
76
|
+
const json = false;
|
|
77
|
+
const _noStream = false;
|
|
78
|
+
const status = 'running';
|
|
79
|
+
const toolName = 'bash';
|
|
80
|
+
const toolId = 'tool-123';
|
|
81
|
+
const activeTools = {};
|
|
82
|
+
|
|
83
|
+
if (showTools && !json) {
|
|
84
|
+
if (status === 'running' && !activeTools[toolId]) {
|
|
85
|
+
activeTools[toolId] = true;
|
|
86
|
+
const runningMsg = `\n${TOOL_COLORS.yellow}�${TOOL_COLORS.reset} ${TOOL_COLORS.cyan}${toolName}${TOOL_COLORS.reset} ${TOOL_COLORS.dim}running...${TOOL_COLORS.reset}\n`;
|
|
87
|
+
process.stdout.write(runningMsg);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
expect(mockStdout).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('�'));
|
|
93
|
+
expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('running...'));
|
|
94
|
+
|
|
95
|
+
// Second call with same tool should not output again
|
|
96
|
+
mockStdout.mockClear();
|
|
97
|
+
|
|
98
|
+
if (showTools && !json) {
|
|
99
|
+
if (status === 'running' && !activeTools[toolId]) {
|
|
100
|
+
activeTools[toolId] = true;
|
|
101
|
+
process.stdout.write('Should not be called');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
expect(mockStdout).not.toHaveBeenCalled();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('should track tool states in JSON mode', () => {
|
|
109
|
+
const showTools = true;
|
|
110
|
+
const toolOutputs = [];
|
|
111
|
+
const toolEntry = {
|
|
112
|
+
id: 'tool-123',
|
|
113
|
+
name: 'bash',
|
|
114
|
+
status: 'pending_confirmation',
|
|
115
|
+
input: '{"command": "rm -rf /"}',
|
|
116
|
+
output: null,
|
|
117
|
+
duration: undefined,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
if (showTools) {
|
|
121
|
+
toolOutputs.push(toolEntry);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
expect(toolOutputs).toHaveLength(1);
|
|
125
|
+
expect(toolOutputs[0].status).toBe('pending_confirmation');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('Tool State Transitions', () => {
|
|
130
|
+
test('should handle tool state progression', () => {
|
|
131
|
+
const toolOutputs = [];
|
|
132
|
+
const toolId = 'tool-123';
|
|
133
|
+
const showTools = true;
|
|
134
|
+
|
|
135
|
+
// Running state
|
|
136
|
+
let toolEntry = {
|
|
137
|
+
id: toolId,
|
|
138
|
+
name: 'bash',
|
|
139
|
+
status: 'running',
|
|
140
|
+
input: '{"command": "sleep 5"}',
|
|
141
|
+
output: null,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
if (showTools) {
|
|
145
|
+
toolOutputs.push(toolEntry);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
expect(toolOutputs[0].status).toBe('running');
|
|
149
|
+
|
|
150
|
+
// Update to completed
|
|
151
|
+
toolEntry = {
|
|
152
|
+
...toolEntry,
|
|
153
|
+
status: 'completed',
|
|
154
|
+
output: 'Command completed',
|
|
155
|
+
duration: 5000,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const existingIdx = toolOutputs.findIndex((t) => t.id === toolId);
|
|
159
|
+
if (existingIdx >= 0) {
|
|
160
|
+
toolOutputs[existingIdx] = toolEntry;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
expect(toolOutputs[0].status).toBe('completed');
|
|
164
|
+
expect(toolOutputs[0].output).toBe('Command completed');
|
|
165
|
+
expect(toolOutputs[0].duration).toBe(5000);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for --no-tools flag functionality
|
|
3
|
+
* Tool output is shown by default, use --no-tools to disable
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Use mock parseArgs function from test runner
|
|
7
|
+
const { parseArgs } = global.mockModules || { parseArgs(args) {
|
|
8
|
+
// Default: showTools is true
|
|
9
|
+
// --no-tools disables it
|
|
10
|
+
return {
|
|
11
|
+
command: args[0] || '',
|
|
12
|
+
commandArgs: args.slice(1).filter((arg) => !arg.startsWith('--') && !arg.startsWith('-')),
|
|
13
|
+
showTools: !args.includes('--no-tools'),
|
|
14
|
+
json: args.includes('--json'),
|
|
15
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
16
|
+
noStream: args.includes('--no-stream'),
|
|
17
|
+
};
|
|
18
|
+
} };
|
|
19
|
+
|
|
20
|
+
describe('Tools Flag Parsing', () => {
|
|
21
|
+
test('should default showTools to true', () => {
|
|
22
|
+
const args = parseArgs(['chat', 'test', 'message']);
|
|
23
|
+
expect(args.showTools).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should parse --no-tools flag to disable', () => {
|
|
27
|
+
const args = parseArgs(['chat', '--no-tools', 'test', 'message']);
|
|
28
|
+
expect(args.showTools).toBe(false);
|
|
29
|
+
expect(args.command).toBe('chat');
|
|
30
|
+
expect(args.commandArgs).toEqual(['test', 'message']);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should work with other flags', () => {
|
|
34
|
+
const args = parseArgs(['chat', '--no-tools', '--json', '--verbose', 'test']);
|
|
35
|
+
expect(args.showTools).toBe(false);
|
|
36
|
+
expect(args.json).toBe(true);
|
|
37
|
+
expect(args.verbose).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should filter flags from command args', () => {
|
|
41
|
+
const args = parseArgs(['chat', '--no-tools', 'run', 'bash', 'command']);
|
|
42
|
+
expect(args.commandArgs).toEqual(['run', 'bash', 'command']);
|
|
43
|
+
expect(args.commandArgs).not.toContain('--no-tools');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('Tools Flag in Help Text', () => {
|
|
48
|
+
// Mock console.log to capture help output
|
|
49
|
+
let consoleSpy;
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterEach(() => {
|
|
55
|
+
consoleSpy.mockRestore();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should include --no-tools in help text', () => {
|
|
59
|
+
const { showHelp } = require('../lib/args-parser');
|
|
60
|
+
showHelp();
|
|
61
|
+
|
|
62
|
+
const helpOutput = consoleSpy.mock.calls.map((call) => call[0]).join('\\n');
|
|
63
|
+
expect(helpOutput).toContain('--no-tools');
|
|
64
|
+
});
|
|
65
|
+
});
|