Files
Meldwork/desktop/test/security/main-security.test.cjs
T
Ryder Sun ec6674d96a feat: ship concurrent collaboration harness
Implement frozen concurrent responses, Agent-negotiated V4 discussion work, strict durable receipts and recovery, validated runtime phase UI, and the animated return-to-bottom control. Prepare the 0.1.2 prerelease metadata and documentation.\n\nChecks before commit: frontend 299/299; desktop 1270/1270; deterministic eval 6 cases/18 results; web and desktop renderer builds; desktop pack; staged and unstaged diff checks.
2026-08-17 11:35:32 +08:00

2129 lines
86 KiB
JavaScript

const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
const { pathToFileURL } = require('node:url')
const { serializeAgentConnectorManifest } = require('../../src/agents/connectors/agent-connector-manifest.cjs')
const {
SAMPLE_AGENT_CONNECTOR_MANIFEST,
SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST,
SAMPLE_LOCAL_ECHO_AGENT_CONNECTOR_PACKAGE,
} = require('../../src/agents/connectors/agent-connector-local.cjs')
const { serializeAgentConnectorPackage } = require('../../src/agents/connectors/agent-connector-package-store.cjs')
const {
LOCAL_IPC_CHANNELS,
PROVIDER_AGENT_KINDS,
PROVIDER_METADATA,
deferred,
eventFor,
loadMain,
pngHeader,
waitFor,
} = require('../support/main-security-test-harness.cjs')
test('local desktop authorization requires the current main frame and exact frontend file', (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-main-security-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { main } = loadMain(directory)
const frontend = path.join(directory, 'frontend', 'index.html')
const frontendUrl = `${pathToFileURL(frontend).href}?desktop=1#/chat`
const trusted = eventFor(frontendUrl)
assert.equal(main.isTrustedLocalRenderer(trusted.event, trusted.sender, frontend), true)
assert.equal(main.isTrustedLocalWebContents(trusted.sender, frontend), true)
assert.equal(main.isTrustedLocalRenderer({
sender: trusted.sender,
senderFrame: { url: frontendUrl, processId: 1, routingId: 999 },
}, trusted.sender, frontend), false)
assert.equal(main.isTrustedLocalRenderer(
eventFor(pathToFileURL(path.join(directory, 'offline.html')).href).event,
trusted.sender,
frontend,
), false)
})
test('a second desktop process exits before ready initialization', (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-single-instance-denied-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, { singleInstanceLock: false })
assert.equal(harness.singleInstanceLockCalls, 1)
assert.equal(harness.quitCount, 1)
assert.equal(harness.readyRegistered, false)
assert.equal(harness.workspaceInstances.length, 0)
assert.equal(harness.windows.length, 0)
})
test('product data migration failure stops ready initialization before stores or windows', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-migration-startup-stop-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const diagnostic = { status: 'recovery-required', failedStep: 3, rollbackFailures: [{}] }
const reported = []
const originalError = console.error
console.error = (...args) => { reported.push(args) }
t.after(() => { console.error = originalError })
const { harness } = loadMain(directory, {
moduleMocks: {
'./product-data-migration.cjs': {
migrateLegacyProductData: () => {
throw Object.assign(new Error('MELDWORK_PRODUCT_DATA_MIGRATION_RECOVERY_REQUIRED'), {
code: 'MELDWORK_PRODUCT_DATA_MIGRATION_RECOVERY_REQUIRED',
diagnostic,
})
},
},
},
})
await harness.ready()
assert.equal(harness.quitCount, 1)
assert.equal(harness.workspaceInstances.length, 0)
assert.equal(harness.providerInstances.length, 0)
assert.equal(harness.knowledgeBaseStoreInstances.length, 0)
assert.equal(harness.windows.length, 0)
assert.deepEqual(reported, [[
'MELDWORK_PRODUCT_DATA_MIGRATION_ABORTED', diagnostic,
]])
})
test('controlled media protocol serves attachment bytes with range support and rejects invalid ids', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-media-protocol-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const mediaBytes = Buffer.from('ID3-audio-payload')
const { harness } = loadMain(directory, {
mediaMetadata: {
id: 'generated-audio', name: 'briefing.mp3', mimeType: 'audio/mpeg', size: mediaBytes.length,
},
mediaBytes,
})
assert.equal(harness.registeredSchemes.some(entry => (
entry.scheme === 'meldwork-media'
&& entry.privileges?.secure === true
&& entry.privileges?.standard === true
)), true)
await harness.ready()
const handler = harness.protocolHandlers.get('meldwork-media')
assert.equal(typeof handler, 'function')
const response = await handler(new Request(
'meldwork-media://attachment/generated-audio',
{ headers: { Range: 'bytes=4-8' } },
))
assert.equal(response.status, 206)
assert.equal(response.headers.get('content-type'), 'audio/mpeg')
assert.equal(response.headers.get('content-range'), `bytes 4-8/${mediaBytes.length}`)
assert.deepEqual(Buffer.from(await response.arrayBuffer()), mediaBytes.subarray(4, 9))
const readsBeforeInvalid = harness.attachmentInstances[0].readWithMetadataCalls.length
const invalid = await handler(new Request('meldwork-media://attachment/..%2Fsecret'))
assert.equal(invalid.status, 404)
assert.equal(harness.attachmentInstances[0].readWithMetadataCalls.length, readsBeforeInvalid)
})
test('every local IPC handler rejects an untrusted renderer before dispatch', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-ipc-security-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
assert.deepEqual([...harness.ipcHandlers.keys()], LOCAL_IPC_CHANNELS)
const trustedEvent = harness.event()
const untrustedEvent = {
sender: trustedEvent.sender,
senderFrame: {
...trustedEvent.senderFrame,
routingId: trustedEvent.senderFrame.routingId + 1,
},
}
for (const channel of LOCAL_IPC_CHANNELS) {
await assert.rejects(
async () => harness.ipcHandlers.get(channel)(untrustedEvent),
{ message: 'DESKTOP_CLIENT_ACCESS_DENIED' },
channel,
)
}
})
test('ready activates one fixed local workspace and loads the bundled frontend', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-ready-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
assert.equal(harness.workspaceInstances.length, 1)
assert.equal(
harness.workspaceInstances[0].input.storagePath,
path.join(directory, 'meldwork-workspace.json'),
)
assert.equal(
harness.workspaceInstances[0].input.runLedger.storagePath,
path.join(directory, 'meldwork-run-ledger.json'),
)
assert.match(
harness.workspaceInstances[0].input.agentFitMatrix.matrixId,
/^fit-matrix-[a-f0-9]{64}$/,
)
assert.equal(harness.workspaceInstances[0].refreshCount, 0)
assert.equal(harness.providerInstances[0].input.storagePath,
path.join(directory, 'meldwork-provider.json'))
assert.equal(harness.customAgentStoreInstances[0].input.storagePath,
path.join(directory, 'meldwork-custom-agents.json'))
assert.deepEqual(
[...harness.providerInstances[0].input.allowedKinds].sort(),
[...PROVIDER_AGENT_KINDS].sort(),
)
assert.equal(harness.knowledgeBaseStoreInstances[0].input.storagePath,
path.join(directory, 'meldwork-knowledge-base.json'))
assert.equal(harness.attachmentInstances[0].input.rootPath,
path.join(directory, 'attachments'))
assert.equal(harness.skillCatalogInstances[0].input.home,
path.join(directory, 'Home'))
assert.equal(
harness.skillSnapshotStoreInstances[0].input.contentBlobStore,
harness.workspaceInstances[0].input.contentBlobStore,
)
assert.equal(
harness.skillSnapshotSelectionInstances[0].input.contentBlobStore,
harness.workspaceInstances[0].input.contentBlobStore,
)
assert.equal(
harness.skillSnapshotSelectionInstances[0].input.snapshotStore,
harness.skillSnapshotStoreInstances[0],
)
assert.equal(
harness.skillSnapshotSelectionInstances[0].input.catalog,
harness.skillCatalogInstances[0],
)
assert.equal(
harness.skillSnapshotSelectionInstances[0].input.trustStore,
harness.skillTrustStoreInstances[0],
)
assert.equal(
harness.skillTrustStoreInstances[0].input.storagePath,
path.join(directory, 'meldwork-private', 'skill-trust-audit.jsonl'),
)
assert.equal(typeof harness.skillSnapshotSelectionInstances[0].input.requestTrust, 'function')
const selectedSkills = [{
targetKind: 'codex', namespace: 'global', slug: 'review', name: 'Review',
}]
assert.deepEqual(
await harness.workspaceInstances[0].input.validateSkillSelections('codex', selectedSkills),
selectedSkills,
)
assert.deepEqual(harness.skillSnapshotSelectionInstances[0].prepareCalls, [{
kind: 'codex', selections: selectedSkills,
}])
const detected = await harness.workspaceInstances[0].input.detectAgents()
assert.deepEqual(detected, [])
assert.equal(harness.installerInstances[0].detectedCount, 1)
assert.equal(harness.customAgentStoreInstances[0].detectCount, 1)
assert.equal(typeof harness.workspaceInstances[0].input.connectorRuntime.run, 'function')
assert.equal(typeof harness.workspaceInstances[0].input.resolveAttachments, 'function')
assert.equal(typeof harness.workspaceInstances[0].input.validateSkillSelections, 'function')
assert.equal(typeof harness.workspaceInstances[0].input.validateKnowledgeBaseSelections, 'function')
assert.equal(typeof harness.workspaceInstances[0].input.imageAttachmentLimit, 'function')
assert.equal(typeof harness.workspaceInstances[0].input.agentLabel, 'function')
assert.equal(harness.cloudAgentRuntimeInstances.length, 1)
assert.equal(harness.cloudAgentRuntimeInstances[0].input.runLedger,
harness.workspaceInstances[0].input.runLedger)
assert.equal(harness.cloudAgentRuntimeInstances[0].input.outcomeStore,
harness.workspaceInstances[0].input.outcomeStore)
assert.deepEqual(harness.cloudAgentRuntimeInstances[0].input.connectors, [])
assert.equal(harness.cloudAgentRuntimeInstances[0].startCount, 1)
assert.equal(harness.cloudAgentOperationStoreInstances[0].input.storagePath,
path.join(directory, 'meldwork-private', 'cloud-agent-operations.json'))
assert.equal(harness.channelIngressRuntimeInstances.length, 1)
assert.equal(
harness.channelIngressRuntimeInstances[0].input.store,
harness.channelInboxStoreInstances[0],
)
assert.deepEqual(harness.channelIngressRuntimeInstances[0].input.connectors, [])
assert.equal(harness.channelIngressRuntimeInstances[0].startCount, 1)
assert.equal(harness.channelIngressRuntimeInstances[0].status().receiverCount, 0)
assert.equal(harness.channelInboxStoreInstances[0].input.storagePath,
path.join(directory, 'meldwork-private', 'channel-inbox.json'))
assert.deepEqual(harness.attachmentInstances[0].cleanupCalls, [[]])
assert.equal(harness.windows.length, 1)
assert.equal(harness.windows[0].input.icon?.isEmpty?.(), false)
assert.match(harness.nativeImagePathCalls[0], /frontend[\\/]public[\\/]logos[\\/]meldwork-app\.png$/)
if (process.platform === 'darwin') assert.equal(harness.dockIconCalls.length, 1)
assert.equal(
harness.windows[0].input.backgroundColor,
process.platform === 'darwin' ? '#e7edef' : '#f3f6f8',
)
if (process.platform === 'darwin') {
assert.equal(harness.windows[0].input.titleBarStyle, 'hiddenInset')
assert.deepEqual(harness.windows[0].input.trafficLightPosition, { x: 18, y: 16 })
} else {
assert.equal('titleBarStyle' in harness.windows[0].input, false)
assert.equal('trafficLightPosition' in harness.windows[0].input, false)
}
assert.equal(
harness.windows[0].loads[0].filename,
path.resolve(__dirname, '../../../frontend/dist/index.html'),
)
assert.deepEqual(harness.windows[0].loads[0].options, { hash: '/chat' })
assert.deepEqual(
[...harness.ipcHandlers.keys()].filter(name => name.includes('cloud')),
[
'local-cloud-agent:provide-input',
'local-cloud-agent:decide-permission',
'local-cloud-agent:cancel',
],
)
assert.equal([...harness.ipcHandlers.keys()].some(name => (
name.startsWith('local-cloud-agent:') && name.includes('configure')
)), false)
assert.equal([...harness.ipcHandlers.keys()].some(name => name.includes('channel')), false)
assert.equal(harness.ipcListeners.size, 0)
})
test('an explicitly installed Agent Connector is available through generic catalog metadata and main runtime', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-agent-connector-main-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const manifestDirectory = path.join(directory, 'agent-connectors', 'manifests')
fs.mkdirSync(manifestDirectory, { recursive: true })
fs.writeFileSync(
path.join(manifestDirectory, `${SAMPLE_AGENT_CONNECTOR_MANIFEST.manifestId}.json`),
serializeAgentConnectorManifest(SAMPLE_AGENT_CONNECTOR_MANIFEST),
)
const { harness } = loadMain(directory, {
detectedAgents: [{
kind: 'codex', name: 'Codex CLI', executable: '/private/bin/codex',
version: 'codex-cli 0.147.0', compatibilityState: 'compatible',
}],
})
await harness.ready()
await assert.rejects(
harness.ipcHandlers.get('local-agent-connector:configure')(
harness.event(),
{
manifestId: SAMPLE_AGENT_CONNECTOR_MANIFEST.manifestId,
label: 'Codex review account',
credentials: null,
credentialRef: 'credential-ref:renderer-must-not-control',
},
),
{ message: 'AGENT_CONNECTOR_REQUEST_INVALID' },
)
const configured = await harness.ipcHandlers.get('local-agent-connector:configure')(
harness.event(),
{
manifestId: SAMPLE_AGENT_CONNECTOR_MANIFEST.manifestId,
label: 'Codex review account',
credentials: null,
},
)
assert.equal(configured.credentialConfigured, false)
assert.equal(Object.hasOwn(configured, 'credentialRef'), false)
const workspace = harness.workspaceInstances[0]
const agents = await workspace.input.detectAgents()
const connector = agents.find(agent => agent.connectorInstanceId)
assert.ok(connector)
const catalog = await harness.ipcHandlers.get('local-agent-installer:catalog')(harness.event())
const profile = catalog.agents.find(agent => agent.kind === connector.kind)
assert.equal(profile.connector, true)
assert.equal(profile.providerMode, 'connector')
assert.equal(profile.description, SAMPLE_AGENT_CONNECTOR_MANIFEST.description)
assert.doesNotMatch(JSON.stringify(profile), /private\/bin|credential-ref/i)
const result = await workspace.input.connectorRuntime.run(
connector,
'Review through the installed Connector',
directory,
{ runId: 'run-1', agentRunId: 'agent-run-1', sandbox: 'read-only' },
)
assert.equal(result.outcome, 'completed')
assert.equal(result.connector.upstreamVersion, '0.147.0')
assert.equal(Object.hasOwn(result.connector, 'credentialRefId'), false)
assert.equal(harness.runAgentCalls.length, 1)
assert.equal(harness.runAgentCalls[0][0].executable, '/private/bin/codex')
})
test('Agent Connector IPC persists isolated accounts without returning CredentialRefs or secrets', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-agent-connector-accounts-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const manifestDirectory = path.join(directory, 'agent-connectors', 'manifests')
fs.mkdirSync(manifestDirectory, { recursive: true })
fs.writeFileSync(
path.join(
manifestDirectory,
`${SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST.manifestId}.json`,
),
serializeAgentConnectorManifest(SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST),
)
const options = {
providerConfigured: true,
detectedAgents: [{
kind: 'codex', name: 'Codex CLI', executable: '/private/bin/codex',
version: 'codex-cli 0.147.0', compatibilityState: 'compatible',
}],
}
const { harness } = loadMain(directory, options)
await harness.ready()
const configure = harness.ipcHandlers.get('local-agent-connector:configure')
const list = harness.ipcHandlers.get('local-agent-connector:list')
const remove = harness.ipcHandlers.get('local-agent-connector:delete')
const first = await configure(harness.event(), {
manifestId: SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST.manifestId,
label: 'Codex account A',
credentials: { 'openai-api-key': 'connector-main-secret-a' },
})
const second = await configure(harness.event(), {
manifestId: SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST.manifestId,
label: 'Codex account B',
credentials: { 'openai-api-key': 'connector-main-secret-b' },
})
assert.notEqual(first.instanceId, second.instanceId)
assert.equal(first.credentialConfigured, true)
const listed = await list(harness.event())
assert.deepEqual(listed.map(item => item.label), ['Codex account A', 'Codex account B'])
assert.doesNotMatch(JSON.stringify(listed), /credential-ref|connector-main-secret/i)
const workspace = harness.workspaceInstances[0]
const agents = await workspace.input.detectAgents()
const result = await workspace.input.connectorRuntime.run(
agents.find(agent => agent.kind === first.instanceId),
'Review with account A',
directory,
{ runId: 'run-account-a', agentRunId: 'agent-run-account-a', sandbox: 'read-only' },
)
assert.doesNotMatch(JSON.stringify(result), /credential-ref|connector-main-secret/i)
assert.equal(harness.runAgentCalls.at(-1)[3].env.OPENAI_API_KEY, 'connector-main-secret-a')
assert.equal(Object.hasOwn(harness.runAgentCalls.at(-1)[3].env, 'OPENAI_BASE_URL'), false)
assert.equal(Object.hasOwn(harness.runAgentCalls.at(-1)[3].env, 'OPENAI_MODEL'), false)
assert.equal(Object.hasOwn(harness.runAgentCalls.at(-1)[3], 'connectorCredentialIsolation'), false)
await workspace.input.connectorRuntime.run(
agents.find(agent => agent.kind === second.instanceId),
'Review with account B',
directory,
{ runId: 'run-account-b', agentRunId: 'agent-run-account-b', sandbox: 'read-only' },
)
assert.equal(harness.runAgentCalls.at(-1)[3].env.OPENAI_API_KEY, 'connector-main-secret-b')
assert.notEqual(harness.runAgentCalls.at(-1)[3].env.OPENAI_API_KEY, 'provider-key')
const instanceFile = fs.readFileSync(
path.join(directory, 'agent-connectors', 'instances.json'),
'utf8',
)
const credentialFile = fs.readFileSync(
path.join(directory, 'meldwork-private', 'agent-connector-credentials.json'),
'utf8',
)
assert.match(instanceFile, /credential-ref:/)
assert.doesNotMatch(instanceFile, /connector-main-secret|encrypted/i)
assert.doesNotMatch(credentialFile, /connector-main-secret|Codex account/i)
const { harness: restarted } = loadMain(directory, options)
await restarted.ready()
const restored = await restarted.ipcHandlers.get('local-agent-connector:list')(
restarted.event(),
)
assert.deepEqual(restored.map(item => item.label), ['Codex account A', 'Codex account B'])
await restarted.ipcHandlers.get('local-agent-connector:delete')(
restarted.event(), first.instanceId,
)
const afterDelete = await restarted.ipcHandlers.get('local-agent-connector:list')(
restarted.event(),
)
assert.deepEqual(afterDelete.map(item => item.label), ['Codex account B'])
await assert.rejects(
remove(harness.event(), {
instanceId: second.instanceId,
credentialRef: 'credential-ref:renderer-controlled',
}),
{ message: 'AGENT_CONNECTOR_REQUEST_INVALID' },
)
await assert.rejects(
configure(harness.event(), {
manifestId: SAMPLE_CREDENTIAL_AGENT_CONNECTOR_MANIFEST.manifestId,
label: 'Invalid account',
credentials: { unexpected: 'connector-main-secret-c' },
}),
{ message: 'AGENT_CONNECTOR_CREDENTIAL_INVALID' },
)
})
test('Agent Connector package IPC keeps paths private and requires native approval', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-agent-connector-package-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const packagePath = path.join(directory, 'local-echo.connector.json')
fs.writeFileSync(
packagePath,
serializeAgentConnectorPackage(SAMPLE_LOCAL_ECHO_AGENT_CONNECTOR_PACKAGE),
)
const { harness } = loadMain(directory, {
dialogResult: { canceled: false, filePaths: [packagePath] },
messageBoxResult: { response: 0 },
})
await harness.ready()
const invoke = name => harness.ipcHandlers.get(`local-agent-connector:${name}`)
const imported = await invoke('import')(harness.event())
assert.equal(imported.canceled, false)
assert.equal(imported.package.state, 'imported')
assert.equal(imported.package.origin.filename, path.basename(packagePath))
assert.doesNotMatch(JSON.stringify(imported), new RegExp(directory.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
const packageId = SAMPLE_LOCAL_ECHO_AGENT_CONNECTOR_PACKAGE.packageId
const approved = await invoke('approve')(harness.event(), packageId)
assert.equal(approved.canceled, false)
assert.equal(approved.package.state, 'approved')
const approvalOptions = harness.dialogCalls.at(-1)[1]
assert.match(approvalOptions.detail, /Meldwork/)
assert.match(approvalOptions.detail, /Transport: cli\/json/)
assert.match(approvalOptions.detail, /Permissions: read-only/)
assert.match(approvalOptions.detail, /Credential slots: None/)
assert.match(approvalOptions.detail, /Outbound destinations: None/)
assert.doesNotMatch(approvalOptions.detail, new RegExp(directory.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
assert.equal((await invoke('install')(harness.event(), packageId)).state, 'installed')
const configured = await invoke('configure')(harness.event(), {
manifestId: SAMPLE_LOCAL_ECHO_AGENT_CONNECTOR_PACKAGE.manifest.manifestId,
label: 'Main-process echo',
credentials: null,
})
const tested = await invoke('test')(harness.event(), configured.instanceId)
assert.equal(tested.passed, true)
assert.equal(Object.hasOwn(tested, 'text'), false)
assert.equal(harness.runAgentCalls.length, 0)
assert.deepEqual((await invoke('audit')(harness.event(), packageId)).map(event => event.action), [
'imported', 'approved', 'installed',
])
assert.equal((await invoke('disable')(harness.event(), packageId)).state, 'disabled')
assert.equal((await invoke('install')(harness.event(), packageId)).state, 'installed')
assert.equal((await invoke('revoke')(harness.event(), packageId)).state, 'revoked')
await invoke('delete')(harness.event(), configured.instanceId)
assert.equal((await invoke('remove')(harness.event(), packageId)).state, 'removed')
})
test('unsigned Skill trust uses native approval and exposes only review and revocation', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-skill-trust-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const bindingId = `skill-trust-binding-${'a'.repeat(64)}`
const record = {
bindingId,
state: 'approved',
decisionId: `skill-trust-decision-${'b'.repeat(64)}`,
}
const { harness } = loadMain(directory, {
messageBoxResult: { response: 0 },
skillTrustRecords: [record],
})
await harness.ready()
const manifest = {
identity: { id: 'global/review', version: '1.0.0' },
origin: { type: 'local-unsigned', publisher: 'Local author' },
agents: [{ kind: 'codex', minVersion: '0.100.0', maxVersion: '1.0.0' }],
inputTypes: ['text'],
tools: ['filesystem'],
credentials: [],
permissionMode: 'read-only',
networkDestinations: [],
sideEffectClass: 'none',
}
const approved = await harness.skillSnapshotSelectionInstances[0].input.requestTrust({
binding: {
bindingId,
contractHash: 'c'.repeat(64),
contentHash: 'd'.repeat(64),
},
coordinates: {
targetKind: 'codex', namespace: 'global', slug: 'review', name: 'Review',
},
manifest,
})
assert.equal(approved, true)
const approvalOptions = harness.dialogCalls.at(-1)[1]
assert.match(approvalOptions.detail, /Skill: Review \(global\/review 1\.0\.0\)/)
assert.match(approvalOptions.detail, /Permission: read-only/)
assert.match(approvalOptions.detail, /Side-effect class: none/)
assert.doesNotMatch(approvalOptions.detail, new RegExp(directory.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
assert.deepEqual(
await harness.ipcHandlers.get('local-skill-trust:list')(harness.event()),
[record],
)
assert.deepEqual(
await harness.ipcHandlers.get('local-skill-trust:revoke')(harness.event(), bindingId),
{ bindingId, revoked: true },
)
assert.deepEqual(harness.skillTrustStoreInstances[0].revocations, [bindingId])
assert.throws(
() => harness.ipcHandlers.get('local-skill-trust:revoke')(harness.event(), { bindingId }),
{ message: 'LOCAL_SKILL_TRUST_REQUEST_INVALID' },
)
})
test('Custom Agent IPC keeps executable paths private and refreshes the local catalog', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-custom-agent-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const selectedExecutable = '/private/tools/review-agent'
const { harness } = loadMain(directory, {
dialogResult: { canceled: false, filePaths: [selectedExecutable] },
})
await harness.ready()
const result = await harness.ipcHandlers.get('local-custom-agent:create')(
harness.event(),
{
label: 'Review Agent',
description: 'Reviews repository changes.',
args: ['review', '--format=text'],
promptMode: 'stdin',
executable: '/renderer/must-not-control-this',
},
)
assert.equal(result.canceled, false)
assert.equal(result.agent.kind, 'custom-0123456789abcdef')
assert.equal(result.agent.commandName, 'review-agent')
assert.equal('executable' in result.agent, false)
assert.equal('args' in result.agent, false)
assert.doesNotMatch(JSON.stringify(result), /private\/tools|renderer\/must-not-control/)
assert.deepEqual(harness.customAgentStoreInstances[0].created, [{
input: {
label: 'Review Agent',
description: 'Reviews repository changes.',
args: ['review', '--format=text'],
promptMode: 'stdin',
},
executable: selectedExecutable,
}])
assert.equal(harness.workspaceInstances[0].refreshCount, 1)
let outboundCalls = 0
const onOutboundPayload = () => { outboundCalls += 1 }
const signal = new AbortController().signal
const customReply = await harness.workspaceInstances[0].input.runAgent(
{ kind: result.agent.kind },
'Review this change',
'/tmp/project',
{
sandbox: 'read-only',
signal,
attachments: ['/tmp/project/input.txt'],
onProgress: () => {},
onEvent: () => {},
onOutboundPayload,
},
)
assert.deepEqual(customReply, { text: 'custom reply', sessionRef: '' })
assert.equal(harness.customAgentRunCalls.length, 1)
assert.equal(outboundCalls, 0)
const [runKind, runPrompt, runWorkdir, runOptions] = harness.customAgentRunCalls[0]
assert.equal(runKind, result.agent.kind)
assert.equal(runPrompt, 'Review this change')
assert.equal(runWorkdir, '/tmp/project')
assert.equal(runOptions.signal, signal)
assert.equal(runOptions.sandbox, 'read-only')
assert.deepEqual(runOptions.attachments, ['/tmp/project/input.txt'])
assert.equal(runOptions.onOutboundPayload, onOutboundPayload)
assert.equal(harness.runAgentCalls.length, 0)
const catalog = await harness.ipcHandlers.get('local-agent-installer:catalog')(harness.event())
const custom = catalog.agents.find(agent => agent.kind === 'custom-0123456789abcdef')
assert.equal(custom.custom, true)
assert.equal(custom.commandName, 'review-agent')
assert.equal('executable' in custom, false)
assert.equal('args' in custom, false)
assert.deepEqual(
await harness.ipcHandlers.get('local-agent-installer:skills')(
harness.event(), 'custom-0123456789abcdef',
),
{ supported: false, skills: [], total: 0, limit: 0 },
)
})
test('Custom Agent deletion is blocked while a local conversation references it', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-custom-agent-delete-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const kind = 'custom-0123456789abcdef'
const { harness } = loadMain(directory, {
customAgents: [{
kind,
label: 'Review Agent',
description: '',
commandName: 'review-agent',
promptMode: 'stdin',
custom: true,
installed: true,
}],
workspaceSnapshot: {
agents: [],
groups: [{ id: 'group-1', agentKinds: [kind] }],
messages: [],
localOnly: true,
},
})
await harness.ready()
await assert.rejects(
harness.ipcHandlers.get('local-custom-agent:delete')(harness.event(), kind),
{ message: 'CUSTOM_AGENT_IN_USE' },
)
assert.deepEqual(harness.customAgentStoreInstances[0].removed, [])
harness.workspaceInstances[0].state.groups = []
assert.deepEqual(
await harness.ipcHandlers.get('local-custom-agent:delete')(harness.event(), kind),
{ deleted: true, kind },
)
assert.deepEqual(harness.customAgentStoreInstances[0].removed, [kind])
})
test('a second desktop launch restores and focuses the existing window', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-single-instance-focus-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
windowFocused: false,
windowMinimized: true,
})
await harness.ready()
harness.appListeners.get('second-instance')()
assert.equal(harness.windows.length, 1)
assert.equal(harness.windows[0].restoreCount, 1)
assert.equal(harness.windows[0].showCount, 1)
assert.equal(harness.windows[0].focusCount, 1)
})
test('application activation cannot recreate a window after shutdown starts', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-shutdown-activate-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const originalWindow = harness.windows[0]
harness.appListeners.get('before-quit')({ preventDefault: () => {} })
originalWindow.windowListeners.get('closed')()
harness.appListeners.get('activate')()
assert.equal(harness.windows.length, 1)
await waitFor(() => harness.exitCalls.length === 1)
assert.deepEqual(harness.exitCalls, [0])
})
test('quit cleanup has a strict deadline when a runtime does not settle', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-quit-timeout-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { main } = loadMain(directory)
const result = await main.runQuitCleanup([
() => new Promise(() => {}),
() => Promise.reject(new Error('cleanup failed')),
], 5)
assert.deepEqual(result, { timedOut: true })
})
test('closing the app window does not stop an active main-process Channel receiver', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-channel-background-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, { channelReceiverCount: 1 })
await harness.ready()
const runtime = harness.channelIngressRuntimeInstances[0]
harness.appListeners.get('window-all-closed')()
assert.equal(runtime.startCount, 1)
assert.equal(runtime.shutdownCount, 0)
assert.equal(harness.quitCount, 0)
})
test('run completion uses sanitized renderer events and a localized background notification', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-notification-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, { locale: 'zh-CN', windowFocused: false })
await harness.ready()
const window = harness.windows[0]
const workspace = harness.workspaceInstances[0]
workspace.emit('run-finished', {
groupId: '历史群聊 1',
runId: 'run:trace.1',
mode: 'auto',
status: 'partial',
threadRootId: 'thread-1',
targetKinds: ['hermes', '../../private', 'hermes'],
completedKinds: ['hermes'],
failedKinds: ['codex', '../../private', 'codex'],
startedAt: 100,
finishedAt: 200,
path: '/private/workspace',
sessionRef: 'secret-session',
content: 'secret message body',
})
const finished = window.webContents.sent.find(([channel]) => (
channel === 'local-workspace:run-finished'
))
assert.deepEqual(finished, ['local-workspace:run-finished', {
groupId: '历史群聊 1',
runId: 'run:trace.1',
mode: 'auto',
status: 'partial',
threadRootId: 'thread-1',
targetKinds: ['hermes'],
completedKinds: ['hermes'],
failedKinds: ['codex'],
startedAt: 100,
finishedAt: 200,
}])
assert.equal(harness.notificationInstances.length, 1)
const notification = harness.notificationInstances[0]
assert.equal(notification.input.title, 'Meldwork · 部分完成')
assert.equal(notification.input.body, '1 个 Agent 完成,1 个未完成')
assert.equal(notification.input.icon?.isEmpty?.(), false)
assert.equal(notification.showCount, 1)
assert.doesNotMatch(
JSON.stringify(notification.input),
/private|secret-session|secret message|历史群聊|thread-1/,
)
notification.emit('click')
assert.equal(window.showCount, 1)
assert.equal(window.focusCount, 1)
assert.deepEqual(window.webContents.sent.at(-1), [
'local-workspace:open-group', { groupId: '历史群聊 1' },
])
workspace.emit('run-finished', {
groupId: 'group-1', status: 'completed', targetKinds: [], completedKinds: [],
})
assert.equal(harness.notificationInstances.length, 1)
})
test('runtime trace IPC forwards only sanitized allowlisted fields', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-run-event-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const window = harness.windows[0]
const workspace = harness.workspaceInstances[0]
workspace.emit('run-event', {
runId: 'run-1',
agentRunId: 'run-1:1:codex:agent-1',
groupId: '历史群聊 1',
threadRootId: 'thread-1',
agentKind: 'codex',
round: 1,
seq: 2,
timestamp: 100,
id: 'tool-1',
type: 'tool_result_summary',
status: 'completed',
title: 'search',
summary: 'Read /Users/private/work with token=private-value',
command: 'rg private',
executable: '/tmp/codex',
sessionRef: 'private-session',
env: { SECRET: 'private' },
})
assert.deepEqual(window.webContents.sent.at(-1), [
'local-workspace:run-event',
{
runId: 'run-1',
agentRunId: 'run-1:1:codex:agent-1',
groupId: '历史群聊 1',
threadRootId: 'thread-1',
agentKind: 'codex',
round: 1,
seq: 2,
timestamp: 100,
status: 'completed',
id: 'tool-1',
type: 'tool_result_summary',
title: 'search',
summary: 'Read [path] with credential=[redacted]',
},
])
const sentCount = window.webContents.sent.length
workspace.emit('run-event', {
runId: 'run-2', agentRunId: 'agent-2', groupId: 'group-1',
agentKind: '../../private', round: 1, seq: 1, timestamp: 100,
type: 'status', status: 'running',
})
assert.equal(window.webContents.sent.length, sentCount)
})
test('a completion notification restores a closed window and opens its local group', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-notification-restore-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, { deferRestoredWindowLoad: true })
await harness.ready()
const originalWindow = harness.windows[0]
const workspace = harness.workspaceInstances[0]
originalWindow.windowListeners.get('closed')()
workspace.emit('run-finished', {
groupId: 'group-restore',
status: 'completed',
targetKinds: ['codex'],
completedKinds: ['codex'],
})
assert.equal(harness.notificationInstances.length, 1)
assert.equal(harness.notificationInstances[0].input.title, 'Meldwork · Run completed')
assert.equal(harness.notificationInstances[0].input.body, '1 Agent completed the reply')
assert.equal(harness.notificationInstances[0].input.icon?.isEmpty?.(), false)
assert.equal(originalWindow.webContents.sent.length, 0)
harness.notificationInstances[0].emit('click')
assert.equal(harness.windows.length, 2)
const restoredWindow = harness.windows[1]
assert.equal(restoredWindow.showCount, 1)
assert.equal(restoredWindow.focusCount, 1)
assert.equal(restoredWindow.webContents.mainFrame.url, 'about:blank')
assert.deepEqual(restoredWindow.webContents.sent, [])
restoredWindow.finishLoad()
assert.deepEqual(restoredWindow.webContents.sent.at(-1), [
'local-workspace:open-group', { groupId: 'group-restore' },
])
restoredWindow.finishLoad()
assert.equal(restoredWindow.webContents.sent.length, 1)
})
test('attachment storage initialization failure does not block text chat startup', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-attachment-fallback-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
attachmentInitError: new Error('sensitive local storage path'),
})
await harness.ready()
assert.equal(harness.attachmentConstructionCount, 1)
assert.equal(harness.attachmentInstances.length, 0)
assert.equal(harness.windows.length, 1)
await assert.doesNotReject(
harness.ipcHandlers.get('local-workspace:send')(
harness.event(),
{ groupId: 'group-1', text: 'text still works', targetKinds: ['codex'], attachments: [] },
),
)
for (const [channel, args] of [
['local-attachments:pick', []],
['local-attachments:import', [{ name: 'x.png', mimeType: 'image/png', bytes: [1] }]],
['local-attachments:preview', ['attachment-1']],
['local-attachments:open', ['attachment-1']],
['local-attachments:discard', [['attachment-1']]],
]) {
await assert.rejects(
async () => harness.ipcHandlers.get(channel)(harness.event(), ...args),
{ message: 'LOCAL_ATTACHMENT_STORAGE_UNAVAILABLE' },
)
}
})
test('workspace run IPC requires an explicit non-empty Agent target contract', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-target-contract-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
for (const [channel, input] of [
['local-workspace:send', { groupId: 'group-1', text: 'Do the work' }],
['local-workspace:send', { groupId: 'group-1', text: 'Do the work', targetKinds: [] }],
]) {
await assert.rejects(
async () => harness.ipcHandlers.get(channel)(harness.event(), input),
{ message: 'LOCAL_MESSAGE_TARGET_REQUIRED' },
channel,
)
}
await assert.doesNotReject(() => harness.ipcHandlers.get('local-workspace:send')(
harness.event(),
{ groupId: 'group-1', text: 'Route the work', targetKinds: [], routingMode: 'automatic' },
))
})
test('workspace run IPC normalizes one strict collaboration protocol', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-protocol-contract-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const send = harness.ipcHandlers.get('local-workspace:send')
const workspace = harness.workspaceInstances[0]
const request = { groupId: 'group-1', text: 'Do the work', targetKinds: ['codex', 'hermes'] }
for (const selectors of [
{ protocol: 'v4 ' },
{ protocol: 'unknown', harnessVersion: 4 },
{ protocol: 'legacy', harnessVersion: 4 },
{ harnessVersion: 5 },
{ collaborationVersion: 2 },
{ v4: 'true' },
]) {
await assert.rejects(
async () => send(harness.event(), { ...request, ...selectors }),
{ message: 'LOCAL_MESSAGE_PROTOCOL_INVALID' },
)
}
assert.deepEqual(workspace.sendMessageCalls, [])
for (const [selectors, protocol] of [
[{}, 'legacy'],
[{ protocol: 'legacy' }, 'legacy'],
[{ protocol: 'v4' }, 'v4'],
[{ harnessVersion: 4 }, 'v4'],
[{ collaborationVersion: 4, v4: true }, 'v4'],
[{ harnessVersion: 3, collaborationVersion: 3, v4: false }, 'legacy'],
]) {
await send(harness.event(), { ...request, ...selectors })
assert.deepEqual(workspace.sendMessageCalls.at(-1), { ...request, protocol })
}
})
test('workspace stop IPC forwards only a validated group and run pair', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-stop-contract-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const stop = harness.ipcHandlers.get('local-workspace:stop')
const workspace = harness.workspaceInstances[0]
assert.equal(await stop(harness.event(), 'group-1', 'run:trace.1'), true)
assert.equal(await stop(harness.event(), '历史群聊 1', 'run-legacy'), true)
assert.deepEqual(workspace.stopCalls, [
{ groupId: 'group-1', runId: 'run:trace.1' },
{ groupId: '历史群聊 1', runId: 'run-legacy' },
])
assert.equal(await stop(harness.event(), 'group-1', ''), false)
assert.equal(await stop(harness.event(), 'group\ninvalid', 'run-2'), false)
assert.equal(await stop(harness.event(), 'group-1', '../run'), false)
assert.equal(workspace.stopCalls.length, 2)
})
test('workspace Agent control IPC accepts only a bound active Agent request', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-agent-control-contract-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const control = harness.ipcHandlers.get('local-workspace:control-agent')
const workspace = harness.workspaceInstances[0]
assert.equal(await control(
harness.event(), '群聊 1', 'run:trace.1', 'hermes', 'retry', '',
), true)
assert.equal(await control(
harness.event(), '群聊 1', 'run:trace.1', 'hermes', 'replace', 'codex',
), true)
assert.deepEqual(workspace.agentControlCalls, [
{
groupId: '群聊 1', runId: 'run:trace.1', kind: 'hermes', action: 'retry', replacementKind: '',
},
{
groupId: '群聊 1', runId: 'run:trace.1', kind: 'hermes', action: 'replace', replacementKind: 'codex',
},
])
for (const args of [
['group\ninvalid', 'run-1', 'hermes', 'cancel', ''],
['group-1', '../run', 'hermes', 'cancel', ''],
['group-1', 'run-1', '../hermes', 'cancel', ''],
['group-1', 'run-1', 'hermes', 'restart', ''],
['group-1', 'run-1', 'hermes', 'retry', 'codex'],
['group-1', 'run-1', 'hermes', 'replace', 'hermes'],
]) assert.equal(await control(harness.event(), ...args), false)
assert.equal(workspace.agentControlCalls.length, 2)
})
test('workspace Human Gate IPC derives decisions from the persisted option', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-human-gate-contract-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const decide = harness.ipcHandlers.get('local-workspace:decide-human-gate')
const workspace = harness.workspaceInstances[0]
const gateId = `human-gate-${'b'.repeat(64)}`
const inputGateId = `human-gate-${'c'.repeat(64)}`
workspace.state.humanGates = [{
gateId,
options: [
{ optionId: 'allow-once', name: 'Allow once', kind: 'allow_once' },
{ optionId: 'reject-once', name: 'Reject', kind: 'reject_once' },
{ optionId: 'reopen-task', name: 'Reopen Task', kind: 'reopen' },
],
}, {
gateId: inputGateId,
type: 'input',
options: [
{ optionId: 'submit-input', name: 'Submit', kind: 'respond' },
{ optionId: 'cancel-input', name: 'Cancel', kind: 'reject' },
],
}]
assert.deepEqual(await decide(harness.event(), gateId, {
status: 'approved', optionId: 'allow-once',
}), { gateId, status: 'approved', optionId: 'allow-once' })
assert.deepEqual(await decide(harness.event(), gateId, {
optionId: 'reopen-task',
}), { gateId, status: 'rejected', optionId: 'reopen-task' })
assert.deepEqual(await decide(harness.event(), inputGateId, {
optionId: 'submit-input', response: 'stable',
}), {
gateId: inputGateId, status: 'approved', optionId: 'submit-input', response: 'stable',
})
assert.deepEqual(workspace.humanGateDecisionCalls, [
{ gateId, decision: { status: 'approved', optionId: 'allow-once' } },
{ gateId, decision: { status: 'rejected', optionId: 'reopen-task' } },
{
gateId: inputGateId,
decision: { status: 'approved', optionId: 'submit-input', response: 'stable' },
},
])
for (const [invalidGateId, decision] of [
['gate-1', { status: 'approved', optionId: 'allow-once' }],
[gateId, { status: 'pending', optionId: 'allow-once' }],
[gateId, { status: 'approved', optionId: '../allow' }],
[gateId, { status: 'approved', optionId: 'allow-once', actorId: 'renderer' }],
[gateId, { status: 'approved', optionId: 'reopen-task' }],
[gateId, { optionId: 'allow-once', response: 'unexpected' }],
[inputGateId, { optionId: 'submit-input' }],
[inputGateId, { optionId: 'cancel-input', response: 'unexpected' }],
[gateId, { optionId: 'missing-option' }],
]) {
await assert.rejects(
async () => decide(harness.event(), invalidGateId, decision),
{ message: 'HUMAN_GATE_DECISION_INVALID' },
)
}
assert.equal(workspace.humanGateDecisionCalls.length, 3)
})
test('Cloud Agent IPC exposes only validated continuation and cancel actions', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-cloud-agent-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const runtime = harness.cloudAgentRuntimeInstances[0]
const provideInput = harness.ipcHandlers.get('local-cloud-agent:provide-input')
const decidePermission = harness.ipcHandlers.get('local-cloud-agent:decide-permission')
const cancel = harness.ipcHandlers.get('local-cloud-agent:cancel')
runtime.provideInput = (runId, requestId, value) => {
runtime.inputCalls.push({ runId, requestId, value })
return {
runId,
agentRunId: 'agent-run-cloud-1',
status: 'waiting_input',
connectorId: 'cloud-test',
jobId: 'private-job-1',
cursor: 'private-cursor-1',
artifactIds: ['artifact-1'],
evidenceIds: ['evidence-1'],
waiting: {
type: 'input', requestId, prompt: 'Which branch?',
jobId: 'nested-private-job', cursor: 'nested-private-cursor',
},
}
}
runtime.decidePermission = (runId, requestId, decision) => {
runtime.permissionCalls.push({ runId, requestId, decision })
return {
runId,
agentRunId: 'agent-run-cloud-1',
status: 'waiting_permission',
connectorId: 'cloud-test',
jobId: 'private-job-1',
cursor: 'private-cursor-2',
artifactIds: ['artifact-1'],
evidenceIds: ['evidence-1'],
waiting: {
type: 'permission', requestId, permission: 'workspace-write', summary: 'Apply patch',
jobId: 'nested-private-job', cursor: 'nested-private-cursor',
},
}
}
assert.deepEqual(
await provideInput(harness.event(), 'run-cloud-1', 'question-1', 'release/next'),
{
runId: 'run-cloud-1',
agentRunId: 'agent-run-cloud-1',
status: 'waiting_input',
connectorId: 'cloud-test',
artifactIds: ['artifact-1'],
evidenceIds: ['evidence-1'],
waiting: { type: 'input', requestId: 'question-1', prompt: 'Which branch?' },
},
)
assert.deepEqual(
await decidePermission(harness.event(), 'run-cloud-1', 'permission-1', 'approved'),
{
runId: 'run-cloud-1',
agentRunId: 'agent-run-cloud-1',
status: 'waiting_permission',
connectorId: 'cloud-test',
artifactIds: ['artifact-1'],
evidenceIds: ['evidence-1'],
waiting: {
type: 'permission', requestId: 'permission-1',
permission: 'workspace-write', summary: 'Apply patch',
},
},
)
assert.equal(await cancel(harness.event(), 'run-cloud-1'), true)
assert.deepEqual(runtime.inputCalls, [{
runId: 'run-cloud-1', requestId: 'question-1', value: 'release/next',
}])
assert.deepEqual(runtime.permissionCalls, [{
runId: 'run-cloud-1', requestId: 'permission-1', decision: 'approved',
}])
assert.deepEqual(runtime.cancelCalls, ['run-cloud-1'])
assert.throws(
() => provideInput(harness.event(), '../run', 'question-1', 'value'),
{ message: 'CLOUD_AGENT_INPUT_INVALID' },
)
assert.throws(
() => provideInput(harness.event(), 'run-cloud-1', 'question-1', ['private']),
{ message: 'CLOUD_AGENT_INPUT_INVALID' },
)
assert.throws(
() => decidePermission(harness.event(), 'run-cloud-1', 'permission-1', 'allow'),
{ message: 'CLOUD_AGENT_PERMISSION_DECISION_INVALID' },
)
assert.throws(
() => cancel(harness.event(), '../run'),
{ message: 'CLOUD_AGENT_RUN_INVALID' },
)
assert.equal(runtime.inputCalls.length, 1)
assert.equal(runtime.permissionCalls.length, 1)
assert.equal(runtime.cancelCalls.length, 1)
})
test('Outcome IPC persists every Adoption action with a main-owned human actor', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-outcome-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const workspace = harness.workspaceInstances[0]
const { contentBlobStore, outcomeStore } = workspace.input
const contentRef = contentBlobStore.put('Outcome IPC report', { mediaType: 'text/plain' })
const artifact = outcomeStore.putArtifact({
type: 'document',
name: 'outcome-ipc-report.txt',
producedBy: {
runId: 'run-outcome-1',
agentRunId: 'agent-run-outcome-1',
agentKind: 'codex',
},
contentRef,
contentHash: contentRef.hash,
})
const recordAdoption = harness.ipcHandlers.get('local-outcome:record-adoption')
let previousAdoptionId = null
for (const status of ['exported', 'applied', 'committed', 'sent']) {
const request = {
artifactId: artifact.artifactId,
status,
summary: `The local user recorded ${status}.`,
destinationRef: { kind: 'workspace-relative', path: `adoptions/${status}.json` },
previousAdoptionId,
}
const result = await recordAdoption(harness.event(), request)
assert.deepEqual(Object.keys(result).sort(), [
'adoptionId', 'artifactId', 'previousAdoptionId', 'status',
])
assert.equal(result.artifactId, artifact.artifactId)
assert.equal(result.status, status)
assert.equal(result.previousAdoptionId, previousAdoptionId)
const stored = outcomeStore.getAdoption(result.adoptionId)
assert.deepEqual(stored.actor, { kind: 'human', actorId: 'local-user' })
assert.deepEqual(stored.destinationRef, request.destinationRef)
previousAdoptionId = result.adoptionId
}
assert.throws(
() => recordAdoption(harness.event(), {
artifactId: artifact.artifactId,
status: 'exported',
destinationRef: { kind: 'workspace-relative', path: 'adoptions/exported.json' },
actor: { kind: 'agent', agentKind: 'codex' },
}),
{ message: 'LOCAL_ADOPTION_REQUEST_INVALID' },
)
assert.throws(
() => recordAdoption(harness.event(), {
artifactId: `artifact-${'a'.repeat(64)}`,
status: 'exported',
destinationRef: { kind: 'workspace-relative', path: 'adoptions/exported.json' },
}),
{ message: 'ARTIFACT_NOT_FOUND' },
)
assert.throws(
() => recordAdoption(harness.event(), {
artifactId: artifact.artifactId,
status: 'accepted',
destinationRef: { kind: 'workspace-relative', path: 'adoptions/accepted.json' },
}),
{ message: 'LOCAL_ADOPTION_REQUEST_INVALID' },
)
assert.throws(
() => recordAdoption(harness.event(), {
artifactId: artifact.artifactId,
status: 'exported',
}),
{ message: 'LOCAL_ADOPTION_REQUEST_INVALID' },
)
assert.throws(
() => recordAdoption(harness.event(), {
artifactId: artifact.artifactId,
status: 'sent',
summary: 'Authorization: Bearer renderer-secret-value',
destinationRef: { kind: 'uri', uri: 'https://example.test/delivery/1' },
}),
{ message: 'ADOPTION_FORBIDDEN_VALUE' },
)
})
test('startup attachment cleanup receives every persisted message reference once', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-attachment-cleanup-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
fs.writeFileSync(path.join(directory, 'meldwork-workspace.json'), JSON.stringify({
version: 2,
groups: [{ id: 'one' }, { id: 'two' }],
messages: [
{ groupId: 'one', attachments: [{ id: 'shared' }, { id: 'only-one' }] },
{ groupId: 'two', attachments: [{ id: 'shared' }] },
],
sessions: {},
}))
const { harness } = loadMain(directory, {
workspaceSnapshot: {
agents: [],
groups: [{ id: 'one' }, { id: 'two' }],
messages: [
{ groupId: 'one', attachments: [{ id: 'shared' }, { id: 'only-one' }] },
{ groupId: 'two', attachments: [{ id: 'shared' }] },
],
localOnly: true,
},
})
await harness.ready()
assert.deepEqual(harness.attachmentInstances[0].cleanupCalls, [['shared', 'only-one']])
})
test('startup attachment cleanup failure keeps the validated store available', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-attachment-cleanup-fallback-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
attachmentCleanupError: new Error('temporary cleanup failure'),
})
await harness.ready()
assert.deepEqual(harness.attachmentInstances[0].cleanupCalls, [[]])
await assert.doesNotReject(
harness.ipcHandlers.get('local-attachments:pick')(harness.event(), 1),
)
})
test('startup skips destructive attachment cleanup when the workspace file is malformed', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-attachment-corrupt-workspace-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
fs.writeFileSync(path.join(directory, 'meldwork-workspace.json'), '{not-json')
const { harness } = loadMain(directory)
await harness.ready()
assert.equal(harness.windows.length, 1)
assert.deepEqual(harness.attachmentInstances[0].cleanupCalls, [])
})
test('ready creates the desktop window without eagerly duplicating renderer Agent detection', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-ready-window-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
assert.equal(harness.windows.length, 1)
assert.equal(harness.workspaceInstances[0].refreshCount, 0)
})
test('Electron safeStorage stays lazy until after the desktop window exists', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-ready-safe-storage-'))
const safeStorageAccesses = []
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
onSafeStorageAccess: windowCount => safeStorageAccesses.push(windowCount),
})
await harness.ready()
assert.deepEqual(safeStorageAccesses, [])
assert.equal(harness.providerInstances[0].input.safeStorage.isEncryptionAvailable(), true)
assert.deepEqual(safeStorageAccesses, [1])
})
test('window navigation permits only local app pages and credential-free HTTPS links', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-navigation-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const window = harness.windows[0]
assert.equal(harness.permissionHandlers.check(), false)
let granted = true
harness.permissionHandlers.request(null, 'camera', value => { granted = value })
assert.equal(granted, false)
assert.equal(harness.permissionHandlers.device(), false)
assert.deepEqual(window.openHandler({ url: 'https://example.com/docs' }), { action: 'deny' })
assert.deepEqual(window.openHandler({ url: 'http://example.com' }), { action: 'deny' })
assert.deepEqual(window.openHandler({ url: 'https://user:[email protected]' }), { action: 'deny' })
assert.deepEqual(harness.externalUrls, ['https://example.com/docs'])
const navigate = window.webContents.listeners.get('will-navigate')
let prevented = 0
navigate({ preventDefault: () => { prevented += 1 } }, window.loads[0].url)
assert.equal(prevented, 0)
navigate(
{ preventDefault: () => { prevented += 1 } },
pathToFileURL(path.join(directory, 'untrusted.html')).href,
)
navigate({ preventDefault: () => { prevented += 1 } }, 'https://example.com/help')
navigate({ preventDefault: () => { prevented += 1 } }, 'javascript:alert(1)')
assert.equal(prevented, 3)
assert.deepEqual(harness.externalUrls, [
'https://example.com/docs',
'https://example.com/help',
])
})
test('Provider IPC accepts the complete user payload and supports local deletion', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-provider-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const input = { ...PROVIDER_METADATA, apiKey: 'renderer-provider-key', preset: 'custom' }
const initial = await harness.ipcHandlers.get('local-agent-provider:status')(
harness.event(), 'hermes',
)
assert.equal(initial.configured, false)
assert.deepEqual(harness.providerInstances[0].statusCalls, [{ kind: 'hermes', input: undefined }])
await harness.ipcHandlers.get('local-agent-provider:probe')(harness.event(), 'hermes')
assert.deepEqual(harness.providerInstances[0].statusCalls, [
{ kind: 'hermes', input: undefined },
{ kind: 'hermes', input: { probeEncryption: true } },
])
const saved = await harness.ipcHandlers.get('local-agent-provider:save')(
harness.event(), 'hermes', input,
)
assert.deepEqual(harness.providerInstances[0].saved, [{ kind: 'hermes', input }])
assert.equal(saved.configured, true)
assert.equal(harness.workspaceInstances[0].refreshCount, 1)
assert.deepEqual(harness.workspaceInstances[0].runtimeCredentialMarks, [
{ kind: 'hermes', credentialState: 'unknown' },
])
const activated = await harness.ipcHandlers.get('local-agent-provider:activate')(
harness.event(), 'hermes', 'custom',
)
assert.deepEqual(harness.providerInstances[0].activated, [{ kind: 'hermes', preset: 'custom' }])
assert.equal(activated.activePreset, 'custom')
assert.equal(harness.workspaceInstances[0].refreshCount, 2)
assert.deepEqual(harness.workspaceInstances[0].runtimeCredentialMarks, [
{ kind: 'hermes', credentialState: 'unknown' },
{ kind: 'hermes', credentialState: 'unknown' },
])
await assert.rejects(
async () => harness.ipcHandlers.get('local-agent-provider:status')(harness.event(), 'not-an-agent'),
{ message: 'PROVIDER_AGENT_UNSUPPORTED' },
)
const deleted = await harness.ipcHandlers.get('local-agent-provider:delete')(
harness.event(), 'hermes', 'custom',
)
assert.deepEqual(harness.providerInstances[0].deleted, [{ kind: 'hermes', preset: 'custom' }])
assert.equal(deleted.configured, false)
assert.equal(harness.workspaceInstances[0].refreshCount, 3)
assert.deepEqual(harness.workspaceInstances[0].runtimeCredentialMarks, [
{ kind: 'hermes', credentialState: 'unknown' },
{ kind: 'hermes', credentialState: 'unknown' },
{ kind: 'hermes', credentialState: 'unknown' },
])
})
test('Knowledge base IPC exposes status, safe guides, and a local Obsidian directory picker', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-knowledge-base-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const vaultPath = path.join(directory, 'Obsidian Vault')
fs.mkdirSync(vaultPath)
const { harness } = loadMain(directory, {
dialogResult: { canceled: false, filePaths: [vaultPath] },
knowledgeBaseGuideUrl: (kind, action) => (
kind === 'unsafe'
? 'http://example.com/unsafe'
: `https://example.com/${kind}/${action}`
),
})
await harness.ready()
const status = await harness.ipcHandlers.get('local-knowledge-base:status')(harness.event())
assert.deepEqual(status, [{ kind: 'obsidian', installed: true, vaultPath: '' }])
assert.equal(harness.knowledgeBaseResolveCalls[0].home, path.join(directory, 'Home'))
const opened = await harness.ipcHandlers.get('local-knowledge-base:open-guide')(
harness.event(), 'feishu', 'login',
)
assert.equal(opened, true)
assert.deepEqual(harness.externalUrls, ['https://example.com/feishu/login'])
const unsafe = await harness.ipcHandlers.get('local-knowledge-base:open-guide')(
harness.event(), 'unsafe', 'login',
)
assert.equal(unsafe, false)
assert.deepEqual(harness.externalUrls, ['https://example.com/feishu/login'])
const picked = await harness.ipcHandlers.get('local-knowledge-base:pick-obsidian-vault')(
harness.event(),
)
assert.deepEqual(harness.dialogCalls[0][1], {
properties: ['openDirectory', 'createDirectory'],
})
assert.deepEqual(harness.knowledgeBaseStoreInstances[0].savedVaultPaths, [vaultPath])
assert.deepEqual(picked, [{ kind: 'obsidian', installed: true, vaultPath }])
})
test('Knowledge Connector IPC exposes a sanitized complete lifecycle with main-owned source grants', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-knowledge-connector-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const vaultPath = path.join(directory, 'Private Obsidian Vault')
const notePath = path.join(vaultPath, 'notes', 'decision.md')
fs.mkdirSync(path.dirname(notePath), { recursive: true })
fs.writeFileSync(notePath, [
'Connector evidence for a decision.',
'api_key=sk-renderer-must-not-see-123456',
].join('\n'))
const { harness } = loadMain(directory, { obsidianVaultPath: vaultPath })
await harness.ready()
const list = harness.ipcHandlers.get('local-knowledge-connector:list')
const probe = harness.ipcHandlers.get('local-knowledge-connector:probe')
const search = harness.ipcHandlers.get('local-knowledge-connector:search')
const fetch = harness.ipcHandlers.get('local-knowledge-connector:fetch')
const snapshot = harness.ipcHandlers.get('local-knowledge-connector:snapshot')
const citation = harness.ipcHandlers.get('local-knowledge-connector:citation')
const revoke = harness.ipcHandlers.get('local-knowledge-connector:revoke')
const authorize = harness.ipcHandlers.get('local-knowledge-connector:authorize')
const select = harness.ipcHandlers.get('local-knowledge-connector:select')
const instances = await list(harness.event())
assert.equal(instances.length, 2)
const instance = instances.find(item => item.connectorId === 'knowledge.filesystem')
assert.ok(instance)
const probed = await probe(harness.event(), instance.instanceId)
const [source] = await search(harness.event(), instance.instanceId, {
query: 'evidence', limit: 5,
})
const sourceRequest = { sourceId: source.sourceId, locator: source.locator }
const fetched = await fetch(harness.event(), instance.instanceId, sourceRequest)
const captured = await snapshot(harness.event(), instance.instanceId, sourceRequest)
const cited = await citation(harness.event(), instance.instanceId, {
snapshotId: captured.snapshotId,
})
const selected = await select(harness.event(), instance.instanceId, {
...sourceRequest,
captureMode: 'snapshot',
})
const rendererPayload = JSON.stringify({
instances, probed, source, fetched, captured, cited, selected,
})
assert.equal(instance.accessMode, 'read-only')
assert.equal(probed.status, 'ready')
assert.equal(Object.hasOwn(selected, 'locator'), false)
assert.equal(Object.hasOwn(captured, 'contentRef'), false)
assert.equal(Object.hasOwn(cited.citation, 'contentRef'), false)
assert.match(fetched.content, /\[redacted\]/)
assert.doesNotMatch(rendererPayload, new RegExp(vaultPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
assert.doesNotMatch(rendererPayload, /credentialRef|sk-renderer-must-not-see/i)
const validated = await harness.workspaceInstances[0].input.validateKnowledgeBaseSelections(
['codex'],
[{ kind: 'obsidian', targetKinds: ['codex'], selectionId: selected.selectionId }],
)
assert.equal(validated[0].connectorSource.snapshot.sourceId, source.sourceId)
assert.equal(validated[0].connectorSource.citation.verification, 'snapshot')
fs.writeFileSync(notePath, 'Mutated after main-owned snapshot')
assert.match(
harness.workspaceInstances[0].input.contentBlobStore
.read(validated[0].connectorSource.snapshot.contentRef).toString('utf8'),
/Connector evidence/,
)
assert.throws(
() => list(harness.event(), 'unexpected'),
{ message: 'LOCAL_KNOWLEDGE_CONNECTOR_REQUEST_INVALID' },
)
await assert.rejects(
() => search(harness.event(), instance.instanceId, {
query: 'evidence', limit: 5, vaultPath,
}),
{ message: 'LOCAL_KNOWLEDGE_SEARCH_INVALID' },
)
await assert.rejects(
() => select(harness.event(), instance.instanceId, {
sourceId: source.sourceId,
locator: source.locator,
captureMode: 'snapshot',
credentialRef: 'credential-ref:renderer-controlled',
}),
{ message: 'LOCAL_KNOWLEDGE_SELECTION_INVALID' },
)
await assert.rejects(
() => fetch(harness.event(), instance.instanceId, {
sourceId: `knowledge-source-${'a'.repeat(64)}`,
locator: 'notes/private.md',
}),
{ message: 'LOCAL_KNOWLEDGE_SOURCE_NOT_GRANTED' },
)
await assert.rejects(
() => harness.workspaceInstances[0].input.validateKnowledgeBaseSelections(
['codex'],
[{
kind: 'obsidian', targetKinds: ['codex'], selectionId: selected.selectionId,
locator: source.locator,
}],
),
{ message: 'LOCAL_KNOWLEDGE_BASE_SELECTION_INVALID' },
)
const revoked = await revoke(harness.event(), instance.instanceId)
assert.equal(revoked.authorized, false)
const reauthorized = await authorize(harness.event(), 'knowledge.filesystem')
assert.equal(reauthorized.instanceId, instance.instanceId)
})
test('Knowledge base status IPC shares concurrent source probes', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-knowledge-base-single-flight-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const result = deferred()
const expected = [{ kind: 'feishu', installed: true, ready: true }]
const { harness } = loadMain(directory, {
resolveKnowledgeBaseSources: () => result.promise,
})
await harness.ready()
const status = harness.ipcHandlers.get('local-knowledge-base:status')
const first = status(harness.event())
const second = status(harness.event())
await waitFor(() => harness.knowledgeBaseResolveCalls.length === 1)
assert.equal(harness.knowledgeBaseResolveCalls.length, 1)
result.resolve(expected)
assert.deepEqual(await Promise.all([first, second]), [expected, expected])
assert.deepEqual(await status(harness.event()), expected)
assert.equal(harness.knowledgeBaseResolveCalls.length, 2)
})
test('Knowledge base selections derive safe access from main-process source status', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-knowledge-base-selection-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const source = {
kind: 'dingtalk',
label: 'DingTalk',
accessMode: 'cli',
commandName: 'dws',
ready: true,
}
const hintCalls = []
const { harness } = loadMain(directory, {
knowledgeBaseSources: [source],
knowledgeBaseSelectionHint: (cachedSource, targetKinds) => {
hintCalls.push({ cachedSource, targetKinds })
return cachedSource?.kind === 'dingtalk' ? {
kind: 'dingtalk',
name: 'DingTalk',
accessMode: 'cli',
commandName: cachedSource.commandName,
targetKinds,
} : null
},
})
await harness.ready()
const validate = harness.workspaceInstances[0].input.validateKnowledgeBaseSelections
const validated = await validate(['codex', 'hermes'], [{
kind: 'dingtalk',
targetKinds: ['hermes'],
commandName: 'renderer-controlled-command',
}])
assert.deepEqual(validated, [{
kind: 'dingtalk', name: 'DingTalk', accessMode: 'cli',
commandName: 'dws', targetKinds: ['hermes'],
}])
assert.deepEqual(hintCalls, [{ cachedSource: source, targetKinds: ['hermes'] }])
assert.equal(harness.knowledgeBaseResolveCalls.length, 1)
await assert.rejects(validate(['codex'], [{
kind: 'dingtalk', targetKinds: ['hermes'],
}]), { message: 'LOCAL_KNOWLEDGE_BASE_SELECTION_INVALID' })
})
test('directory picker uses the operating system localized title', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-directory-dialog-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory)
await harness.ready()
const selected = await harness.ipcHandlers.get('local-workspace:pick-directory')(harness.event())
assert.equal(selected, '')
assert.equal(harness.dialogCalls.length, 1)
assert.deepEqual(harness.dialogCalls[0][1], {
properties: ['openDirectory', 'createDirectory'],
})
})
test('Skills IPC uses the installed-Agent gate and the shared local catalog', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-skills-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const skillsResult = {
supported: true,
total: 1,
limit: 100,
skills: [{ targetKind: 'codex', namespace: 'global', slug: 'review', name: 'Review' }],
}
const { harness } = loadMain(directory, { skillsResult })
await harness.ready()
const result = await harness.ipcHandlers.get('local-agent-installer:skills')(
harness.event(), 'codex',
)
assert.deepEqual(result, skillsResult)
assert.equal(harness.installerInstances[0].skillsKind, 'codex')
assert.deepEqual(harness.installerInstances[0].input.listSkills('codex'), skillsResult)
assert.deepEqual(harness.skillCatalogInstances[0].listCalls, ['codex'])
})
test('attachment IPC returns bounded metadata, opens private files, and never exposes paths', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-image-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const first = path.join(directory, 'diagram.png')
const second = path.join(directory, 'flow.png')
const third = path.join(directory, 'overflow.png')
const { harness } = loadMain(directory, {
dialogResult: { canceled: false, filePaths: [first, second, third] },
})
await harness.ready()
const picked = await harness.ipcHandlers.get('local-attachments:pick')(
harness.event(), 2,
)
assert.equal(picked.attachments.length, 2)
assert.equal(picked.truncated, true)
assert.deepEqual(harness.attachmentInstances[0].importedFiles, [first, second])
assert.deepEqual(harness.dialogCalls[0][1], {
properties: ['openFile', 'multiSelections'],
filters: [{
name: 'Files',
extensions: require('../../src/attachments/attachment-records.cjs').ATTACHMENT_FILE_EXTENSIONS,
}],
})
for (const attachment of picked.attachments) {
assert.deepEqual(Object.keys(attachment).sort(), [
'id', 'mimeType', 'name', 'previewDataUrl', 'size',
])
assert.equal(attachment.previewDataUrl, 'data:image/png;base64,AQID')
assert.equal(JSON.stringify(attachment).includes(directory), false)
}
const imported = await harness.ipcHandlers.get('local-attachments:import')(
harness.event(),
{ name: 'paste.png', mimeType: 'image/png', bytes: [1, 2, 3] },
)
assert.equal(imported.name, 'paste.png')
assert.equal(imported.previewDataUrl, 'data:image/png;base64,AQID')
assert.deepEqual(harness.attachmentInstances[0].importedBuffers, [
{ name: 'paste.png', mimeType: 'image/png', bytes: [1, 2, 3] },
])
const previewed = await harness.ipcHandlers.get('local-attachments:preview')(
harness.event(), picked.attachments[0].id,
)
assert.equal(previewed.previewDataUrl, 'data:image/png;base64,AQID')
assert.deepEqual(harness.attachmentInstances[0].readWithMetadataCalls, [
picked.attachments[0].id,
picked.attachments[1].id,
imported.id,
picked.attachments[0].id,
])
assert.deepEqual(harness.attachmentInstances[0].resolved, [])
assert.equal('path' in previewed, false)
const opened = await harness.ipcHandlers.get('local-attachments:open')(
harness.event(), picked.attachments[0].id,
)
assert.equal(opened, true)
assert.deepEqual(harness.attachmentInstances[0].resolved, [[picked.attachments[0].id]])
assert.deepEqual(harness.openPathCalls, [
path.join(directory, 'attachments', picked.attachments[0].id, 'image.png'),
])
assert.equal(JSON.stringify(opened).includes(directory), false)
})
test('image picker does not import files after application shutdown starts', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-image-shutdown-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const dialogResult = deferred()
const selected = path.join(directory, 'late-selection.png')
const { harness } = loadMain(directory, { dialogResult: dialogResult.promise })
await harness.ready()
const picking = harness.ipcHandlers.get('local-attachments:pick')(harness.event())
await waitFor(() => harness.dialogCalls.length === 1)
harness.appListeners.get('before-quit')({ preventDefault: () => {} })
dialogResult.resolve({ canceled: false, filePaths: [selected] })
await assert.rejects(picking, { message: 'DESKTOP_CLIENT_SHUTTING_DOWN' })
assert.deepEqual(harness.attachmentInstances[0].importedFiles, [])
})
test('image dimensions are bounded before nativeImage decoding and checked again afterward', async (t) => {
const firstDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-image-pixels-before-'))
const secondDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-image-pixels-after-'))
t.after(() => fs.rmSync(firstDirectory, { recursive: true, force: true }))
t.after(() => fs.rmSync(secondDirectory, { recursive: true, force: true }))
const oversizedBeforeDecode = loadMain(firstDirectory, {
attachmentBytes: pngHeader(8193, 4096),
})
await oversizedBeforeDecode.harness.ready()
await assert.rejects(
async () => oversizedBeforeDecode.harness.ipcHandlers.get('local-attachments:import')(
oversizedBeforeDecode.harness.event(),
{ name: 'large.png', mimeType: 'image/png', bytes: [1, 2, 3] },
),
{ message: 'LOCAL_ATTACHMENT_TOO_LARGE' },
)
assert.equal(oversizedBeforeDecode.harness.nativeImageCalls.length, 0)
assert.equal(oversizedBeforeDecode.harness.attachmentInstances[0].discarded.length, 1)
const oversizedAfterDecode = loadMain(secondDirectory, {
attachmentBytes: pngHeader(1, 1),
nativeImageSize: { width: 8193, height: 4096 },
})
await oversizedAfterDecode.harness.ready()
await assert.rejects(
async () => oversizedAfterDecode.harness.ipcHandlers.get('local-attachments:import')(
oversizedAfterDecode.harness.event(),
{ name: 'decoded-large.png', mimeType: 'image/png', bytes: [1, 2, 3] },
),
{ message: 'LOCAL_ATTACHMENT_TOO_LARGE' },
)
assert.equal(oversizedAfterDecode.harness.nativeImageCalls.length, 1)
assert.equal(oversizedAfterDecode.harness.attachmentInstances[0].discarded.length, 1)
})
test('discard IPC is idempotent and refuses to delete attachments referenced by messages', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-discard-ipc-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
workspaceSnapshot: {
agents: [],
groups: [{ id: 'group-1' }],
messages: [{
groupId: 'group-1',
attachments: [{ id: 'referenced' }],
}],
localOnly: true,
},
})
await harness.ready()
const discard = harness.ipcHandlers.get('local-attachments:discard')
assert.deepEqual(
await discard(harness.event(), ['referenced', 'orphan', 'already-absent', 'orphan']),
{
discardedIds: ['orphan', 'already-absent'],
retainedIds: ['referenced'],
},
)
assert.deepEqual(harness.attachmentInstances[0].discarded, [
['orphan', 'already-absent'],
])
assert.deepEqual(
await discard(harness.event(), ['already-absent']),
{ discardedIds: ['already-absent'], retainedIds: [] },
)
})
test('deleting a conversation removes only attachments no longer referenced elsewhere', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-delete-attachments-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
workspaceSnapshot: {
agents: [],
groups: [{ id: 'group-one' }, { id: 'group-two' }],
messages: [
{
groupId: 'group-one',
attachments: [{ id: 'shared' }, { id: 'only-one' }],
},
{ groupId: 'group-two', attachments: [{ id: 'shared' }] },
],
localOnly: true,
},
})
await harness.ready()
const snapshot = await harness.ipcHandlers.get('local-workspace:delete-group')(
harness.event(), 'group-one',
)
assert.deepEqual(snapshot.groups, [{ id: 'group-two' }])
assert.deepEqual(snapshot.messages, [
{ groupId: 'group-two', attachments: [{ id: 'shared' }] },
])
assert.deepEqual(harness.attachmentInstances[0].discarded, [['only-one']])
})
test('deleting a message normalizes identifiers and discards only newly unreferenced attachments', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-delete-message-attachments-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
workspaceSnapshot: {
agents: [],
groups: [{ id: '42' }],
messages: [
{
id: '7', groupId: '42', role: 'agent',
attachments: [{ id: 'shared' }, { id: 'only-message' }],
},
{
id: '8', groupId: '42', role: 'agent',
attachments: [{ id: 'shared' }],
},
],
localOnly: true,
},
})
await harness.ready()
const snapshot = await harness.ipcHandlers.get('local-workspace:delete-message')(
harness.event(), 42, 7,
)
assert.deepEqual(harness.workspaceInstances[0].deleteMessageCalls, [['42', '7']])
assert.deepEqual(snapshot.messages, [{
id: '8', groupId: '42', role: 'agent', attachments: [{ id: 'shared' }],
}])
assert.deepEqual(harness.attachmentInstances[0].discarded, [['only-message']])
})
test('configured Provider is injected only through local Agent execution options', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-provider-routing-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const { harness } = loadMain(directory, {
providerConfigured: true,
nativeShellEnvironment: () => ({
env: { PATH: '/opt/native-agent/bin:/usr/bin' },
source: 'native-shell',
}),
nativeEnvironment: kind => kind === 'hermes'
? { ANTHROPIC_API_KEY: 'native-hermes-key' }
: {},
})
await harness.ready()
await harness.workspaceInstances[0].input.runAgent(
{ kind: 'hermes', executable: '/tmp/hermes' },
'hello', directory, { env: { CURRENT_RUN: '1' } },
)
const options = harness.runAgentCalls[0][3]
assert.deepEqual(options.provider, { id: 'openai-api', model: 'example-model' })
assert.equal(options.env.OPENAI_API_KEY, 'provider-key')
assert.equal(options.env.OPENAI_BASE_URL, PROVIDER_METADATA.baseUrl)
assert.equal(options.env.OPENAI_MODEL, PROVIDER_METADATA.model)
assert.equal(options.env.HERMES_INFERENCE_PROVIDER, 'openai-api')
assert.equal(options.env.HERMES_INFERENCE_MODEL, PROVIDER_METADATA.model)
assert.equal(options.env.ANTHROPIC_API_KEY, 'native-hermes-key')
assert.equal(options.env.CURRENT_RUN, '1')
assert.equal(options.env.PATH, '/opt/native-agent/bin:/usr/bin')
})
test('OpenClaw native auth is routed through the app-owned isolated runtime', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-openclaw-native-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const credentialChecks = []
const { harness } = loadMain(directory, {
moduleMocks: {
'./agents/local-agent-readiness.cjs': {
nativeCredentialEnvironment: kind => kind === 'openclaw'
? {
OPENCLAW_NATIVE_CONFIG: 'available',
OPENAI_API_KEY: 'unrelated-openai-key',
OPENROUTER_API_KEY: 'unrelated-openrouter-key',
}
: {},
resolveNativeOpenClawRuntime: async () => ({
model: 'native/model',
provider: {
id: 'native',
baseUrl: 'https://native.example.com/v1',
api: 'openai-completions',
apiKey: 'native-openclaw-key',
model: { id: 'model', name: 'Native Model', input: ['text'] },
},
}),
resolveNativeShellEnvironment: async () => ({
env: { PATH: '/opt/native-agent/bin:/usr/bin' },
source: 'native-shell',
}),
resolveNativeCredentialState: async (kind, input) => {
credentialChecks.push({ kind, input })
return { state: 'ready', source: 'native-credential' }
},
},
},
})
await harness.ready()
const workspace = harness.workspaceInstances[0]
const readiness = await workspace.input.credentialState('openclaw', {
executable: '/tmp/openclaw',
})
assert.deepEqual(readiness, { state: 'ready', source: 'native-credential' })
assert.equal(credentialChecks.length, 1)
assert.equal(credentialChecks[0].kind, 'openclaw')
assert.equal(credentialChecks[0].input.executable, '/tmp/openclaw')
assert.equal(credentialChecks[0].input.env.PATH, '/opt/native-agent/bin:/usr/bin')
assert.equal(credentialChecks[0].input.credentialSource, 'native-shell')
await workspace.input.runAgent(
{ kind: 'openclaw', executable: '/tmp/openclaw' },
'hello', directory, {
sessionRef: 'agent:main:desktop-native-openclaw',
env: {
GITHUB_TOKEN: 'caller-secret',
OPENAI_API_KEY: 'caller-openai-secret',
OPENROUTER_API_KEY: 'caller-openrouter-secret',
},
},
)
const options = harness.runAgentCalls[0][3]
assert.equal(Object.hasOwn(options.env, 'OPENCLAW_NATIVE_CONFIG'), false)
assert.equal(Object.hasOwn(options.env, 'OPENAI_API_KEY'), false)
assert.equal(Object.hasOwn(options.env, 'OPENROUTER_API_KEY'), false)
assert.equal(Object.hasOwn(options.env, 'GITHUB_TOKEN'), false)
assert.equal(Object.hasOwn(options.env, 'MANAGED_OPENCLAW'), false)
const isolated = JSON.parse(options.env.NATIVE_OPENCLAW)
assert.equal(isolated.workdir, directory)
assert.equal(isolated.sessionRef, 'agent:main:desktop-native-openclaw')
assert.equal(isolated.allowWrite, false)
assert.deepEqual(isolated.runtime, {
model: 'native/model',
provider: {
id: 'native',
baseUrl: 'https://native.example.com/v1',
api: 'openai-completions',
apiKey: 'native-openclaw-key',
model: { id: 'model', name: 'Native Model', input: ['text'] },
},
})
})
test('manual Agent refreshes remain serialized', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-refresh-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const firstGate = deferred()
const secondGate = deferred()
const { harness } = loadMain(directory, {
onRefresh: async (_workspace, count) => {
if (count === 1) await firstGate.promise
if (count === 2) await secondGate.promise
},
})
await harness.ready()
const handler = harness.ipcHandlers.get('local-workspace:refresh-agents')
const first = handler(harness.event())
const second = handler(harness.event())
await waitFor(() => harness.workspaceInstances[0].refreshCount === 1)
assert.equal(harness.workspaceInstances[0].maxConcurrentRefreshes, 1)
firstGate.resolve()
await waitFor(() => harness.workspaceInstances[0].refreshCount === 2)
assert.equal(harness.workspaceInstances[0].maxConcurrentRefreshes, 1)
secondGate.resolve()
await Promise.all([first, second])
assert.equal(harness.workspaceInstances[0].clearRuntimeCredentialFailuresCount, 0)
assert.equal(harness.installerInstances[0].invalidateCount, 2)
assert.equal(harness.skillCatalogInstances[0].invalidateCalls, 2)
})
test('before-quit waits for local workspace and installer cleanup', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'meldwork-quit-'))
t.after(() => fs.rmSync(directory, { recursive: true, force: true }))
const workspaceStopGate = deferred()
const installerIdleGate = deferred()
const cloudShutdownGate = deferred()
const { harness } = loadMain(directory, {
workspaceStopGate,
installerIdleGate,
cloudShutdownGate,
windowFocused: false,
installerState: { phase: 'installing', canCancel: true, taskId: 'task-1' },
})
await harness.ready()
let prevented = 0
harness.appListeners.get('before-quit')({ preventDefault: () => { prevented += 1 } })
assert.equal(prevented, 1)
assert.equal(harness.installerInstances[0].pendingCancelCount, 1)
assert.deepEqual(harness.installerInstances[0].cancelled, ['task-1'])
assert.equal(harness.channelIngressRuntimeInstances[0].shutdownCount, 1)
assert.equal(harness.cloudAgentRuntimeInstances[0].shutdownCount, 1)
assert.equal(harness.quitCount, 0)
harness.workspaceInstances[0].emit('run-finished', {
groupId: 'group-1', status: 'stopped', targetKinds: [], completedKinds: [],
})
assert.equal(harness.notificationInstances.length, 0)
for (const channel of LOCAL_IPC_CHANNELS) {
await assert.rejects(
Promise.resolve().then(() => harness.ipcHandlers.get(channel)(harness.event())),
{ message: 'DESKTOP_CLIENT_SHUTTING_DOWN' },
`${channel} should reject after shutdown starts`,
)
}
workspaceStopGate.resolve()
await new Promise(resolve => setImmediate(resolve))
assert.equal(harness.quitCount, 0)
installerIdleGate.resolve()
await new Promise(resolve => setImmediate(resolve))
assert.equal(harness.quitCount, 0)
cloudShutdownGate.resolve()
await waitFor(() => harness.exitCalls.length === 1)
assert.deepEqual(harness.exitCalls, [0])
assert.equal(harness.workspaceInstances[0].stopCount, 1)
})