Updates
Rolling release / release (push) Failing after 1m50s

This commit is contained in:
2026-09-14 11:31:41 -04:00
parent aa06c71fe1
commit af9246151f
12 changed files with 176 additions and 159 deletions
+3 -2
View File
@@ -287,14 +287,15 @@ test('camera Allow now starts a grant even when Camera access is off', async ()
} finally { await daemon.close(); }
});
test('a failed camera portal does not revoke an Allow now grant', async () => {
test('a failed camera permission request revokes the grant instead of showing active access', async () => {
const daemon = new JarvisDaemon();
try {
daemon.webcam = { access: async () => { throw new Error('Camera portal Access response 2'); } };
daemon.webcamGrant();
await Promise.resolve();
await Promise.resolve();
assert.equal(daemon.camera.status().active, true);
assert.equal(daemon.camera.status().active, false);
assert.equal(daemon.camera.status().backend, 'none');
} finally { await daemon.close(); }
});
+27
View File
@@ -237,6 +237,33 @@ test('Obsidian Apply replaces the tool and memory selection, resets context, and
}
});
test('file access applies live without a service restart', async () => {
const previous = process.env.XDG_CONFIG_HOME;
const dir = await mkdtemp(path.join(tmpdir(), 'jarvis-file-access-'));
process.env.XDG_CONFIG_HOME = dir; await mkdir(path.join(dir, 'jarvis'));
const daemon = new JarvisDaemon(); let resets = 0;
daemon.harness.resetContext = async () => { resets++; };
daemon.setState = state => { daemon.state = state; };
daemon.startVoice = async () => { daemon.voiceLoop = { stop: async () => {}, status: { errors: {} } }; };
daemon.voiceLoop = { stop: async () => {} };
try {
const config = path.join(dir, 'jarvis/config.json');
await writeFile(config, JSON.stringify({ fsAccess: 'filesystem' }));
const result = JSON.parse(await daemon.reloadSettings());
assert.equal(resets, 1); assert.deepEqual(daemon.harness.options.roots, ['/']);
assert.equal(result.restartRequired.includes('fsAccess'), false);
const names = daemon.harness.options.tools.map(t => t.name);
assert.equal(new Set(names).size, names.length);
await writeFile(config, JSON.stringify({ fsAccess: 'workspace' }));
await daemon.reloadSettings();
assert.equal(resets, 2); assert.deepEqual(daemon.harness.options.roots, []);
} finally {
clearInterval(daemon._idleTimer); clearInterval(daemon._telemetryTimer);
if (previous === undefined) delete process.env.XDG_CONFIG_HOME; else process.env.XDG_CONFIG_HOME = previous;
await rm(dir, { recursive: true, force: true });
}
});
test('voice preview uses selected text without changing chat history or the repeat reply', async () => {
const daemon = new JarvisDaemon(); const speech = []; const replies = [];
daemon.setState = state => { daemon.state = state; };