@projitive/mcp 1.0.1 → 1.0.3

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 (66) hide show
  1. package/README.md +44 -20
  2. package/output/helpers/artifacts/artifacts.js +10 -0
  3. package/output/helpers/artifacts/artifacts.test.js +18 -0
  4. package/output/helpers/artifacts/index.js +1 -0
  5. package/output/helpers/index.js +3 -0
  6. package/output/helpers/linter/codes.js +25 -0
  7. package/output/helpers/linter/index.js +2 -0
  8. package/output/helpers/linter/linter.js +6 -0
  9. package/output/helpers/linter/linter.test.js +16 -0
  10. package/output/helpers/response/index.js +1 -0
  11. package/output/helpers/response/response.js +73 -0
  12. package/output/helpers/response/response.test.js +50 -0
  13. package/output/hooks.js +1 -14
  14. package/output/hooks.test.js +7 -18
  15. package/output/index.js +23 -5
  16. package/output/package.json +36 -0
  17. package/output/projitive.js +158 -124
  18. package/output/projitive.test.js +1 -0
  19. package/output/rendering-input-guard.test.js +20 -0
  20. package/output/roadmap.js +106 -80
  21. package/output/roadmap.test.js +11 -0
  22. package/output/smoke-reports/2026-02-18T13-18-19-740Z/projectContext.md +48 -0
  23. package/output/smoke-reports/2026-02-18T13-18-19-740Z/projectInit.md +40 -0
  24. package/output/smoke-reports/2026-02-18T13-18-19-740Z/projectLocate.md +22 -0
  25. package/output/smoke-reports/2026-02-18T13-18-19-740Z/projectNext.md +31 -0
  26. package/output/smoke-reports/2026-02-18T13-18-19-740Z/projectScan.md +28 -0
  27. package/output/smoke-reports/2026-02-18T13-18-19-740Z/roadmapContext.md +33 -0
  28. package/output/smoke-reports/2026-02-18T13-18-19-740Z/roadmapList.md +25 -0
  29. package/output/smoke-reports/2026-02-18T13-18-19-740Z/summary.json +90 -0
  30. package/output/smoke-reports/2026-02-18T13-18-19-740Z/summary.md +17 -0
  31. package/output/smoke-reports/2026-02-18T13-18-19-740Z/taskContext.md +47 -0
  32. package/output/smoke-reports/2026-02-18T13-18-19-740Z/taskList.md +27 -0
  33. package/output/smoke-reports/2026-02-18T13-18-19-740Z/taskNext.md +64 -0
  34. package/output/source/designs.js +38 -0
  35. package/output/source/helpers/artifacts/artifacts.js +10 -0
  36. package/output/source/helpers/artifacts/artifacts.test.js +18 -0
  37. package/output/source/helpers/artifacts/index.js +1 -0
  38. package/output/source/helpers/catch/catch.js +48 -0
  39. package/output/source/helpers/catch/catch.test.js +43 -0
  40. package/output/source/helpers/catch/index.js +1 -0
  41. package/output/source/helpers/files/files.js +62 -0
  42. package/output/source/helpers/files/files.test.js +32 -0
  43. package/output/source/helpers/files/index.js +1 -0
  44. package/output/source/helpers/index.js +6 -0
  45. package/output/source/helpers/linter/codes.js +25 -0
  46. package/output/source/helpers/linter/index.js +2 -0
  47. package/output/source/helpers/linter/linter.js +6 -0
  48. package/output/source/helpers/linter/linter.test.js +16 -0
  49. package/output/source/helpers/markdown/index.js +1 -0
  50. package/output/source/helpers/markdown/markdown.js +33 -0
  51. package/output/source/helpers/markdown/markdown.test.js +36 -0
  52. package/output/source/helpers/response/index.js +1 -0
  53. package/output/source/helpers/response/response.js +73 -0
  54. package/output/source/helpers/response/response.test.js +50 -0
  55. package/output/source/index.js +215 -0
  56. package/output/source/projitive.js +488 -0
  57. package/output/source/projitive.test.js +75 -0
  58. package/output/source/readme.js +26 -0
  59. package/output/source/reports.js +36 -0
  60. package/output/source/roadmap.js +165 -0
  61. package/output/source/roadmap.test.js +11 -0
  62. package/output/source/tasks.js +762 -0
  63. package/output/source/tasks.test.js +152 -0
  64. package/output/tasks.js +403 -204
  65. package/output/tasks.test.js +78 -4
  66. package/package.json +1 -1
@@ -1,5 +1,8 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { TASKS_END, TASKS_START, isValidTaskId, normalizeTask, parseTasksBlock, rankActionableTaskCandidates, renderTasksMarkdown, taskPriority, toTaskUpdatedAtMs, validateTransition, } from "./tasks.js";
2
+ import { TASKS_END, TASKS_START, collectTaskLintSuggestions, isValidTaskId, normalizeTask, parseTasksBlock, rankActionableTaskCandidates, resolveNoTaskDiscoveryGuidance, renderTaskSeedTemplate, renderTasksMarkdown, taskPriority, toTaskUpdatedAtMs, validateTransition, } from "./tasks.js";
3
+ import fs from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
3
6
  function buildCandidate(partial) {
4
7
  const task = normalizeTask({
5
8
  id: partial.id,
@@ -29,8 +32,6 @@ describe("tasks module", () => {
29
32
  "- roadmapRefs: ROADMAP-0001",
30
33
  "- links:",
31
34
  " - ./designs/example.md",
32
- "- hooks:",
33
- " - onAssigned: ./hooks/on_task_assigned.md",
34
35
  TASKS_END,
35
36
  ].join("\n");
36
37
  const tasks = await parseTasksBlock(markdown);
@@ -38,7 +39,7 @@ describe("tasks module", () => {
38
39
  expect(tasks[0].id).toBe("TASK-0001");
39
40
  expect(tasks[0].status).toBe("TODO");
40
41
  expect(tasks[0].roadmapRefs).toEqual(["ROADMAP-0001"]);
41
- expect(tasks[0].hooks).toEqual({ onAssigned: "./hooks/on_task_assigned.md" });
42
+ expect(tasks[0].links).toEqual(["./designs/example.md"]);
42
43
  });
43
44
  it("renders markdown containing markers", () => {
44
45
  const task = normalizeTask({ id: "TASK-0002", title: "render", status: "IN_PROGRESS" });
@@ -75,4 +76,77 @@ describe("tasks module", () => {
75
76
  expect(ranked[1].task.id).toBe("TASK-0002");
76
77
  expect(ranked[2].task.id).toBe("TASK-0001");
77
78
  });
79
+ it("renders lint lines with stable code prefix", () => {
80
+ const task = normalizeTask({
81
+ id: "TASK-0001",
82
+ title: "lint",
83
+ status: "IN_PROGRESS",
84
+ owner: "",
85
+ roadmapRefs: [],
86
+ });
87
+ const lint = collectTaskLintSuggestions([task]);
88
+ expect(lint.some((line) => line.startsWith("- [TASK_IN_PROGRESS_OWNER_EMPTY]"))).toBe(true);
89
+ expect(lint.some((line) => line.startsWith("- [TASK_ROADMAP_REFS_EMPTY]"))).toBe(true);
90
+ });
91
+ it("scopes outside-marker lint to provided task IDs", () => {
92
+ const tasks = [
93
+ normalizeTask({ id: "TASK-0001", title: "A", status: "TODO", roadmapRefs: ["ROADMAP-0001"] }),
94
+ normalizeTask({ id: "TASK-0002", title: "B", status: "TODO", roadmapRefs: ["ROADMAP-0001"] }),
95
+ ];
96
+ const markdown = [
97
+ "# Tasks",
98
+ "TASK-0002 outside",
99
+ "TASK-0003 outside",
100
+ TASKS_START,
101
+ "## TASK-0001 | TODO | A",
102
+ "- owner: (none)",
103
+ "- summary: (none)",
104
+ "- updatedAt: 2026-02-18T00:00:00.000Z",
105
+ "- roadmapRefs: ROADMAP-0001",
106
+ "- links:",
107
+ " - (none)",
108
+ "## TASK-0002 | TODO | B",
109
+ "- owner: (none)",
110
+ "- summary: (none)",
111
+ "- updatedAt: 2026-02-18T00:00:00.000Z",
112
+ "- roadmapRefs: ROADMAP-0001",
113
+ "- links:",
114
+ " - (none)",
115
+ TASKS_END,
116
+ ].join("\n");
117
+ const scoped = collectTaskLintSuggestions(tasks, markdown, new Set(["TASK-0001"]));
118
+ const scopedOutside = scoped.find((line) => line.includes("TASK IDs found outside marker block"));
119
+ expect(scopedOutside).toBeUndefined();
120
+ const all = collectTaskLintSuggestions(tasks, markdown);
121
+ const allOutside = all.find((line) => line.includes("TASK IDs found outside marker block"));
122
+ expect(allOutside).toContain("TASK-0002");
123
+ expect(allOutside).toContain("TASK-0003");
124
+ });
125
+ it("renders seed task template with provided roadmap ref", () => {
126
+ const lines = renderTaskSeedTemplate("ROADMAP-0099");
127
+ const markdown = lines.join("\n");
128
+ expect(markdown).toContain("## TASK-0001 | TODO | Define initial executable objective");
129
+ expect(markdown).toContain("- roadmapRefs: ROADMAP-0099");
130
+ expect(markdown).toContain("- links:");
131
+ expect(markdown).not.toContain("- hooks:");
132
+ });
133
+ it("uses default no-task guidance when hook file is absent", async () => {
134
+ const guidance = await resolveNoTaskDiscoveryGuidance("/path/that/does/not/exist");
135
+ expect(guidance.length).toBeGreaterThan(3);
136
+ expect(guidance.some((line) => line.includes("TODO/FIXME/HACK"))).toBe(true);
137
+ });
138
+ it("uses hook checklist when task_no_actionable hook exists", async () => {
139
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "projitive-mcp-test-"));
140
+ const hooksDir = path.join(dir, "hooks");
141
+ await fs.mkdir(hooksDir, { recursive: true });
142
+ await fs.writeFile(path.join(hooksDir, "task_no_actionable.md"), [
143
+ "Objective:",
144
+ "- custom-item-1",
145
+ "- custom-item-2",
146
+ ].join("\n"), "utf-8");
147
+ const guidance = await resolveNoTaskDiscoveryGuidance(dir);
148
+ expect(guidance).toContain("- custom-item-1");
149
+ expect(guidance).toContain("- custom-item-2");
150
+ await fs.rm(dir, { recursive: true, force: true });
151
+ });
78
152
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projitive/mcp",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Projitive MCP Server for project and task discovery/update",
5
5
  "license": "ISC",
6
6
  "author": "",