@scardis/omnifocus-mcp 0.1.0 → 0.1.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/schemas/shapes.d.ts +3 -33
- package/dist/schemas/shapes.d.ts.map +1 -1
- package/dist/schemas/shapes.js +3 -5
- package/dist/schemas/shapes.js.map +1 -1
- package/dist/server.js +3 -5
- package/dist/server.js.map +1 -1
- package/dist/tools/createTask.d.ts +1 -11
- package/dist/tools/createTask.d.ts.map +1 -1
- package/dist/tools/editTask.d.ts +1 -11
- package/dist/tools/editTask.d.ts.map +1 -1
- package/dist/tools/index.d.ts +2 -22
- package/dist/tools/index.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/snippets/edit_task.js +4 -6
- package/.claude/commands/opsx/apply.md +0 -152
- package/.claude/commands/opsx/archive.md +0 -157
- package/.claude/commands/opsx/bulk-archive.md +0 -242
- package/.claude/commands/opsx/continue.md +0 -114
- package/.claude/commands/opsx/explore.md +0 -173
- package/.claude/commands/opsx/ff.md +0 -97
- package/.claude/commands/opsx/new.md +0 -69
- package/.claude/commands/opsx/onboard.md +0 -550
- package/.claude/commands/opsx/propose.md +0 -106
- package/.claude/commands/opsx/sync.md +0 -134
- package/.claude/commands/opsx/verify.md +0 -164
- package/.claude/skills/openspec-apply-change/SKILL.md +0 -156
- package/.claude/skills/openspec-archive-change/SKILL.md +0 -114
- package/.claude/skills/openspec-bulk-archive-change/SKILL.md +0 -246
- package/.claude/skills/openspec-continue-change/SKILL.md +0 -118
- package/.claude/skills/openspec-explore/SKILL.md +0 -288
- package/.claude/skills/openspec-ff-change/SKILL.md +0 -101
- package/.claude/skills/openspec-new-change/SKILL.md +0 -74
- package/.claude/skills/openspec-onboard/SKILL.md +0 -554
- package/.claude/skills/openspec-propose/SKILL.md +0 -110
- package/.claude/skills/openspec-sync-specs/SKILL.md +0 -138
- package/.claude/skills/openspec-verify-change/SKILL.md +0 -168
- package/CONTRIBUTING.md +0 -83
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/design.md +0 -162
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/proposal.md +0 -49
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/attachments/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/batch-operations/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/database-inspection/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/execution-runtime/spec.md +0 -69
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/folder-management/spec.md +0 -25
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/forecast/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/identity-resolution/spec.md +0 -45
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/perspective-management/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/project-management/spec.md +0 -25
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/recurrence/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/settings/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/tag-management/spec.md +0 -25
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/task-management/spec.md +0 -29
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/url-automation/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/window-state/spec.md +0 -9
- package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/tasks.md +0 -84
- package/openspec/changes/archive/2026-04-09-folder-crud/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-folder-crud/design.md +0 -58
- package/openspec/changes/archive/2026-04-09-folder-crud/proposal.md +0 -28
- package/openspec/changes/archive/2026-04-09-folder-crud/specs/folder-write/spec.md +0 -45
- package/openspec/changes/archive/2026-04-09-folder-crud/tasks.md +0 -41
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/design.md +0 -38
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/proposal.md +0 -30
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/specs/folder-management/spec.md +0 -21
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/specs/tag-management/spec.md +0 -21
- package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/tasks.md +0 -35
- package/openspec/changes/archive/2026-04-09-move-operations/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-move-operations/design.md +0 -43
- package/openspec/changes/archive/2026-04-09-move-operations/proposal.md +0 -25
- package/openspec/changes/archive/2026-04-09-move-operations/specs/move-operations/spec.md +0 -41
- package/openspec/changes/archive/2026-04-09-move-operations/tasks.md +0 -40
- package/openspec/changes/archive/2026-04-09-project-crud/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-project-crud/design.md +0 -60
- package/openspec/changes/archive/2026-04-09-project-crud/proposal.md +0 -29
- package/openspec/changes/archive/2026-04-09-project-crud/specs/project-write/spec.md +0 -74
- package/openspec/changes/archive/2026-04-09-project-crud/tasks.md +0 -48
- package/openspec/changes/archive/2026-04-09-project-filtering/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-project-filtering/design.md +0 -52
- package/openspec/changes/archive/2026-04-09-project-filtering/proposal.md +0 -26
- package/openspec/changes/archive/2026-04-09-project-filtering/specs/project-filtering/spec.md +0 -66
- package/openspec/changes/archive/2026-04-09-project-filtering/specs/project-management/spec.md +0 -13
- package/openspec/changes/archive/2026-04-09-project-filtering/tasks.md +0 -41
- package/openspec/changes/archive/2026-04-09-tag-crud/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-tag-crud/design.md +0 -45
- package/openspec/changes/archive/2026-04-09-tag-crud/proposal.md +0 -28
- package/openspec/changes/archive/2026-04-09-tag-crud/specs/tag-write/spec.md +0 -49
- package/openspec/changes/archive/2026-04-09-tag-crud/tasks.md +0 -41
- package/openspec/changes/archive/2026-04-09-task-crud/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-task-crud/design.md +0 -62
- package/openspec/changes/archive/2026-04-09-task-crud/proposal.md +0 -29
- package/openspec/changes/archive/2026-04-09-task-crud/specs/task-management/spec.md +0 -17
- package/openspec/changes/archive/2026-04-09-task-crud/specs/task-write/spec.md +0 -89
- package/openspec/changes/archive/2026-04-09-task-crud/tasks.md +0 -55
- package/openspec/changes/archive/2026-04-09-task-filtering/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-09-task-filtering/design.md +0 -61
- package/openspec/changes/archive/2026-04-09-task-filtering/proposal.md +0 -26
- package/openspec/changes/archive/2026-04-09-task-filtering/specs/task-filtering/spec.md +0 -63
- package/openspec/changes/archive/2026-04-09-task-filtering/specs/task-management/spec.md +0 -17
- package/openspec/changes/archive/2026-04-09-task-filtering/tasks.md +0 -42
- package/openspec/changes/archive/2026-04-10-planned-date/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-10-planned-date/design.md +0 -27
- package/openspec/changes/archive/2026-04-10-planned-date/proposal.md +0 -29
- package/openspec/changes/archive/2026-04-10-planned-date/specs/task-management/spec.md +0 -29
- package/openspec/changes/archive/2026-04-10-planned-date/specs/task-write/spec.md +0 -69
- package/openspec/changes/archive/2026-04-10-planned-date/tasks.md +0 -26
- package/openspec/changes/archive/2026-04-10-task-recurrence/.openspec.yaml +0 -2
- package/openspec/changes/archive/2026-04-10-task-recurrence/design.md +0 -81
- package/openspec/changes/archive/2026-04-10-task-recurrence/proposal.md +0 -28
- package/openspec/changes/archive/2026-04-10-task-recurrence/specs/recurrence/spec.md +0 -47
- package/openspec/changes/archive/2026-04-10-task-recurrence/specs/task-management/spec.md +0 -25
- package/openspec/changes/archive/2026-04-10-task-recurrence/specs/task-write/spec.md +0 -61
- package/openspec/changes/archive/2026-04-10-task-recurrence/tasks.md +0 -39
- package/openspec/config.yaml +0 -20
- package/openspec/specs/attachments/spec.md +0 -15
- package/openspec/specs/batch-operations/spec.md +0 -15
- package/openspec/specs/database-inspection/spec.md +0 -15
- package/openspec/specs/execution-runtime/spec.md +0 -75
- package/openspec/specs/folder-management/spec.md +0 -39
- package/openspec/specs/folder-write/spec.md +0 -45
- package/openspec/specs/forecast/spec.md +0 -15
- package/openspec/specs/identity-resolution/spec.md +0 -51
- package/openspec/specs/move-operations/spec.md +0 -41
- package/openspec/specs/perspective-management/spec.md +0 -15
- package/openspec/specs/project-filtering/spec.md +0 -72
- package/openspec/specs/project-management/spec.md +0 -31
- package/openspec/specs/project-write/spec.md +0 -79
- package/openspec/specs/recurrence/spec.md +0 -51
- package/openspec/specs/settings/spec.md +0 -15
- package/openspec/specs/tag-management/spec.md +0 -39
- package/openspec/specs/tag-write/spec.md +0 -49
- package/openspec/specs/task-filtering/spec.md +0 -63
- package/openspec/specs/task-management/spec.md +0 -51
- package/openspec/specs/task-write/spec.md +0 -115
- package/openspec/specs/url-automation/spec.md +0 -15
- package/openspec/specs/window-state/spec.md +0 -15
- package/scripts/cleanup-fixtures.ts +0 -89
- package/server.json +0 -21
- package/src/runtime/bridge.ts +0 -97
- package/src/runtime/index.ts +0 -4
- package/src/runtime/jxaShim.ts +0 -55
- package/src/runtime/resultProtocol.ts +0 -62
- package/src/runtime/snippetLoader.ts +0 -79
- package/src/schemas/enums.ts +0 -32
- package/src/schemas/index.ts +0 -38
- package/src/schemas/shapes.ts +0 -267
- package/src/server.ts +0 -58
- package/src/tools/completeProject.ts +0 -21
- package/src/tools/completeTask.ts +0 -23
- package/src/tools/createFolder.ts +0 -20
- package/src/tools/createProject.ts +0 -20
- package/src/tools/createTag.ts +0 -20
- package/src/tools/createTask.ts +0 -20
- package/src/tools/deleteFolder.ts +0 -24
- package/src/tools/deleteProject.ts +0 -24
- package/src/tools/deleteTag.ts +0 -24
- package/src/tools/deleteTask.ts +0 -26
- package/src/tools/dropProject.ts +0 -21
- package/src/tools/dropTask.ts +0 -23
- package/src/tools/editFolder.ts +0 -19
- package/src/tools/editProject.ts +0 -20
- package/src/tools/editTag.ts +0 -20
- package/src/tools/editTask.ts +0 -20
- package/src/tools/getFolder.ts +0 -24
- package/src/tools/getProject.ts +0 -24
- package/src/tools/getTag.ts +0 -24
- package/src/tools/getTask.ts +0 -24
- package/src/tools/index.ts +0 -85
- package/src/tools/listFolders.ts +0 -32
- package/src/tools/listProjects.ts +0 -32
- package/src/tools/listTags.ts +0 -32
- package/src/tools/listTasks.ts +0 -56
- package/src/tools/moveProject.ts +0 -20
- package/src/tools/moveTask.ts +0 -20
- package/src/tools/resolveName.ts +0 -37
- package/test/integration/.gitkeep +0 -0
- package/test/integration/completeProject.int.test.ts +0 -25
- package/test/integration/completeTask.int.test.ts +0 -30
- package/test/integration/createFolder.int.test.ts +0 -50
- package/test/integration/createProject.int.test.ts +0 -49
- package/test/integration/createTag.int.test.ts +0 -52
- package/test/integration/createTask.int.test.ts +0 -55
- package/test/integration/deleteFolder.int.test.ts +0 -64
- package/test/integration/deleteProject.int.test.ts +0 -31
- package/test/integration/deleteTag.int.test.ts +0 -61
- package/test/integration/deleteTask.int.test.ts +0 -36
- package/test/integration/dropProject.int.test.ts +0 -24
- package/test/integration/dropTask.int.test.ts +0 -29
- package/test/integration/editFolder.int.test.ts +0 -43
- package/test/integration/editProject.int.test.ts +0 -39
- package/test/integration/editTag.int.test.ts +0 -43
- package/test/integration/editTask.int.test.ts +0 -56
- package/test/integration/fixtures.ts +0 -219
- package/test/integration/getTask.int.test.ts +0 -64
- package/test/integration/listFoldersFiltered.int.test.ts +0 -98
- package/test/integration/listProjects.int.test.ts +0 -73
- package/test/integration/listProjectsFiltered.int.test.ts +0 -96
- package/test/integration/listTagsFiltered.int.test.ts +0 -54
- package/test/integration/listTasksFiltered.int.test.ts +0 -141
- package/test/integration/moveProject.int.test.ts +0 -57
- package/test/integration/moveTask.int.test.ts +0 -61
- package/test/integration/plannedDate.int.test.ts +0 -72
- package/test/integration/preflight.ts +0 -60
- package/test/integration/resolveName.int.test.ts +0 -86
- package/test/integration/taskRecurrence.int.test.ts +0 -106
- package/test/unit/.gitkeep +0 -0
- package/test/unit/bridge.injection.test.ts +0 -66
- package/test/unit/resultProtocol.test.ts +0 -71
- package/test/unit/schemas.createFolder.test.ts +0 -38
- package/test/unit/schemas.createProject.test.ts +0 -115
- package/test/unit/schemas.createTask.test.ts +0 -87
- package/test/unit/schemas.editTag.test.ts +0 -64
- package/test/unit/schemas.folderTagFiltering.test.ts +0 -42
- package/test/unit/schemas.listProjects.test.ts +0 -44
- package/test/unit/schemas.moveOperations.test.ts +0 -60
- package/test/unit/schemas.recurrence.test.ts +0 -120
- package/test/unit/schemas.test.ts +0 -126
- package/test/unit/snippetLoader.test.ts +0 -56
- package/test/unit/tools.deleteTask.test.ts +0 -19
- package/test/unit/tools.listTasks.test.ts +0 -126
- package/tsconfig.json +0 -19
- package/vitest.config.ts +0 -8
- package/vitest.integration.config.ts +0 -18
package/src/tools/resolveName.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { runSnippet } from "../runtime/index.js";
|
|
3
|
-
import { EntityType, ResolveCandidate } from "../schemas/index.js";
|
|
4
|
-
|
|
5
|
-
export const resolveNameSchema = z.object({
|
|
6
|
-
type: EntityType.describe(
|
|
7
|
-
"The entity type to search: task, project, folder, tag, or perspective"
|
|
8
|
-
),
|
|
9
|
-
query: z.string().min(1).describe("Exact name to search for"),
|
|
10
|
-
scope: z
|
|
11
|
-
.string()
|
|
12
|
-
.optional()
|
|
13
|
-
.describe(
|
|
14
|
-
'Optional path prefix to narrow results, e.g. "Work ▸ Clients"'
|
|
15
|
-
),
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export type ResolveNameInput = z.infer<typeof resolveNameSchema>;
|
|
19
|
-
|
|
20
|
-
export async function resolveNameHandler(
|
|
21
|
-
input: ResolveNameInput
|
|
22
|
-
): Promise<z.infer<typeof ResolveCandidate>[]> {
|
|
23
|
-
const raw = await runSnippet("resolve_name", {
|
|
24
|
-
type: input.type,
|
|
25
|
-
query: input.query,
|
|
26
|
-
scope: input.scope ?? null,
|
|
27
|
-
});
|
|
28
|
-
return z.array(ResolveCandidate).parse(raw);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const resolveNameTool = {
|
|
32
|
-
name: "resolve_name",
|
|
33
|
-
description:
|
|
34
|
-
"Resolve an entity name to its stable ID(s). Returns ALL matches — never silently picks one. If multiple candidates are returned, ask the user or caller to disambiguate using the path field before proceeding with a write operation.",
|
|
35
|
-
inputSchema: resolveNameSchema,
|
|
36
|
-
handler: resolveNameHandler,
|
|
37
|
-
} as const;
|
|
File without changes
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { ProjectDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("complete_project (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let projectId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
projectId = await createTestProject(fixture.folderId, "CompleteProject Test Project");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await cleanupTestFolder(fixture.folderId);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("marks project complete and returns status done", async () => {
|
|
20
|
-
const raw = await runSnippet("complete_project", { id: projectId });
|
|
21
|
-
const project = ProjectDetail.parse(raw);
|
|
22
|
-
expect(project.status).toBe("done");
|
|
23
|
-
expect(project.completionDate).not.toBeNull();
|
|
24
|
-
});
|
|
25
|
-
});
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { TaskDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("complete_task (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let taskId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
const projectId = await createTestProject(fixture.folderId, "CompleteTask Test Project");
|
|
13
|
-
const taskRaw = await runSnippet("create_task", {
|
|
14
|
-
name: "Task to complete",
|
|
15
|
-
projectId,
|
|
16
|
-
});
|
|
17
|
-
taskId = TaskDetail.parse(taskRaw).id;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await cleanupTestFolder(fixture.folderId);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("marks task complete and returns status complete", async () => {
|
|
25
|
-
const raw = await runSnippet("complete_task", { id: taskId });
|
|
26
|
-
const task = TaskDetail.parse(raw);
|
|
27
|
-
expect(task.status).toBe("complete");
|
|
28
|
-
expect(task.completionDate).not.toBeNull();
|
|
29
|
-
});
|
|
30
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { cleanupTestFolder } from "./fixtures.js";
|
|
4
|
-
import { FolderDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("create_folder (integration)", () => {
|
|
7
|
-
const createdFolderIds: string[] = [];
|
|
8
|
-
|
|
9
|
-
afterAll(async () => {
|
|
10
|
-
for (const id of createdFolderIds) {
|
|
11
|
-
await cleanupTestFolder(id);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("creates a top-level folder and returns stable id", async () => {
|
|
16
|
-
const name = `__mcp_test_folder_${Date.now()}__`;
|
|
17
|
-
const raw = await runSnippet("create_folder", { name });
|
|
18
|
-
const folder = FolderDetail.parse(raw);
|
|
19
|
-
expect(folder.id).toBeTruthy();
|
|
20
|
-
expect(folder.name).toBe(name);
|
|
21
|
-
expect(folder.parentId).toBeNull();
|
|
22
|
-
expect(folder.path).toBe(name);
|
|
23
|
-
createdFolderIds.push(folder.id);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("creates a nested folder with correct path and parentId", async () => {
|
|
27
|
-
const parentName = `__mcp_test_parent_${Date.now()}__`;
|
|
28
|
-
const parentRaw = await runSnippet("create_folder", { name: parentName });
|
|
29
|
-
const parent = FolderDetail.parse(parentRaw);
|
|
30
|
-
createdFolderIds.push(parent.id);
|
|
31
|
-
|
|
32
|
-
const childRaw = await runSnippet("create_folder", {
|
|
33
|
-
name: "Child",
|
|
34
|
-
parentFolderId: parent.id,
|
|
35
|
-
});
|
|
36
|
-
const child = FolderDetail.parse(childRaw);
|
|
37
|
-
expect(child.parentId).toBe(parent.id);
|
|
38
|
-
expect(child.path).toContain(parentName);
|
|
39
|
-
expect(child.path).toContain("Child");
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("returns not-found error for invalid parentFolderId", async () => {
|
|
43
|
-
await expect(
|
|
44
|
-
runSnippet("create_folder", { name: "X", parentFolderId: "nonexistent-id-xyz" })
|
|
45
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
46
|
-
const err = e as Record<string, unknown>;
|
|
47
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { ProjectDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("create_project (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
|
|
9
|
-
beforeAll(async () => {
|
|
10
|
-
fixture = await createTestFolder();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
afterAll(async () => {
|
|
14
|
-
await cleanupTestFolder(fixture.folderId);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("creates a top-level project and returns stable id", async () => {
|
|
18
|
-
const name = `__mcp_test_proj_${Date.now()}__`;
|
|
19
|
-
const raw = await runSnippet("create_project", { name });
|
|
20
|
-
const project = ProjectDetail.parse(raw);
|
|
21
|
-
expect(project.id).toBeTruthy();
|
|
22
|
-
expect(project.name).toBe(name);
|
|
23
|
-
expect(project.folderPath).toBe("");
|
|
24
|
-
expect(project.type).toBe("parallel");
|
|
25
|
-
// Clean up the top-level project
|
|
26
|
-
await runSnippet("delete_project", { id: project.id });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("creates project inside a folder and sets folderPath", async () => {
|
|
30
|
-
const raw = await runSnippet("create_project", {
|
|
31
|
-
name: "Folder Project Test",
|
|
32
|
-
folderId: fixture.folderId,
|
|
33
|
-
});
|
|
34
|
-
const project = ProjectDetail.parse(raw);
|
|
35
|
-
expect(project.id).toBeTruthy();
|
|
36
|
-
expect(project.folderPath).toBeTruthy();
|
|
37
|
-
expect(project.type).toBe("parallel");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("creates sequential project and returns type sequential", async () => {
|
|
41
|
-
const raw = await runSnippet("create_project", {
|
|
42
|
-
name: "Sequential Project Test",
|
|
43
|
-
folderId: fixture.folderId,
|
|
44
|
-
type: "sequential",
|
|
45
|
-
});
|
|
46
|
-
const project = ProjectDetail.parse(raw);
|
|
47
|
-
expect(project.type).toBe("sequential");
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { deleteTestTag } from "./fixtures.js";
|
|
4
|
-
import { TagDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("create_tag (integration)", () => {
|
|
7
|
-
const createdTagIds: string[] = [];
|
|
8
|
-
|
|
9
|
-
afterAll(async () => {
|
|
10
|
-
for (const id of createdTagIds) {
|
|
11
|
-
await deleteTestTag(id);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("creates a top-level tag and returns stable id", async () => {
|
|
16
|
-
const name = `__mcp_test_tag_${Date.now()}__`;
|
|
17
|
-
const raw = await runSnippet("create_tag", { name });
|
|
18
|
-
const tag = TagDetail.parse(raw);
|
|
19
|
-
expect(tag.id).toBeTruthy();
|
|
20
|
-
expect(tag.name).toBe(name);
|
|
21
|
-
expect(tag.parentId).toBeNull();
|
|
22
|
-
expect(tag.path).toBe(name);
|
|
23
|
-
createdTagIds.push(tag.id);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("creates a child tag with correct path and parentId", async () => {
|
|
27
|
-
const parentName = `__mcp_test_parent_tag_${Date.now()}__`;
|
|
28
|
-
const parentRaw = await runSnippet("create_tag", { name: parentName });
|
|
29
|
-
const parent = TagDetail.parse(parentRaw);
|
|
30
|
-
createdTagIds.push(parent.id);
|
|
31
|
-
|
|
32
|
-
const childRaw = await runSnippet("create_tag", {
|
|
33
|
-
name: "Child",
|
|
34
|
-
parentTagId: parent.id,
|
|
35
|
-
});
|
|
36
|
-
const child = TagDetail.parse(childRaw);
|
|
37
|
-
expect(child.parentId).toBe(parent.id);
|
|
38
|
-
expect(child.path).toContain(parentName);
|
|
39
|
-
expect(child.path).toContain("Child");
|
|
40
|
-
// Parent should now list child
|
|
41
|
-
expect(parent.childTagIds).not.toContain(child.id); // stale parent object; child is real
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("returns not-found error for invalid parentTagId", async () => {
|
|
45
|
-
await expect(
|
|
46
|
-
runSnippet("create_tag", { name: "X", parentTagId: "nonexistent-id-xyz" })
|
|
47
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
48
|
-
const err = e as Record<string, unknown>;
|
|
49
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { TaskDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("create_task (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let projectId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
projectId = await createTestProject(fixture.folderId, "CreateTask Test Project");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await cleanupTestFolder(fixture.folderId);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("creates an inbox task and returns a stable id", async () => {
|
|
20
|
-
const raw = await runSnippet("create_task", { name: "Inbox task test" });
|
|
21
|
-
const task = TaskDetail.parse(raw);
|
|
22
|
-
expect(task.id).toBeTruthy();
|
|
23
|
-
expect(task.name).toBe("Inbox task test");
|
|
24
|
-
expect(task.containerType).toBe("inbox");
|
|
25
|
-
// Clean up inbox task
|
|
26
|
-
await runSnippet("delete_task", { id: task.id });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("creates a task in a project and sets containerId", async () => {
|
|
30
|
-
const raw = await runSnippet("create_task", {
|
|
31
|
-
name: "Project task test",
|
|
32
|
-
projectId,
|
|
33
|
-
});
|
|
34
|
-
const task = TaskDetail.parse(raw);
|
|
35
|
-
expect(task.id).toBeTruthy();
|
|
36
|
-
expect(task.name).toBe("Project task test");
|
|
37
|
-
expect(task.containerId).toBe(projectId);
|
|
38
|
-
expect(task.containerType).toBe("project");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("creates a subtask and sets parentTaskId", async () => {
|
|
42
|
-
const parentRaw = await runSnippet("create_task", {
|
|
43
|
-
name: "Parent task",
|
|
44
|
-
projectId,
|
|
45
|
-
});
|
|
46
|
-
const parent = TaskDetail.parse(parentRaw);
|
|
47
|
-
|
|
48
|
-
const childRaw = await runSnippet("create_task", {
|
|
49
|
-
name: "Child task",
|
|
50
|
-
parentTaskId: parent.id,
|
|
51
|
-
});
|
|
52
|
-
const child = TaskDetail.parse(childRaw);
|
|
53
|
-
expect(child.parentTaskId).toBe(parent.id);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { FolderDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("delete_folder (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
|
|
9
|
-
beforeAll(async () => {
|
|
10
|
-
fixture = await createTestFolder();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
afterAll(async () => {
|
|
14
|
-
// Best-effort cleanup — the folder may already be deleted by the test
|
|
15
|
-
try { await cleanupTestFolder(fixture.folderId); } catch (_) {}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("deletes folder with child project and get_folder returns not-found afterwards", async () => {
|
|
19
|
-
// Create a nested folder with a project inside the fixture
|
|
20
|
-
const childRaw = await runSnippet("create_folder", {
|
|
21
|
-
name: "ToDelete",
|
|
22
|
-
parentFolderId: fixture.folderId,
|
|
23
|
-
});
|
|
24
|
-
const childFolder = FolderDetail.parse(childRaw);
|
|
25
|
-
await createTestProject(childFolder.id, "Project inside folder");
|
|
26
|
-
|
|
27
|
-
// Delete the child folder
|
|
28
|
-
await runSnippet("delete_folder", { id: childFolder.id });
|
|
29
|
-
|
|
30
|
-
// get_folder should return not-found
|
|
31
|
-
await expect(
|
|
32
|
-
runSnippet("get_folder", { id: childFolder.id })
|
|
33
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
34
|
-
const err = e as Record<string, unknown>;
|
|
35
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("deletes an empty folder", async () => {
|
|
40
|
-
const raw = await runSnippet("create_folder", {
|
|
41
|
-
name: "EmptyToDelete",
|
|
42
|
-
parentFolderId: fixture.folderId,
|
|
43
|
-
});
|
|
44
|
-
const folder = FolderDetail.parse(raw);
|
|
45
|
-
|
|
46
|
-
await runSnippet("delete_folder", { id: folder.id });
|
|
47
|
-
|
|
48
|
-
await expect(
|
|
49
|
-
runSnippet("get_folder", { id: folder.id })
|
|
50
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
51
|
-
const err = e as Record<string, unknown>;
|
|
52
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("returns not-found error for invalid id", async () => {
|
|
57
|
-
await expect(
|
|
58
|
-
runSnippet("delete_folder", { id: "nonexistent-id-xyz" })
|
|
59
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
60
|
-
const err = e as Record<string, unknown>;
|
|
61
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { ProjectDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("delete_project (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let projectId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
projectId = await createTestProject(fixture.folderId, "DeleteProject Test Project");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await cleanupTestFolder(fixture.folderId);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("deletes the project and get_project returns not-found afterwards", async () => {
|
|
20
|
-
await runSnippet("delete_project", { id: projectId });
|
|
21
|
-
|
|
22
|
-
await expect(
|
|
23
|
-
runSnippet("get_project", { id: projectId })
|
|
24
|
-
).rejects.toSatisfy(
|
|
25
|
-
(e: unknown) => {
|
|
26
|
-
const err = e as Record<string, unknown>;
|
|
27
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestTag } from "./fixtures.js";
|
|
4
|
-
import { TagDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("delete_tag (integration)", () => {
|
|
7
|
-
let tagId: string;
|
|
8
|
-
let parentTagId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
tagId = await createTestTag(`__mcp_test_del_tag_${Date.now()}__`);
|
|
12
|
-
parentTagId = await createTestTag(`__mcp_test_del_parent_${Date.now()}__`);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("deletes a tag and get_tag returns not-found afterwards", async () => {
|
|
16
|
-
await runSnippet("delete_tag", { id: tagId });
|
|
17
|
-
|
|
18
|
-
await expect(
|
|
19
|
-
runSnippet("get_tag", { id: tagId })
|
|
20
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
21
|
-
const err = e as Record<string, unknown>;
|
|
22
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("deletes parent tag and child tags are also gone", async () => {
|
|
27
|
-
// Create a child tag under parentTagId
|
|
28
|
-
const childRaw = await runSnippet("create_tag", {
|
|
29
|
-
name: "ChildToDelete",
|
|
30
|
-
parentTagId,
|
|
31
|
-
});
|
|
32
|
-
const child = TagDetail.parse(childRaw);
|
|
33
|
-
|
|
34
|
-
// Delete the parent
|
|
35
|
-
await runSnippet("delete_tag", { id: parentTagId });
|
|
36
|
-
|
|
37
|
-
// Both parent and child should be gone
|
|
38
|
-
await expect(
|
|
39
|
-
runSnippet("get_tag", { id: parentTagId })
|
|
40
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
41
|
-
const err = e as Record<string, unknown>;
|
|
42
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
await expect(
|
|
46
|
-
runSnippet("get_tag", { id: child.id })
|
|
47
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
48
|
-
const err = e as Record<string, unknown>;
|
|
49
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("returns not-found error for invalid id", async () => {
|
|
54
|
-
await expect(
|
|
55
|
-
runSnippet("delete_tag", { id: "nonexistent-id-xyz" })
|
|
56
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
57
|
-
const err = e as Record<string, unknown>;
|
|
58
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { TaskDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("delete_task (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let taskId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
const projectId = await createTestProject(fixture.folderId, "DeleteTask Test Project");
|
|
13
|
-
const taskRaw = await runSnippet("create_task", {
|
|
14
|
-
name: "Task to delete",
|
|
15
|
-
projectId,
|
|
16
|
-
});
|
|
17
|
-
taskId = TaskDetail.parse(taskRaw).id;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await cleanupTestFolder(fixture.folderId);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("deletes the task and get_task returns not-found afterwards", async () => {
|
|
25
|
-
await runSnippet("delete_task", { id: taskId });
|
|
26
|
-
|
|
27
|
-
await expect(
|
|
28
|
-
runSnippet("get_task", { id: taskId })
|
|
29
|
-
).rejects.toSatisfy(
|
|
30
|
-
(e: unknown) => {
|
|
31
|
-
const err = e as Record<string, unknown>;
|
|
32
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
33
|
-
}
|
|
34
|
-
);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { ProjectDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("drop_project (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let projectId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
projectId = await createTestProject(fixture.folderId, "DropProject Test Project");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await cleanupTestFolder(fixture.folderId);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("marks project dropped and returns status dropped", async () => {
|
|
20
|
-
const raw = await runSnippet("drop_project", { id: projectId });
|
|
21
|
-
const project = ProjectDetail.parse(raw);
|
|
22
|
-
expect(project.status).toBe("dropped");
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { TaskDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("drop_task (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let taskId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
const projectId = await createTestProject(fixture.folderId, "DropTask Test Project");
|
|
13
|
-
const taskRaw = await runSnippet("create_task", {
|
|
14
|
-
name: "Task to drop",
|
|
15
|
-
projectId,
|
|
16
|
-
});
|
|
17
|
-
taskId = TaskDetail.parse(taskRaw).id;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await cleanupTestFolder(fixture.folderId);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("marks task dropped and returns status dropped", async () => {
|
|
25
|
-
const raw = await runSnippet("drop_task", { id: taskId });
|
|
26
|
-
const task = TaskDetail.parse(raw);
|
|
27
|
-
expect(task.status).toBe("dropped");
|
|
28
|
-
});
|
|
29
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { FolderDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("edit_folder (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let childFolderId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
// Create a child folder to rename
|
|
13
|
-
const raw = await runSnippet("create_folder", {
|
|
14
|
-
name: "Original Name",
|
|
15
|
-
parentFolderId: fixture.folderId,
|
|
16
|
-
});
|
|
17
|
-
const folder = FolderDetail.parse(raw);
|
|
18
|
-
childFolderId = folder.id;
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
afterAll(async () => {
|
|
22
|
-
await cleanupTestFolder(fixture.folderId);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("renames a folder and returns updated name and path", async () => {
|
|
26
|
-
const raw = await runSnippet("edit_folder", {
|
|
27
|
-
id: childFolderId,
|
|
28
|
-
name: "Renamed Folder",
|
|
29
|
-
});
|
|
30
|
-
const folder = FolderDetail.parse(raw);
|
|
31
|
-
expect(folder.name).toBe("Renamed Folder");
|
|
32
|
-
expect(folder.path).toContain("Renamed Folder");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("returns not-found error for invalid id", async () => {
|
|
36
|
-
await expect(
|
|
37
|
-
runSnippet("edit_folder", { id: "nonexistent-id-xyz", name: "X" })
|
|
38
|
-
).rejects.toSatisfy((e: unknown) => {
|
|
39
|
-
const err = e as Record<string, unknown>;
|
|
40
|
-
return err.name === "ExecutionError" && err.errorName === "NotFoundError";
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
-
import { runSnippet } from "../../src/runtime/bridge.js";
|
|
3
|
-
import { createTestFolder, cleanupTestFolder, createTestProject, type TestFixture } from "./fixtures.js";
|
|
4
|
-
import { ProjectDetail } from "../../src/schemas/index.js";
|
|
5
|
-
|
|
6
|
-
describe("edit_project (integration)", () => {
|
|
7
|
-
let fixture: TestFixture;
|
|
8
|
-
let projectId: string;
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
fixture = await createTestFolder();
|
|
12
|
-
projectId = await createTestProject(fixture.folderId, "EditProject Test Project");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await cleanupTestFolder(fixture.folderId);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("edits name only; other fields unchanged", async () => {
|
|
20
|
-
const raw = await runSnippet("edit_project", { id: projectId, name: "Updated name" });
|
|
21
|
-
const project = ProjectDetail.parse(raw);
|
|
22
|
-
expect(project.name).toBe("Updated name");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("sets status to onHold", async () => {
|
|
26
|
-
const raw = await runSnippet("edit_project", { id: projectId, status: "onHold" });
|
|
27
|
-
const project = ProjectDetail.parse(raw);
|
|
28
|
-
expect(project.status).toBe("onHold");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("sets review interval", async () => {
|
|
32
|
-
const raw = await runSnippet("edit_project", {
|
|
33
|
-
id: projectId,
|
|
34
|
-
reviewInterval: { steps: 2, unit: "weeks" },
|
|
35
|
-
});
|
|
36
|
-
const project = ProjectDetail.parse(raw);
|
|
37
|
-
expect(project.reviewInterval).toBeTruthy();
|
|
38
|
-
});
|
|
39
|
-
});
|