Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,13 @@ jobs:
QWEN_DEFAULT_AUTH_TYPE: ''
run: |-
node -e "const fs = require('node:fs'); for (const key of ['HOME', 'USERPROFILE']) { const dir = process.env[key]; if (dir) fs.mkdirSync(dir, { recursive: true }); }"
# Not a duplicate of the pre-checkout autocrlf step: HOME and
# USERPROFILE are redirected for this step, so git reads a different
# global config here — and that step is gated on self-hosted runners,
# so on the hosted windows-2022 fallback it never runs. Deleting this
# line silently returns CRLF conversion to every git operation the
# suites perform, and no test notices.
git config --global core.autocrlf false
Comment thread
yiliang114 marked this conversation as resolved.
# ENOSPC has failed test steps mid-suite while the host looks
# healthy afterwards — a transient spike, likely /tmp inodes or a
# tmpfs cap. Sample the routed temp filesystem every 10s so the
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/windows-runner-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,10 @@ jobs:
QWEN_DEFAULT_AUTH_TYPE: ''
run: |-
node -e "const fs = require('node:fs'); for (const key of ['HOME', 'USERPROFILE']) { const dir = process.env[key]; if (dir) fs.mkdirSync(dir, { recursive: true }); }"
# Not a duplicate of the pre-checkout autocrlf step: HOME and
# USERPROFILE are redirected for this step, so git reads the empty
# profile created just above rather than the one that step wrote.
# Deleting this line silently returns CRLF conversion to every git
# operation the suites perform, and no test notices.
git config --global core.autocrlf false
Comment thread
yiliang114 marked this conversation as resolved.
npm run test:ci
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ describe('Mem0 Auto Recall local provider', () => {
const server = createTcpServer((socket) => {
connected = true;
sockets.push(socket);
socket.on('error', () => undefined);
});
servers.push(server);
await new Promise<void>((resolve) =>
Expand Down
105 changes: 104 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@
"LICENSE"
],
"devDependencies": {
"@emnapi/core": "1.11.3",
"@emnapi/runtime": "1.11.3",
"@types/chrome": "^0.1.32",
"@types/jsdom": "^28.0.3",
"@types/marked": "^5.0.2",
Expand Down
4 changes: 3 additions & 1 deletion packages/acp-bridge/src/sessionAttachments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,9 @@ describe('SessionAttachmentStore', () => {
);
await fs.mkdir(directory, { recursive: true });
await fs.writeFile(path.join(directory, 'notes.txt'), 'a');
await fs.writeFile(path.join(directory, 'bad?.txt'), 'b');
if (process.platform !== 'win32') {
await fs.writeFile(path.join(directory, 'bad?.txt'), 'b');
}
await fs.mkdir(path.join(directory, 'sub'));

expect((await store.list()).map((item) => item.attachmentId)).toEqual([
Expand Down
17 changes: 13 additions & 4 deletions packages/cli/src/acp-integration/acpAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7364,7 +7364,7 @@ describe('QwenAgent MCP SSE/HTTP support', () => {
});
});

it('rejects a standalone directory identity replaced during Config relocation', async () => {
it('rejects a standalone directory identity replaced during Config relocation', async (ctx) => {
await withEmptyTrustedFolders(async (directory) => {
const settings = makeSessionSettings({ mcpServers: {} });
const { agent, agentPromise, sessionId, innerConfig } =
Expand All @@ -7373,6 +7373,12 @@ describe('QwenAgent MCP SSE/HTTP support', () => {
const target = path.join(root, getConversationDirectoryName(sessionId));
await fs.mkdir(target, { recursive: true, mode: 0o700 });
const expectation = await managedConversationExpectation(root, sessionId);
if (expectation.child.inode === 0) {
mockConnectionState.resolve();
await agentPromise;
ctx.skip();
return;
}
innerConfig.getSessionSourceType.mockReturnValue('standalone');
innerConfig.relocateWorkingDirectory.mockImplementation(async () => {
const previous = `${expectation.child.canonicalPath}.previous`;
Expand Down Expand Up @@ -7973,7 +7979,8 @@ describe('QwenAgent MCP SSE/HTTP support', () => {
'trusted-capability',
);
try {
await agent.newSession({ cwd: '/tmp', mcpServers: [] });
const workspaceCwd = path.resolve('/tmp');
await agent.newSession({ cwd: workspaceCwd, mcpServers: [] });
const input = {
title: 'Docs',
locator: { type: 'workspace_file', workspacePath: 'README.md' },
Expand All @@ -7982,7 +7989,9 @@ describe('QwenAgent MCP SSE/HTTP support', () => {
sessionId,
input,
});
innerConfig.getTargetDir.mockReturnValue('/tmp/subdir');
innerConfig.getTargetDir.mockReturnValue(
path.join(workspaceCwd, 'subdir'),
);
const after = await agent.extMethod('qwen/session/sources/upsert', {
sessionId,
input,
Expand All @@ -7992,7 +8001,7 @@ describe('QwenAgent MCP SSE/HTTP support', () => {
change: 'unchanged',
source: before['source'],
});
expect(after['source']).toMatchObject({ workspaceCwd: '/tmp' });
expect(after['source']).toMatchObject({ workspaceCwd });
} finally {
mockConnectionState.resolve();
await agentPromise;
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/commands/review/cleanup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ describe('runCleanup', () => {
},
);

it('reads process.cwd() ONCE per run — the entry capture — and never downstream (R30-6)', () => {
it('reads process.cwd() ONCE per run — the entry capture — and never downstream (R30-6)', (ctx) => {
if (process.platform === 'win32') {
ctx.skip();
return;
}
// The mid-run half of the deleted-cwd class: the entry guard covers a cwd
// already gone, but `scratchWorktreesOf` used to read the cwd again later
// (`resolve(worktree)` against it, `redirectedAncestor`'s default stop),
Expand Down
8 changes: 7 additions & 1 deletion packages/cli/src/commands/review/findings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
mkdtempSync,
readFileSync,
rmSync,
statSync,
symlinkSync,
writeFileSync,
} from 'node:fs';
Expand Down Expand Up @@ -1444,7 +1445,7 @@ describe('findings (command boundary)', () => {
).toThrow(/--to-anchors must not be a symlink/);
});

it('refuses a --to-anchors hardlinked to a sibling file', () => {
it('refuses a --to-anchors hardlinked to a sibling file', (ctx) => {
// realpathSync never resolves hard links: two names of one inode compare
// as different path strings, so a string-identity guard admits them and
// both writes hit the same file — the exact destruction the guard exists
Expand All @@ -1455,6 +1456,11 @@ describe('findings (command boundary)', () => {
writeFileSync(out, JSON.stringify([base])); // a previous run's artifact
const anchors = join(dir, 'anchors.json');
linkSync(out, anchors);
const inode = statSync(out).ino;
if (!Number.isSafeInteger(inode) || inode <= 0) {
ctx.skip();
return;
}
expect(() =>
(findingsCommand.handler as (a: unknown) => void)({
input,
Expand Down
Loading
Loading