@filmwhisper/cli 0.1.0

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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/dist/__tests__/cli.test.d.ts +2 -0
  3. package/dist/__tests__/cli.test.d.ts.map +1 -0
  4. package/dist/__tests__/cli.test.js +38 -0
  5. package/dist/__tests__/cli.test.js.map +1 -0
  6. package/dist/__tests__/migrate.test.d.ts +2 -0
  7. package/dist/__tests__/migrate.test.d.ts.map +1 -0
  8. package/dist/__tests__/migrate.test.js +449 -0
  9. package/dist/__tests__/migrate.test.js.map +1 -0
  10. package/dist/commands/init.d.ts +4 -0
  11. package/dist/commands/init.d.ts.map +1 -0
  12. package/dist/commands/init.js +21 -0
  13. package/dist/commands/init.js.map +1 -0
  14. package/dist/commands/migrate.d.ts +19 -0
  15. package/dist/commands/migrate.d.ts.map +1 -0
  16. package/dist/commands/migrate.js +443 -0
  17. package/dist/commands/migrate.js.map +1 -0
  18. package/dist/commands/process.d.ts +4 -0
  19. package/dist/commands/process.d.ts.map +1 -0
  20. package/dist/commands/process.js +21 -0
  21. package/dist/commands/process.js.map +1 -0
  22. package/dist/commands/search.d.ts +4 -0
  23. package/dist/commands/search.d.ts.map +1 -0
  24. package/dist/commands/search.js +24 -0
  25. package/dist/commands/search.js.map +1 -0
  26. package/dist/commands/status.d.ts +2 -0
  27. package/dist/commands/status.d.ts.map +1 -0
  28. package/dist/commands/status.js +21 -0
  29. package/dist/commands/status.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +36 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/mcp-client.d.ts +11 -0
  35. package/dist/mcp-client.d.ts.map +1 -0
  36. package/dist/mcp-client.js +29 -0
  37. package/dist/mcp-client.js.map +1 -0
  38. package/package.json +29 -0
  39. package/src/__tests__/cli.test.ts +47 -0
  40. package/src/__tests__/migrate.test.ts +600 -0
  41. package/src/commands/init.ts +19 -0
  42. package/src/commands/migrate.ts +734 -0
  43. package/src/commands/process.ts +19 -0
  44. package/src/commands/search.ts +22 -0
  45. package/src/commands/status.ts +20 -0
  46. package/src/index.ts +44 -0
  47. package/src/mcp-client.ts +38 -0
  48. package/tsconfig.json +13 -0
  49. package/tsconfig.tsbuildinfo +1 -0
  50. package/vitest.config.ts +7 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * In-process MCP client — connects to a FilmWhisper server via InMemoryTransport.
3
+ * Avoids subprocess overhead for CLI usage in the same monorepo.
4
+ */
5
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
7
+ // Use relative paths to avoid subpath export resolution issues in TS project references
8
+ import { createServer } from "../../../packages/mcp-server/src/server.js";
9
+ import { ProjectStore } from "../../../packages/mcp-server/src/storage/project-store.js";
10
+ export async function createMcpClient() {
11
+ const projectStore = new ProjectStore();
12
+ const projects = new Map();
13
+ const server = createServer({ projectStore, projects });
14
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
15
+ await server.connect(serverTransport);
16
+ const client = new Client({ name: "fw-cli", version: "0.1.0" });
17
+ await client.connect(clientTransport);
18
+ return {
19
+ async callTool(name, args) {
20
+ const result = await client.callTool({ name, arguments: args });
21
+ return result;
22
+ },
23
+ async close() {
24
+ await client.close();
25
+ await server.close();
26
+ },
27
+ };
28
+ }
29
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,wFAAwF;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,2DAA2D,CAAC;AAOzF,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;IAE3B,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;IAEhF,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAEtC,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI;YACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,OAAO,MAA4D,CAAC;QACtE,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@filmwhisper/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI wrapper for FilmWhisper MCP server",
5
+ "type": "module",
6
+ "bin": {
7
+ "fw": "./dist/index.js"
8
+ },
9
+ "dependencies": {
10
+ "@modelcontextprotocol/sdk": "^1.12.0",
11
+ "better-sqlite3": "^12.8.0",
12
+ "cac": "^6.7.14",
13
+ "@filmwhisper/shared-types": "0.1.0",
14
+ "@filmwhisper/mcp-server": "0.1.0"
15
+ },
16
+ "devDependencies": {
17
+ "@types/better-sqlite3": "^7.6.13",
18
+ "@types/node": "^25.5.0",
19
+ "typescript": "^5.7.0",
20
+ "vitest": "^3.2.4"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "test": "vitest run --passWithNoTests",
25
+ "test:watch": "vitest",
26
+ "type-check": "tsc --noEmit",
27
+ "lint": "echo 'no lint configured yet'"
28
+ }
29
+ }
@@ -0,0 +1,47 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+
3
+ describe("CLI argument parsing", () => {
4
+ beforeEach(() => {
5
+ vi.spyOn(process, "exit").mockImplementation(((code?: number) => {
6
+ throw new Error(`process.exit(${code})`);
7
+ }) as never);
8
+ vi.spyOn(console, "error").mockImplementation(() => {});
9
+ });
10
+
11
+ afterEach(() => {
12
+ vi.restoreAllMocks();
13
+ });
14
+
15
+ describe("migrate command", () => {
16
+ it("requires --source option", async () => {
17
+ const { migrateCommand } = await import("../commands/migrate.js");
18
+ await expect(migrateCommand({})).rejects.toThrow("process.exit(1)");
19
+ expect(console.error).toHaveBeenCalledWith("Error: --source <path> is required");
20
+ });
21
+
22
+ it("errors when source database does not exist", async () => {
23
+ const { migrateCommand } = await import("../commands/migrate.js");
24
+ await expect(
25
+ migrateCommand({ source: "/nonexistent/path/v1.sqlite" }),
26
+ ).rejects.toThrow("process.exit(1)");
27
+ expect(console.error).toHaveBeenCalledWith(
28
+ expect.stringContaining("Source database not found"),
29
+ );
30
+ });
31
+ });
32
+
33
+ describe("status command", () => {
34
+ it("requires project_id argument", async () => {
35
+ const { statusCommand } = await import("../commands/status.js");
36
+ await expect(statusCommand(undefined)).rejects.toThrow("process.exit(1)");
37
+ expect(console.error).toHaveBeenCalledWith("Error: project_id is required");
38
+ });
39
+ });
40
+
41
+ describe("CLI version", () => {
42
+ it("package version matches CLI version constant", async () => {
43
+ const pkg = await import("../../package.json", { assert: { type: "json" } });
44
+ expect(pkg.default.version).toBe("0.1.0");
45
+ });
46
+ });
47
+ });