@cliangdev/flux-plugin 0.1.0-dev.588ae42 → 0.2.0-dev.4f12f3f

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.
@@ -16,10 +16,10 @@ Check if arguments were provided:
16
16
 
17
17
  ## Pre-checks
18
18
 
19
- 1. Call `get_project_context` to ensure Flux is initialized
20
- - If not initialized, tell user: "Run `/flux` first to initialize the project."
19
+ 1. If no ref provided, call `query_entities` with type=prd, status=APPROVED
20
+ - If error with `code: "PROJECT_NOT_INITIALIZED"`, tell user: "Run `/flux` first to initialize the project." and exit.
21
21
 
22
- 2. If no ref provided, call `query_entities` with type=prd, status=APPROVED
22
+ 2. If query successful but no approved PRDs found:
23
23
  - If no approved PRDs, tell user: "No approved PRDs found. Approve a PRD first or run `/flux:prd` to create one."
24
24
  - If multiple approved PRDs, use AskUserQuestion to let user select which one
25
25
 
package/commands/flux.md CHANGED
@@ -6,27 +6,78 @@ allowed-tools: mcp__plugin_flux_flux__*, AskUserQuestion, Read, Write
6
6
 
7
7
  # Flux Command
8
8
 
9
- You are the Flux orchestrator. Detect project state and guide the user to the appropriate next action.
9
+ You are the Flux orchestrator - the main entry point for all Flux operations. Your job is to:
10
+ 1. Detect project state and guide users to the appropriate next action
11
+ 2. Route to specialized commands based on user input
12
+ 3. Provide intelligent suggestions based on workflow state
13
+
14
+ ## Available Commands
15
+
16
+ | Command | Description |
17
+ |---------|-------------|
18
+ | `/flux` | Show project status and suggest next action |
19
+ | `/flux:prd` | Create or refine PRDs through guided interview |
20
+ | `/flux:breakdown` | Break approved PRD into dependency-ordered epics and tasks |
21
+ | `/flux:implement` | Implement tasks with TDD workflow using specialized coding agents |
22
+ | `/flux:linear` | Connect Flux project to Linear for issue tracking |
23
+
24
+ ## Subcommand Routing
25
+
26
+ When user provides arguments, route to the appropriate command:
27
+
28
+ | User Input | Action |
29
+ |------------|--------|
30
+ | `/flux` | Show status (see Main Flow) |
31
+ | `/flux version` | Call `get_version` and display result |
32
+ | `/flux status` | Call `render_status` with `{view: "full"}` |
33
+ | `/flux prd` or `/flux prd ...` | Delegate to `/flux:prd` with any additional args |
34
+ | `/flux breakdown` or `/flux breakdown ...` | Delegate to `/flux:breakdown` with any additional args |
35
+ | `/flux implement` or `/flux implement ...` | Delegate to `/flux:implement` with any additional args |
36
+ | `/flux linear` | Delegate to `/flux:linear` |
37
+ | `/flux help` | Show available commands and their purposes |
38
+
39
+ ## Available MCP Tools
40
+
41
+ These tools are available for programmatic access:
42
+
43
+ **Entity Management:**
44
+ - `create_prd`, `create_epic`, `create_task` - Create entities
45
+ - `update_entity`, `update_status`, `delete_entity` - Modify entities
46
+ - `get_entity`, `query_entities` - Retrieve entities
47
+
48
+ **Project:**
49
+ - `init_project` - Initialize new Flux project
50
+ - `get_stats` - Get entity counts by status
51
+ - `get_version` - Get plugin version
52
+ - `render_status` - Visual project status with progress bars
53
+
54
+ **Relationships:**
55
+ - `add_dependency`, `remove_dependency` - Task/epic dependencies
56
+ - `add_criteria`, `mark_criteria_met` - Acceptance criteria
57
+
58
+ **Integration:**
59
+ - `configure_linear` - Connect to Linear (interactive mode supported)
10
60
 
11
- ## Subcommands
61
+ ## Main Flow
12
62
 
13
- - `/flux version` - Show plugin version (call `get_version`)
14
- - `/flux linear` - Connect to Linear (delegate to `/flux:linear`)
63
+ ### Step 0: Check for Subcommands
15
64
 
16
- ## Main Flow
65
+ First, check if the user provided arguments (e.g., `/flux prd`, `/flux implement FP-T1`).
66
+ If so, route to the appropriate command as described in Subcommand Routing above.
17
67
 
18
- ### Step 1: Get Project Context
68
+ ### Step 1: Check Project State
19
69
 
20
- Call `get_project_context` to check project state.
70
+ If no subcommand, call `render_status` with `{view: "summary"}` to show current state.
21
71
 
22
- ### Step 2: Route Based on State
72
+ ### Step 2: Route Based on Response
23
73
 
24
- **If `initialized: false`:**
74
+ **If error with `code: "PROJECT_NOT_INITIALIZED"`:**
25
75
  → Guide through initialization (see Initialization Flow below)
26
76
 
27
- **If `initialized: true`:**
28
- Call `render_status` with `{view: "summary"}` to show current state
29
- Determine next action based on workflow state (see Workflow States)
77
+ **If success:**
78
+ Display the rendered status
79
+ Analyze workflow state and suggest the most appropriate next action (see Workflow States)
80
+ → If multiple actions are possible, use AskUserQuestion to let user choose
30
81
 
31
82
  ## Initialization Flow
32
83
 
@@ -148,9 +199,38 @@ When determining actions:
148
199
  | 50-80% | Suggest action, wait for confirmation |
149
200
  | < 50% | Ask clarifying question |
150
201
 
202
+ ## Help Output
203
+
204
+ When user runs `/flux help`, display:
205
+
206
+ ```
207
+ Flux - AI-first workflow orchestration
208
+
209
+ Commands:
210
+ /flux Show project status and next action
211
+ /flux:prd Create or refine PRDs
212
+ /flux:breakdown Break PRD into epics and tasks
213
+ /flux:implement Implement tasks with TDD
214
+ /flux:linear Connect to Linear
215
+
216
+ Shortcuts:
217
+ /flux prd Same as /flux:prd
218
+ /flux breakdown Same as /flux:breakdown
219
+ /flux implement Same as /flux:implement
220
+ /flux status Show detailed project status
221
+ /flux version Show plugin version
222
+
223
+ Workflow:
224
+ 1. /flux Initialize project (first time)
225
+ 2. /flux:prd Create your first PRD
226
+ 3. /flux:breakdown Break PRD into tasks
227
+ 4. /flux:implement Start coding with TDD
228
+ ```
229
+
151
230
  ## Guidelines
152
231
 
153
232
  - Use `AskUserQuestion` tool for all user choices during initialization
154
233
  - Be concise - show status and one clear next action
155
234
  - Use `render_status` for visual project overview
156
235
  - Apply confidence-based autonomy for decisions
236
+ - When user input matches a subcommand pattern, delegate immediately without calling render_status first
@@ -53,8 +53,7 @@ The orchestrator resolves all refs to tasks, builds a dependency-ordered queue,
53
53
 
54
54
  ## Pre-checks
55
55
 
56
- 1. Call `get_project_context` to ensure Flux is initialized
57
- 2. Parse arguments and resolve to tasks:
56
+ 1. Parse arguments and resolve to tasks (if any tool returns `PROJECT_NOT_INITIALIZED` error, tell user: "Run `/flux` first to initialize the project." and exit):
58
57
  - No args: Query for next PENDING task with no blockers
59
58
  - PRD ref(s): Expand to all epics → all tasks
60
59
  - Epic ref(s): Expand to all tasks
@@ -21,13 +21,14 @@ The `configure_linear` tool supports progressive discovery:
21
21
 
22
22
  ## Flow
23
23
 
24
- ### Step 1: Verify Project
24
+ ### Step 1: Verify Project & Fetch Teams
25
25
 
26
- Call `get_project_context`.
26
+ Call `configure_linear` with `{interactive: true}`.
27
27
 
28
- - If `initialized: false` → Tell user to run `/flux` first, then exit.
29
- - If `adapter.type === "linear"` and config exists Already configured, show info and exit.
30
- - OtherwiseContinue to Step 2.
28
+ - If error with `code: "PROJECT_NOT_INITIALIZED"` → Tell user to run `/flux` first, then exit.
29
+ - If error about Linear API keyShow instructions (see Step 2 error handling).
30
+ - If success with `step: "already_configured"` Already configured, show info and exit.
31
+ - Otherwise → Continue with team selection (response contains teams list).
31
32
 
32
33
  ### Step 2: Fetch Teams
33
34
 
package/commands/prd.md CHANGED
@@ -20,8 +20,8 @@ Check if arguments were provided:
20
20
 
21
21
  ### Pre-check
22
22
 
23
- 1. Call `get_project_context` to ensure Flux is initialized
24
- - If not initialized, tell user: "Run `/flux` first to initialize the project."
23
+ 1. Call `query_entities` with `type: "prd"` to verify project is initialized
24
+ - If error with `code: "PROJECT_NOT_INITIALIZED"`, tell user: "Run `/flux` first to initialize the project." and exit.
25
25
 
26
26
  2. Call `get_interview` to check for any in-progress interview
27
27
  - If exists, ask: "You have an unfinished interview. Resume it or start fresh?"
@@ -96,7 +96,7 @@ Use AskUserQuestion to confirm:
96
96
 
97
97
  ## After Interview Complete
98
98
 
99
- The `get_project_context` call from Pre-check returns the adapter type. Use this to determine storage behavior.
99
+ The `create_prd` response includes project context. Use it to determine storage behavior, or call `get_entity` on the created PRD to check the adapter type.
100
100
 
101
101
  ### For Local Adapter (`adapter.type === "local"`):
102
102
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliangdev/flux-plugin",
3
- "version": "0.1.0-dev.588ae42",
3
+ "version": "0.2.0-dev.4f12f3f",
4
4
  "description": "Claude Code plugin for AI-first workflow orchestration with MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",
@@ -11,11 +11,11 @@ This skill is automatically active when working in a Flux project. It provides c
11
11
  ## Available MCP Tools
12
12
 
13
13
  ### Query Tools
14
- - `get_project_context` - Check if project initialized, get name/vision/adapter type
15
14
  - `get_stats` - Get PRD/epic/task counts by status
16
15
  - `get_entity` - Fetch entity by ref with optional includes (criteria, tasks, dependencies)
17
16
  - `query_entities` - Search entities by type, status, parent ref
18
17
  - `render_status` - Get formatted project status with progress bars
18
+ - `get_version` - Get Flux plugin version
19
19
 
20
20
  ### Mutation Tools
21
21
  - `init_project` - Initialize new .flux/ directory with project.json and database
@@ -107,7 +107,7 @@ Format: `{PREFIX}-{TYPE}{NUMBER}`
107
107
 
108
108
  ## Best Practices
109
109
 
110
- 1. **Check context first** - Call `get_project_context` before actions
110
+ 1. **Handle PROJECT_NOT_INITIALIZED** - If any tool returns this error, direct user to run `/flux` to initialize the project
111
111
  2. **Use refs, not IDs** - Tools accept `MSA-E1` format
112
112
  3. **Use render_status** - For visual project overview
113
113
  4. **Validate transitions** - `update_status` enforces valid transitions
@@ -219,7 +219,7 @@ erDiagram
219
219
 
220
220
  ## Workflow
221
221
 
222
- Check adapter type via `get_project_context` to determine storage behavior.
222
+ After creating a PRD, the response includes adapter information. Use this to determine storage behavior.
223
223
 
224
224
  ### Local Adapter (`adapter.type === "local"`)
225
225
 
@@ -11,7 +11,6 @@ import {
11
11
  createTaskTool,
12
12
  deleteEntityTool,
13
13
  getEntityTool,
14
- getProjectContextTool,
15
14
  getStatsTool,
16
15
  getVersionTool,
17
16
  initProjectTool,
@@ -47,7 +46,6 @@ const tools: ToolDefinition[] = [
47
46
  // Query tools
48
47
  getEntityTool,
49
48
  queryEntitiesTool,
50
- getProjectContextTool,
51
49
  initProjectTool,
52
50
  getStatsTool,
53
51
  getVersionTool,
@@ -10,7 +10,12 @@ process.env.FLUX_PROJECT_ROOT = TEST_DIR;
10
10
  import { z } from "zod";
11
11
  import { config } from "../../config.js";
12
12
  import { closeDb, initDb } from "../../db/index.js";
13
- import { createError, registerTools, type ToolDefinition } from "../index.js";
13
+ import {
14
+ createError,
15
+ createProjectNotInitializedError,
16
+ registerTools,
17
+ type ToolDefinition,
18
+ } from "../index.js";
14
19
 
15
20
  describe("MCP Interface", () => {
16
21
  beforeEach(() => {
@@ -44,6 +49,42 @@ describe("MCP Interface", () => {
44
49
  });
45
50
  });
46
51
 
52
+ describe("createProjectNotInitializedError", () => {
53
+ test("creates error with setup instructions", () => {
54
+ const error = createProjectNotInitializedError("/test/cwd", "/test/root");
55
+
56
+ expect(error.error).toBe(true);
57
+ expect(error.code).toBe("PROJECT_NOT_INITIALIZED");
58
+ expect(error.message).toContain("/test/cwd");
59
+ expect(error.message).toContain("/test/root");
60
+ expect(error.setup.instructions).toBeDefined();
61
+ expect(error.setup.options).toHaveLength(2);
62
+ });
63
+
64
+ test("includes command option for interactive setup", () => {
65
+ const error = createProjectNotInitializedError("/cwd", "/root");
66
+ const commandOption = error.setup.options.find(
67
+ (o) => o.method === "command",
68
+ );
69
+
70
+ expect(commandOption).toBeDefined();
71
+ expect(commandOption?.name).toBe("/flux");
72
+ expect(commandOption?.description).toContain("Interactive");
73
+ });
74
+
75
+ test("includes tool option with required params", () => {
76
+ const error = createProjectNotInitializedError("/cwd", "/root");
77
+ const toolOption = error.setup.options.find((o) => o.method === "tool");
78
+
79
+ expect(toolOption).toBeDefined();
80
+ expect(toolOption?.name).toBe("init_project");
81
+ expect(toolOption?.params).toBeDefined();
82
+ expect(toolOption?.params?.name).toBeDefined();
83
+ expect(toolOption?.params?.vision).toBeDefined();
84
+ expect(toolOption?.params?.adapter).toBeDefined();
85
+ });
86
+ });
87
+
47
88
  describe("registerTools", () => {
48
89
  test("sets up list tools handler", () => {
49
90
  const handlers: Record<string, Function> = {};
@@ -287,7 +328,7 @@ describe("Project Validation", () => {
287
328
  }
288
329
  });
289
330
 
290
- test("returns PROJECT_NOT_FOUND for tools requiring project", async () => {
331
+ test("returns PROJECT_NOT_INITIALIZED with setup instructions for tools requiring project", async () => {
291
332
  const handlers: Record<string, Function> = {};
292
333
  const mockServer = {
293
334
  setRequestHandler: mock((schema: any, handler: Function) => {
@@ -317,7 +358,11 @@ describe("Project Validation", () => {
317
358
  expect(result.isError).toBe(true);
318
359
  const parsedError = JSON.parse(result.content[0].text);
319
360
  expect(parsedError.error).toBe(true);
320
- expect(parsedError.code).toBe("PROJECT_NOT_FOUND");
361
+ expect(parsedError.code).toBe("PROJECT_NOT_INITIALIZED");
362
+ expect(parsedError.setup).toBeDefined();
363
+ expect(parsedError.setup.instructions).toBeDefined();
364
+ expect(parsedError.setup.options).toBeDefined();
365
+ expect(parsedError.setup.options.length).toBe(2);
321
366
  });
322
367
 
323
368
  test("allows init_project without existing project", async () => {
@@ -353,7 +398,7 @@ describe("Project Validation", () => {
353
398
  expect(handlerMock).toHaveBeenCalled();
354
399
  });
355
400
 
356
- test("allows get_project_context without existing project", async () => {
401
+ test("allows get_version without existing project", async () => {
357
402
  const handlers: Record<string, Function> = {};
358
403
  const mockServer = {
359
404
  setRequestHandler: mock((schema: any, handler: Function) => {
@@ -363,11 +408,11 @@ describe("Project Validation", () => {
363
408
  }),
364
409
  };
365
410
 
366
- const handlerMock = mock(async () => ({ initialized: false }));
411
+ const handlerMock = mock(async () => ({ version: "1.0.0" }));
367
412
 
368
413
  const testTool: ToolDefinition = {
369
- name: "get_project_context",
370
- description: "Get project context",
414
+ name: "get_version",
415
+ description: "Get version",
371
416
  inputSchema: z.object({}),
372
417
  handler: handlerMock,
373
418
  };
@@ -377,7 +422,7 @@ describe("Project Validation", () => {
377
422
  const callHandler = handlers.call;
378
423
  const result = await callHandler({
379
424
  params: {
380
- name: "get_project_context",
425
+ name: "get_version",
381
426
  arguments: {},
382
427
  },
383
428
  });
@@ -385,4 +430,49 @@ describe("Project Validation", () => {
385
430
  expect(result.isError).toBeUndefined();
386
431
  expect(handlerMock).toHaveBeenCalled();
387
432
  });
433
+
434
+ test("setup options have correct structure", async () => {
435
+ const handlers: Record<string, Function> = {};
436
+ const mockServer = {
437
+ setRequestHandler: mock((schema: any, handler: Function) => {
438
+ if (schema.shape?.method?.value === "tools/call") {
439
+ handlers.call = handler;
440
+ }
441
+ }),
442
+ };
443
+
444
+ const testTool: ToolDefinition = {
445
+ name: "query_entities",
446
+ description: "Query entities",
447
+ inputSchema: z.object({ type: z.string() }),
448
+ handler: async () => ({ items: [] }),
449
+ };
450
+
451
+ registerTools(mockServer as any, [testTool]);
452
+
453
+ const callHandler = handlers.call;
454
+ const result = await callHandler({
455
+ params: {
456
+ name: "query_entities",
457
+ arguments: { type: "prd" },
458
+ },
459
+ });
460
+
461
+ expect(result.isError).toBe(true);
462
+ const parsedError = JSON.parse(result.content[0].text);
463
+
464
+ const commandOption = parsedError.setup.options.find(
465
+ (o: any) => o.method === "command",
466
+ );
467
+ expect(commandOption.name).toBe("/flux");
468
+ expect(commandOption.description).toBeTruthy();
469
+
470
+ const toolOption = parsedError.setup.options.find(
471
+ (o: any) => o.method === "tool",
472
+ );
473
+ expect(toolOption.name).toBe("init_project");
474
+ expect(toolOption.params.name).toBeTruthy();
475
+ expect(toolOption.params.vision).toBeTruthy();
476
+ expect(toolOption.params.adapter).toBeTruthy();
477
+ });
388
478
  });
@@ -16,7 +16,6 @@ import { createPrdTool } from "../create-prd.js";
16
16
  import { createTaskTool } from "../create-task.js";
17
17
  import { addDependencyTool } from "../dependencies.js";
18
18
  import { getEntityTool } from "../get-entity.js";
19
- import { getProjectContextTool } from "../get-project-context.js";
20
19
  import { getStatsTool } from "../get-stats.js";
21
20
  import { initProjectTool } from "../init-project.js";
22
21
  import { queryEntitiesTool } from "../query-entities.js";
@@ -242,24 +241,6 @@ describe("Query MCP Tools", () => {
242
241
  });
243
242
  });
244
243
 
245
- describe("get_project_context", () => {
246
- test("returns project context when initialized", async () => {
247
- const result = (await getProjectContextTool.handler({})) as any;
248
-
249
- expect(result.initialized).toBe(true);
250
- expect(result.name).toBe("test-project");
251
- expect(result.ref_prefix).toBe("TEST");
252
- });
253
-
254
- test("returns initialized false when no project", async () => {
255
- // Remove the project.json
256
- rmSync(join(FLUX_DIR, "project.json"));
257
-
258
- const result = (await getProjectContextTool.handler({})) as any;
259
- expect(result.initialized).toBe(false);
260
- });
261
- });
262
-
263
244
  describe("get_stats", () => {
264
245
  test("returns zeroes for empty project", async () => {
265
246
  const result = (await getStatsTool.handler({})) as any;
@@ -7,11 +7,7 @@ import { z } from "zod";
7
7
  import { config } from "../config.js";
8
8
  import { logger } from "../utils/logger.js";
9
9
 
10
- const TOOLS_WITHOUT_PROJECT = [
11
- "init_project",
12
- "get_project_context",
13
- "get_version",
14
- ];
10
+ const TOOLS_WITHOUT_PROJECT = ["init_project", "get_version"];
15
11
 
16
12
  export interface ToolDefinition {
17
13
  name: string;
@@ -26,10 +22,56 @@ export interface ToolError {
26
22
  code: string;
27
23
  }
28
24
 
25
+ export interface ProjectNotInitializedError extends ToolError {
26
+ code: "PROJECT_NOT_INITIALIZED";
27
+ setup: {
28
+ instructions: string;
29
+ options: Array<{
30
+ method: "command" | "tool";
31
+ name: string;
32
+ description: string;
33
+ params?: Record<string, string>;
34
+ }>;
35
+ };
36
+ }
37
+
29
38
  export function createError(message: string, code: string): ToolError {
30
39
  return { error: true, message, code };
31
40
  }
32
41
 
42
+ export function createProjectNotInitializedError(
43
+ cwd: string,
44
+ projectRoot: string,
45
+ ): ProjectNotInitializedError {
46
+ return {
47
+ error: true,
48
+ code: "PROJECT_NOT_INITIALIZED",
49
+ message: `No Flux project found. Current directory: ${cwd}, resolved project root: ${projectRoot}`,
50
+ setup: {
51
+ instructions:
52
+ "Initialize a Flux project before using Flux tools. Use one of the following options:",
53
+ options: [
54
+ {
55
+ method: "command",
56
+ name: "/flux",
57
+ description:
58
+ "Interactive setup with guided prompts (recommended for first-time setup)",
59
+ },
60
+ {
61
+ method: "tool",
62
+ name: "init_project",
63
+ description: "Direct initialization via MCP tool",
64
+ params: {
65
+ name: "Project name (required)",
66
+ vision: "Brief project description (required)",
67
+ adapter: "local | linear (default: local)",
68
+ },
69
+ },
70
+ ],
71
+ },
72
+ };
73
+ }
74
+
33
75
  export function registerTools(server: Server, tools: ToolDefinition[]) {
34
76
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
35
77
  tools: tools.map((t) => ({
@@ -60,13 +102,16 @@ export function registerTools(server: Server, tools: ToolDefinition[]) {
60
102
  }
61
103
 
62
104
  if (!TOOLS_WITHOUT_PROJECT.includes(toolName) && !config.projectExists) {
63
- const message = `No Flux project found. Run init_project first or ensure you're in a directory with a .flux folder (or a subdirectory of one). Current directory: ${process.cwd()}, resolved project root: ${config.projectRoot}`;
64
- logger.error(message);
105
+ const error = createProjectNotInitializedError(
106
+ process.cwd(),
107
+ config.projectRoot,
108
+ );
109
+ logger.error(error.message);
65
110
  return {
66
111
  content: [
67
112
  {
68
113
  type: "text",
69
- text: JSON.stringify(createError(message, "PROJECT_NOT_FOUND")),
114
+ text: JSON.stringify(error, null, 2),
70
115
  },
71
116
  ],
72
117
  isError: true,
@@ -104,7 +149,6 @@ export { deleteEntityTool } from "./delete-entity.js";
104
149
  export { addDependencyTool, removeDependencyTool } from "./dependencies.js";
105
150
  export { getEntityTool } from "./get-entity.js";
106
151
  export { getLinearUrlTool } from "./get-linear-url.js";
107
- export { getProjectContextTool } from "./get-project-context.js";
108
152
  export { getStatsTool } from "./get-stats.js";
109
153
  export { getVersionTool } from "./get-version.js";
110
154
  export { initProjectTool } from "./init-project.js";
@@ -102,7 +102,7 @@ async function handler(input: unknown) {
102
102
  export const initProjectTool: ToolDefinition = {
103
103
  name: "init_project",
104
104
  description:
105
- "Initialize a new Flux project. Required: name, vision. Optional: adapter (local|specflux|linear|notion, default 'local'). Creates .flux/ directory with project.json and SQLite database. Returns {success, project, message}. Fails if .flux/ already exists. Run get_project_context first to check.",
105
+ "Initialize a new Flux project. Required: name, vision. Optional: adapter (local|specflux|linear|notion, default 'local'). Creates .flux/ directory with project.json and SQLite database. Returns {success, project, message}. Fails if .flux/ already exists.",
106
106
  inputSchema,
107
107
  handler,
108
108
  };
@@ -1,33 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { z } from "zod";
3
- import { config } from "../config.js";
4
- import type { ToolDefinition } from "./index.js";
5
-
6
- const inputSchema = z.object({});
7
-
8
- async function handler(_input: unknown) {
9
- const projectJsonPath = config.projectJsonPath;
10
-
11
- if (!existsSync(projectJsonPath)) {
12
- return { initialized: false };
13
- }
14
-
15
- try {
16
- const content = readFileSync(projectJsonPath, "utf-8");
17
- const project = JSON.parse(content);
18
- return { initialized: true, ...project };
19
- } catch (_err) {
20
- return {
21
- initialized: false,
22
- error: "Failed to read project.json",
23
- };
24
- }
25
- }
26
-
27
- export const getProjectContextTool: ToolDefinition = {
28
- name: "get_project_context",
29
- description:
30
- "Get project context from .flux/project.json. No parameters required. Returns {initialized: boolean, name?, vision?, ref_prefix?, adapter?: {type: 'local'|'specflux'|'linear'|'notion'}, created_at?}. Use this to check if a Flux project exists before other operations.",
31
- inputSchema,
32
- handler,
33
- };