@cloudcli-ai/cloudcli 1.37.1 → 1.37.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/abnfDiagram-N423BO3Z-C4UAoHJb.js +1 -0
- package/dist/assets/arc-B8jF-ja9.js +1 -0
- package/dist/assets/architectureDiagram-T3A2C74G-C_Wur_CU.js +36 -0
- package/dist/assets/blockDiagram-VBNYF7ZC-Cq4P1i8t.js +132 -0
- package/dist/assets/c4Diagram-5PPSVZJV-C1wG4eUj.js +10 -0
- package/dist/assets/channel-_falYbU1.js +1 -0
- package/dist/assets/chunk-2GRJ4B5K-B8fnBG6E.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-WdfPooPJ.js +1 -0
- package/dist/assets/chunk-5RXB4S5H-DhZJuG2E.js +231 -0
- package/dist/assets/chunk-5VM5RSS4-B0rjslal.js +15 -0
- package/dist/assets/chunk-6Q2QTUOP-CG2Oj4jL.js +88 -0
- package/dist/assets/chunk-GF5L2VYU-rrl2lRxY.js +206 -0
- package/dist/assets/chunk-JWPE2WC7-CjVbrVMA.js +1 -0
- package/dist/assets/chunk-KBJHAD2P-CRzKgU8S.js +1 -0
- package/dist/assets/chunk-RYQCIY6F-DBz4GTZF.js +1 -0
- package/dist/assets/chunk-XXDRQBXY-wHxalsXk.js +1 -0
- package/dist/assets/classDiagram-JCYQIIEL-Dn-3CfpR.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-Dn-3CfpR.js +1 -0
- package/dist/assets/cose-bilkent-JH36ORCC-s1hygY8e.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-C4LGV15i.js +178 -0
- package/dist/assets/cynefinDiagram-MW4NZA55-C5uhu7B3.js +62 -0
- package/dist/assets/cytoscape.esm-C10L9Icf.js +331 -0
- package/dist/assets/dagre-VZM6K2ZE-B-OBTewm.js +4 -0
- package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/assets/diagram-7IWD3JNH-BjGKQxih.js +30 -0
- package/dist/assets/diagram-B4RE2ZJO-BMKz1X2L.js +3 -0
- package/dist/assets/diagram-LBJQPF4R-DNh-GhKC.js +24 -0
- package/dist/assets/diagram-Q27KOJAE-BaTG9jPT.js +24 -0
- package/dist/assets/diagram-UB23O5K3-BUwo2OvJ.js +41 -0
- package/dist/assets/ebnfDiagram-BXEA7PRR-DAZgfzX2.js +1 -0
- package/dist/assets/erDiagram-JOGREHBK-1w1CcGEb.js +85 -0
- package/dist/assets/flowDiagram-UKHOOZJN-D4EII8Jj.js +156 -0
- package/dist/assets/ganttDiagram-PKOTCBZU-ChvJZAgB.js +292 -0
- package/dist/assets/gitGraphDiagram-DS77QQ5N-DtOn41S8.js +106 -0
- package/dist/assets/graph-Cx-EqisW.js +1 -0
- package/dist/assets/index-CzPLBvXT.css +32 -0
- package/dist/assets/{index-DTMWjJj8.js → index-DFkBBuSA.js} +303 -304
- package/dist/assets/infoDiagram-6WML65LV-DN_PVEJZ.js +2 -0
- package/dist/assets/init-Gi6I4Gst.js +1 -0
- package/dist/assets/ishikawaDiagram-WSZJBQD7-DbkF1kXb.js +70 -0
- package/dist/assets/journeyDiagram-NVQOT4AX-pJwmhddE.js +139 -0
- package/dist/assets/kanban-definition-27J2QSJJ-PPAPgNp5.js +89 -0
- package/dist/assets/layout-D6BstSzF.js +1 -0
- package/dist/assets/linear-iPR-J9f7.js +1 -0
- package/dist/assets/map-CV9uif0g.js +1 -0
- package/dist/assets/mermaid.core-BEUL86Z6.js +312 -0
- package/dist/assets/mindmap-definition-FAOFIHXS-BvZoBib7.js +96 -0
- package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/assets/pegDiagram-VL7TDLO6-DhYreaUd.js +1 -0
- package/dist/assets/pieDiagram-7S7Q4E2Y-CrOHlyD0.js +39 -0
- package/dist/assets/quadrantDiagram-CIZ2JOQS-D4g5yH3t.js +7 -0
- package/dist/assets/railroadDiagram-AXF67PYL-Dj39lHlf.js +1 -0
- package/dist/assets/requirementDiagram-LRYGKXZP-1AS4Zgm_.js +84 -0
- package/dist/assets/sankeyDiagram-W5VNT64P-CKlMn19P.js +40 -0
- package/dist/assets/sequenceDiagram-SI44F4Z6-B_j3qyvo.js +162 -0
- package/dist/assets/sizeCapture-X5ZJPWSS-Bp2Op16v.js +1 -0
- package/dist/assets/stateDiagram-OKZ733FA-C0cN6DoY.js +1 -0
- package/dist/assets/stateDiagram-v2-UEYNNEHI-BvBxUUrZ.js +1 -0
- package/dist/assets/swimlanes-SLNWSIFB-BEvXOV9b.js +2 -0
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CsE-x4YK.js +8 -0
- package/dist/assets/timeline-definition-Z64GVDOM-zdJQinvZ.js +120 -0
- package/dist/assets/vennDiagram-T6HMQDX7-DuF1uZMY.js +34 -0
- package/dist/assets/wardleyDiagram-T6FBY63Y-B9AlLQup.js +78 -0
- package/dist/assets/xychartDiagram-ELKLHX3M-DTJX48Qg.js +7 -0
- package/dist/index.html +2 -2
- package/dist-server/server/index.js +1 -2
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/agent/agent.module.js +2 -1
- package/dist-server/server/modules/agent/agent.module.js.map +1 -1
- package/dist-server/server/modules/auth/auth.middleware.js +1 -1
- package/dist-server/server/modules/auth/auth.middleware.js.map +1 -1
- package/dist-server/server/modules/browser-use/browser-use-runtime.js +10 -0
- package/dist-server/server/modules/browser-use/browser-use-runtime.js.map +1 -0
- package/dist-server/server/modules/browser-use/browser-use.service.js +3 -6
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +2 -0
- package/dist-server/server/modules/browser-use/index.js.map +1 -1
- package/dist-server/server/modules/cli/cli.js +9 -3
- package/dist-server/server/modules/cli/cli.js.map +1 -1
- package/dist-server/server/modules/cli/cli.module.js +0 -1
- package/dist-server/server/modules/cli/cli.module.js.map +1 -1
- package/dist-server/server/modules/cli/cli.service.js +0 -18
- package/dist-server/server/modules/cli/cli.service.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +154 -0
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js +0 -3
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.service.js +18 -10
- package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -1
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +62 -11
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -1
- package/dist-server/server/modules/git/git-branch.service.js +15 -0
- package/dist-server/server/modules/git/git-branch.service.js.map +1 -0
- package/dist-server/server/modules/git/git.routes.js +15 -7
- package/dist-server/server/modules/git/git.routes.js.map +1 -1
- package/dist-server/server/modules/git/tests/git-branch.service.test.js +52 -0
- package/dist-server/server/modules/git/tests/git-branch.service.test.js.map +1 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js +84 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -1
- package/dist-server/server/modules/notifications/index.js +3 -1
- package/dist-server/server/modules/notifications/index.js.map +1 -1
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +22 -1
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js +254 -48
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +5 -0
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js +63 -7
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +35 -0
- package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -1
- package/dist-server/server/shared/utils.js +8 -0
- package/dist-server/server/shared/utils.js.map +1 -1
- package/package.json +6 -2
- package/scripts/promote-dist-server.mjs +50 -0
- package/server/index.ts +1 -2
- package/server/modules/agent/agent.module.ts +2 -1
- package/server/modules/auth/auth.middleware.ts +2 -2
- package/server/modules/browser-use/browser-use-runtime.ts +10 -0
- package/server/modules/browser-use/browser-use.service.ts +5 -8
- package/server/modules/browser-use/index.ts +3 -0
- package/server/modules/cli/cli.module.ts +0 -1
- package/server/modules/cli/cli.service.ts +0 -20
- package/server/modules/cli/cli.ts +9 -3
- package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -0
- package/server/modules/cli/tests/cli.service.test.ts +0 -3
- package/server/modules/file-tree/file-tree.service.ts +21 -10
- package/server/modules/file-tree/tests/file-tree.service.test.ts +65 -11
- package/server/modules/git/git-branch.service.ts +43 -0
- package/server/modules/git/git.routes.ts +16 -9
- package/server/modules/git/tests/git-branch.service.test.ts +60 -0
- package/server/modules/git/tests/git-init.routes.test.ts +83 -0
- package/server/modules/notifications/index.ts +2 -0
- package/server/modules/notifications/services/notification-orchestrator.service.js +24 -1
- package/server/modules/providers/list/claude/claude-runtime.provider.js +275 -54
- package/server/modules/providers/provider.routes.ts +5 -0
- package/server/modules/providers/services/session-conversations-search.service.ts +94 -7
- package/server/modules/providers/tests/provider.routes.test.ts +61 -0
- package/server/shared/types.ts +0 -1
- package/server/shared/utils.ts +10 -0
- package/server/tsconfig.json +6 -2
- package/README.de.md +0 -257
- package/README.ja.md +0 -249
- package/README.ko.md +0 -249
- package/README.md +0 -269
- package/README.ru.md +0 -257
- package/README.tr.md +0 -258
- package/README.zh-CN.md +0 -249
- package/README.zh-TW.md +0 -249
- package/dist/assets/index-D3jfzuKN.css +0 -32
- package/dist-server/server/constants/config.js +0 -6
- package/dist-server/server/constants/config.js.map +0 -1
- package/server/constants/config.ts +0 -5
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AppError } from '@/shared/utils.js';
|
|
2
|
+
|
|
3
|
+
type GitCommandResult = {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type GitCommandRunner = (
|
|
9
|
+
command: string,
|
|
10
|
+
args: string[],
|
|
11
|
+
options: { cwd: string },
|
|
12
|
+
) => Promise<GitCommandResult>;
|
|
13
|
+
|
|
14
|
+
type DeleteLocalBranchInput = {
|
|
15
|
+
projectPath: string;
|
|
16
|
+
branch: string;
|
|
17
|
+
force: boolean;
|
|
18
|
+
runCommand: GitCommandRunner;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Used by the Git routes module to safely delete a non-current local branch. */
|
|
22
|
+
export async function deleteLocalBranch(input: DeleteLocalBranchInput): Promise<string> {
|
|
23
|
+
const { stdout: currentBranch } = await input.runCommand(
|
|
24
|
+
'git',
|
|
25
|
+
['branch', '--show-current'],
|
|
26
|
+
{ cwd: input.projectPath },
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (currentBranch.trim() === input.branch) {
|
|
30
|
+
throw new AppError('Cannot delete the currently checked-out branch', {
|
|
31
|
+
code: 'GIT_CURRENT_BRANCH_DELETE',
|
|
32
|
+
statusCode: 400,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const deleteFlag = input.force ? '-D' : '-d';
|
|
37
|
+
const { stdout } = await input.runCommand(
|
|
38
|
+
'git',
|
|
39
|
+
['branch', deleteFlag, '--', input.branch],
|
|
40
|
+
{ cwd: input.projectPath },
|
|
41
|
+
);
|
|
42
|
+
return stdout;
|
|
43
|
+
}
|
|
@@ -8,6 +8,7 @@ import { AppError } from '@/shared/utils.js';
|
|
|
8
8
|
|
|
9
9
|
// cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
|
|
10
10
|
import { parseGitLogWithStats, parseGitStatusOutput } from './git-parsing.service.js';
|
|
11
|
+
import { deleteLocalBranch } from './git-branch.service.js';
|
|
11
12
|
|
|
12
13
|
type GitRouterDependencies = {
|
|
13
14
|
fileSystem: typeof import('node:fs/promises');
|
|
@@ -839,26 +840,32 @@ router.post('/create-branch', async (req, res) => {
|
|
|
839
840
|
|
|
840
841
|
// Delete a local branch
|
|
841
842
|
router.post('/delete-branch', async (req, res) => {
|
|
842
|
-
const { project, branch } = req.body;
|
|
843
|
+
const { project, branch, force = false } = req.body;
|
|
843
844
|
|
|
844
845
|
if (!project || !branch) {
|
|
845
846
|
return res.status(400).json({ error: 'Project id and branch name are required' });
|
|
846
847
|
}
|
|
847
848
|
|
|
849
|
+
if (typeof force !== 'boolean') {
|
|
850
|
+
return res.status(400).json({ error: 'force must be a boolean' });
|
|
851
|
+
}
|
|
852
|
+
|
|
848
853
|
try {
|
|
849
854
|
const projectPath = await getActualProjectPath(project);
|
|
850
855
|
await validateGitRepository(projectPath);
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
const { stdout } = await spawnAsync('git', ['branch', '-d', branch], { cwd: projectPath });
|
|
856
|
+
validateBranchName(branch);
|
|
857
|
+
const stdout = await deleteLocalBranch({
|
|
858
|
+
projectPath,
|
|
859
|
+
branch,
|
|
860
|
+
force,
|
|
861
|
+
runCommand: spawnAsync,
|
|
862
|
+
});
|
|
859
863
|
res.json({ success: true, output: stdout });
|
|
860
864
|
} catch (error) {
|
|
861
865
|
console.error('Git delete branch error:', error);
|
|
866
|
+
if (error instanceof AppError) {
|
|
867
|
+
return res.status(error.statusCode).json({ error: error.message });
|
|
868
|
+
}
|
|
862
869
|
res.status(500).json({ error: error.message });
|
|
863
870
|
}
|
|
864
871
|
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { deleteLocalBranch } from '../git-branch.service.js';
|
|
5
|
+
|
|
6
|
+
test('deleteLocalBranch uses safe deletion by default', async () => {
|
|
7
|
+
const commands: string[][] = [];
|
|
8
|
+
const output = await deleteLocalBranch({
|
|
9
|
+
projectPath: '/workspace/repo',
|
|
10
|
+
branch: 'feature/safe-delete',
|
|
11
|
+
force: false,
|
|
12
|
+
runCommand: async (_command, args) => {
|
|
13
|
+
commands.push(args);
|
|
14
|
+
return {
|
|
15
|
+
stdout: args.includes('--show-current') ? 'main\n' : 'Deleted branch feature/safe-delete.\n',
|
|
16
|
+
stderr: '',
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
assert.equal(output, 'Deleted branch feature/safe-delete.\n');
|
|
22
|
+
assert.deepEqual(commands, [
|
|
23
|
+
['branch', '--show-current'],
|
|
24
|
+
['branch', '-d', '--', 'feature/safe-delete'],
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('deleteLocalBranch uses force deletion only when requested', async () => {
|
|
29
|
+
const commands: string[][] = [];
|
|
30
|
+
await deleteLocalBranch({
|
|
31
|
+
projectPath: '/workspace/repo',
|
|
32
|
+
branch: 'feature/unmerged',
|
|
33
|
+
force: true,
|
|
34
|
+
runCommand: async (_command, args) => {
|
|
35
|
+
commands.push(args);
|
|
36
|
+
return { stdout: args.includes('--show-current') ? 'main\n' : '', stderr: '' };
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
assert.deepEqual(commands, [
|
|
41
|
+
['branch', '--show-current'],
|
|
42
|
+
['branch', '-D', '--', 'feature/unmerged'],
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('deleteLocalBranch refuses to delete the current branch even when forced', async () => {
|
|
47
|
+
await assert.rejects(
|
|
48
|
+
deleteLocalBranch({
|
|
49
|
+
projectPath: '/workspace/repo',
|
|
50
|
+
branch: 'feature/current',
|
|
51
|
+
force: true,
|
|
52
|
+
runCommand: async () => ({ stdout: 'feature/current\n', stderr: '' }),
|
|
53
|
+
}),
|
|
54
|
+
(error: unknown) => {
|
|
55
|
+
assert.equal((error as { code?: string }).code, 'GIT_CURRENT_BRANCH_DELETE');
|
|
56
|
+
assert.equal((error as { statusCode?: number }).statusCode, 400);
|
|
57
|
+
return true;
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
});
|
|
@@ -50,3 +50,86 @@ test('git init does not run when repository validation fails for an execution er
|
|
|
50
50
|
|
|
51
51
|
assert.deepEqual(commands, [['rev-parse', '--is-inside-work-tree']]);
|
|
52
52
|
});
|
|
53
|
+
|
|
54
|
+
test('delete branch parses force and uses Git force deletion', async () => {
|
|
55
|
+
const commands: string[][] = [];
|
|
56
|
+
const spawnProcess = ((_command: string, args: string[]) => {
|
|
57
|
+
commands.push(args);
|
|
58
|
+
const child = new EventEmitter() as EventEmitter & { stdout: PassThrough; stderr: PassThrough };
|
|
59
|
+
child.stdout = new PassThrough();
|
|
60
|
+
child.stderr = new PassThrough();
|
|
61
|
+
process.nextTick(() => {
|
|
62
|
+
if (args.includes('--is-inside-work-tree')) child.stdout.write('true\n');
|
|
63
|
+
if (args.includes('--show-toplevel')) child.stdout.write('/workspace/repo\n');
|
|
64
|
+
if (args.includes('--show-current')) child.stdout.write('main\n');
|
|
65
|
+
if (args.includes('-D')) child.stdout.write('Deleted branch feature/unmerged.\n');
|
|
66
|
+
child.stdout.end();
|
|
67
|
+
child.stderr.end();
|
|
68
|
+
child.emit('close', 0);
|
|
69
|
+
});
|
|
70
|
+
return child;
|
|
71
|
+
}) as Parameters<typeof createGitRouter>[0]['spawnProcess'];
|
|
72
|
+
const unexpectedProvider = async (): Promise<never> => { throw new Error('unexpected provider call'); };
|
|
73
|
+
const router = createGitRouter({
|
|
74
|
+
fileSystem: { access: async () => undefined } as unknown as Parameters<typeof createGitRouter>[0]['fileSystem'],
|
|
75
|
+
spawnProcess,
|
|
76
|
+
resolveProjectPathById: () => '/workspace/repo',
|
|
77
|
+
queryClaude: unexpectedProvider,
|
|
78
|
+
queryCursor: unexpectedProvider,
|
|
79
|
+
});
|
|
80
|
+
const app = express();
|
|
81
|
+
app.use(express.json());
|
|
82
|
+
app.use('/api/git', router);
|
|
83
|
+
const server = app.listen(0, '127.0.0.1');
|
|
84
|
+
await once(server, 'listening');
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const address = server.address() as AddressInfo;
|
|
88
|
+
const response = await fetch(`http://127.0.0.1:${address.port}/api/git/delete-branch`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: { 'content-type': 'application/json' },
|
|
91
|
+
body: JSON.stringify({ project: 'project-1', branch: 'feature/unmerged', force: true }),
|
|
92
|
+
});
|
|
93
|
+
const body = await response.json() as { success: boolean; output: string };
|
|
94
|
+
assert.equal(response.status, 200);
|
|
95
|
+
assert.equal(body.success, true);
|
|
96
|
+
assert.match(body.output, /Deleted branch/);
|
|
97
|
+
} finally {
|
|
98
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
assert.deepEqual(commands.at(-1), ['branch', '-D', '--', 'feature/unmerged']);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('delete branch rejects a non-boolean force value before running Git', async () => {
|
|
105
|
+
const spawnProcess = (() => {
|
|
106
|
+
throw new Error('Git must not run for invalid input');
|
|
107
|
+
}) as Parameters<typeof createGitRouter>[0]['spawnProcess'];
|
|
108
|
+
const unexpectedProvider = async (): Promise<never> => { throw new Error('unexpected provider call'); };
|
|
109
|
+
const router = createGitRouter({
|
|
110
|
+
fileSystem: { access: async () => undefined } as unknown as Parameters<typeof createGitRouter>[0]['fileSystem'],
|
|
111
|
+
spawnProcess,
|
|
112
|
+
resolveProjectPathById: () => '/workspace/repo',
|
|
113
|
+
queryClaude: unexpectedProvider,
|
|
114
|
+
queryCursor: unexpectedProvider,
|
|
115
|
+
});
|
|
116
|
+
const app = express();
|
|
117
|
+
app.use(express.json());
|
|
118
|
+
app.use('/api/git', router);
|
|
119
|
+
const server = app.listen(0, '127.0.0.1');
|
|
120
|
+
await once(server, 'listening');
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const address = server.address() as AddressInfo;
|
|
124
|
+
const response = await fetch(`http://127.0.0.1:${address.port}/api/git/delete-branch`, {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
headers: { 'content-type': 'application/json' },
|
|
127
|
+
body: JSON.stringify({ project: 'project-1', branch: 'feature/unmerged', force: 'yes' }),
|
|
128
|
+
});
|
|
129
|
+
const body = await response.json() as { error: string };
|
|
130
|
+
assert.equal(response.status, 400);
|
|
131
|
+
assert.equal(body.error, 'force must be a boolean');
|
|
132
|
+
} finally {
|
|
133
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
134
|
+
}
|
|
135
|
+
});
|
|
@@ -9,6 +9,8 @@ export {
|
|
|
9
9
|
notifyRunFailed,
|
|
10
10
|
// Used by provider runtimes to report stopped or completed agent runs.
|
|
11
11
|
notifyRunStopped,
|
|
12
|
+
// Used by provider runtimes to report background work that finished after its turn ended.
|
|
13
|
+
notifyBackgroundWorkCompleted,
|
|
12
14
|
} from '@/modules/notifications/services/notification-orchestrator.service.js';
|
|
13
15
|
export {
|
|
14
16
|
registerDesktopNotificationClient,
|
|
@@ -155,6 +155,7 @@ function buildNotificationPayload(event) {
|
|
|
155
155
|
? `Action Required: Tool "${normalizedEvent.meta.toolName}" needs approval`
|
|
156
156
|
: 'Action Required: A tool needs your approval',
|
|
157
157
|
'run.stopped': normalizedEvent.meta?.stopReason || 'Run Stopped: The run has stopped',
|
|
158
|
+
'run.background_completed': 'Background work finished',
|
|
158
159
|
'run.failed': normalizedEvent.meta?.error ? `Run Failed: ${normalizedEvent.meta.error}` : 'Run Failed: The run encountered an error',
|
|
159
160
|
'agent.notification': normalizedEvent.meta?.message ? String(normalizedEvent.meta.message) : 'You have a new notification',
|
|
160
161
|
'push.enabled': 'Push notifications are now enabled!'
|
|
@@ -261,6 +262,27 @@ function notifyRunStopped({ userId, provider, sessionId = null, stopReason = 'co
|
|
|
261
262
|
});
|
|
262
263
|
}
|
|
263
264
|
|
|
265
|
+
/**
|
|
266
|
+
* Reports background work that finished after its turn had already completed.
|
|
267
|
+
*
|
|
268
|
+
* Uses the `stop` kind so it rides the existing "run stopped" preference rather
|
|
269
|
+
* than needing a new opt-in that would default to off. No explicit dedupeKey, so
|
|
270
|
+
* the default composite key collapses repeats inside the dedupe window.
|
|
271
|
+
*/
|
|
272
|
+
function notifyBackgroundWorkCompleted({ userId, provider, sessionId = null, sessionName = null }) {
|
|
273
|
+
notifyUserIfEnabled({
|
|
274
|
+
userId,
|
|
275
|
+
event: createNotificationEvent({
|
|
276
|
+
provider,
|
|
277
|
+
sessionId,
|
|
278
|
+
kind: 'stop',
|
|
279
|
+
code: 'run.background_completed',
|
|
280
|
+
meta: { sessionName },
|
|
281
|
+
severity: 'info'
|
|
282
|
+
})
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
264
286
|
function notifyRunFailed({ userId, provider, sessionId = null, error, sessionName = null }) {
|
|
265
287
|
const errorMessage = normalizeErrorMessage(error);
|
|
266
288
|
|
|
@@ -283,5 +305,6 @@ export {
|
|
|
283
305
|
createNotificationEvent,
|
|
284
306
|
notifyUserIfEnabled,
|
|
285
307
|
notifyRunStopped,
|
|
286
|
-
notifyRunFailed
|
|
308
|
+
notifyRunFailed,
|
|
309
|
+
notifyBackgroundWorkCompleted
|
|
287
310
|
};
|