@langadventurellc/task-trellis-mcp 2.6.0 → 2.8.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.
- package/README.md +9 -42
- package/dist/http/__tests__/projectTreePage.test.js +161 -0
- package/dist/http/__tests__/projectTreePage.test.js.map +1 -1
- package/dist/http/appShell.d.ts.map +1 -1
- package/dist/http/appShell.js +137 -3
- package/dist/http/appShell.js.map +1 -1
- package/dist/http/projectTreePage/__tests__/computeInitialOpenSet.test.d.ts +2 -0
- package/dist/http/projectTreePage/__tests__/computeInitialOpenSet.test.d.ts.map +1 -0
- package/dist/http/projectTreePage/__tests__/computeInitialOpenSet.test.js +82 -0
- package/dist/http/projectTreePage/__tests__/computeInitialOpenSet.test.js.map +1 -0
- package/dist/http/projectTreePage/__tests__/renderTreeFragment.test.d.ts +2 -0
- package/dist/http/projectTreePage/__tests__/renderTreeFragment.test.d.ts.map +1 -0
- package/dist/http/projectTreePage/__tests__/renderTreeFragment.test.js +124 -0
- package/dist/http/projectTreePage/__tests__/renderTreeFragment.test.js.map +1 -0
- package/dist/http/projectTreePage/computeInitialOpenSet.d.ts +1 -1
- package/dist/http/projectTreePage/computeInitialOpenSet.d.ts.map +1 -1
- package/dist/http/projectTreePage/computeInitialOpenSet.js +2 -1
- package/dist/http/projectTreePage/computeInitialOpenSet.js.map +1 -1
- package/dist/http/projectTreePage/projectTreeHandler.d.ts.map +1 -1
- package/dist/http/projectTreePage/projectTreeHandler.js +6 -1
- package/dist/http/projectTreePage/projectTreeHandler.js.map +1 -1
- package/dist/http/projectTreePage/renderTreeFragment.d.ts +6 -2
- package/dist/http/projectTreePage/renderTreeFragment.d.ts.map +1 -1
- package/dist/http/projectTreePage/renderTreeFragment.js +7 -5
- package/dist/http/projectTreePage/renderTreeFragment.js.map +1 -1
- package/dist/http/projectTreePage/searchHandler.d.ts.map +1 -1
- package/dist/http/projectTreePage/searchHandler.js +15 -3
- package/dist/http/projectTreePage/searchHandler.js.map +1 -1
- package/dist/http/projectTreePage/treeRow.js +1 -1
- package/dist/http/projectTreePage/treeRow.js.map +1 -1
- package/dist/server.js +0 -11
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/resources/__tests__/issueResources.test.d.ts +0 -2
- package/dist/resources/__tests__/issueResources.test.d.ts.map +0 -1
- package/dist/resources/__tests__/issueResources.test.js +0 -209
- package/dist/resources/__tests__/issueResources.test.js.map +0 -1
- package/dist/resources/buildIssueUri.d.ts +0 -3
- package/dist/resources/buildIssueUri.d.ts.map +0 -1
- package/dist/resources/buildIssueUri.js +0 -9
- package/dist/resources/buildIssueUri.js.map +0 -1
- package/dist/resources/decodeCursor.d.ts +0 -6
- package/dist/resources/decodeCursor.d.ts.map +0 -1
- package/dist/resources/decodeCursor.js +0 -15
- package/dist/resources/decodeCursor.js.map +0 -1
- package/dist/resources/encodeCursor.d.ts +0 -6
- package/dist/resources/encodeCursor.d.ts.map +0 -1
- package/dist/resources/encodeCursor.js +0 -14
- package/dist/resources/encodeCursor.js.map +0 -1
- package/dist/resources/handleListResourceTemplates.d.ts +0 -6
- package/dist/resources/handleListResourceTemplates.d.ts.map +0 -1
- package/dist/resources/handleListResourceTemplates.js +0 -18
- package/dist/resources/handleListResourceTemplates.js.map +0 -1
- package/dist/resources/handleListResources.d.ts +0 -10
- package/dist/resources/handleListResources.d.ts.map +0 -1
- package/dist/resources/handleListResources.js +0 -20
- package/dist/resources/handleListResources.js.map +0 -1
- package/dist/resources/handleReadResource.d.ts +0 -12
- package/dist/resources/handleReadResource.d.ts.map +0 -1
- package/dist/resources/handleReadResource.js +0 -25
- package/dist/resources/handleReadResource.js.map +0 -1
- package/dist/resources/index.d.ts +0 -9
- package/dist/resources/index.d.ts.map +0 -1
- package/dist/resources/index.js +0 -20
- package/dist/resources/index.js.map +0 -1
- package/dist/resources/issueResources.d.ts +0 -5
- package/dist/resources/issueResources.d.ts.map +0 -1
- package/dist/resources/issueResources.js +0 -15
- package/dist/resources/issueResources.js.map +0 -1
- package/dist/resources/parseIssueUri.d.ts +0 -7
- package/dist/resources/parseIssueUri.d.ts.map +0 -1
- package/dist/resources/parseIssueUri.js +0 -14
- package/dist/resources/parseIssueUri.js.map +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const models_1 = require("../../../models");
|
|
4
|
+
const renderTreeFragment_1 = require("../renderTreeFragment");
|
|
5
|
+
function makeObj(overrides = {}) {
|
|
6
|
+
return {
|
|
7
|
+
id: "T-test",
|
|
8
|
+
type: models_1.TrellisObjectType.TASK,
|
|
9
|
+
title: "Test Task",
|
|
10
|
+
status: models_1.TrellisObjectStatus.OPEN,
|
|
11
|
+
priority: models_1.TrellisObjectPriority.MEDIUM,
|
|
12
|
+
parent: null,
|
|
13
|
+
prerequisites: [],
|
|
14
|
+
affectedFiles: new Map(),
|
|
15
|
+
log: [],
|
|
16
|
+
schema: "v1.0",
|
|
17
|
+
childrenIds: [],
|
|
18
|
+
created: "2026-01-01T00:00:00Z",
|
|
19
|
+
updated: "2026-01-01T00:00:00Z",
|
|
20
|
+
body: "",
|
|
21
|
+
...overrides,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
describe("renderTreeFragment", () => {
|
|
25
|
+
it("honors a supplied openSet — matching IDs render with open class, others do not", () => {
|
|
26
|
+
const parent = makeObj({
|
|
27
|
+
id: "F-open",
|
|
28
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
29
|
+
title: "Open Feature",
|
|
30
|
+
childrenIds: ["T-child"],
|
|
31
|
+
parent: null,
|
|
32
|
+
});
|
|
33
|
+
const child = makeObj({ id: "T-child", parent: "F-open" });
|
|
34
|
+
const other = makeObj({
|
|
35
|
+
id: "F-closed",
|
|
36
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
37
|
+
title: "Closed Feature",
|
|
38
|
+
childrenIds: ["T-other-child"],
|
|
39
|
+
parent: null,
|
|
40
|
+
});
|
|
41
|
+
const otherChild = makeObj({ id: "T-other-child", parent: "F-closed" });
|
|
42
|
+
// Only F-open is in the supplied openSet
|
|
43
|
+
const openSet = new Set(["F-open"]);
|
|
44
|
+
const html = (0, renderTreeFragment_1.renderTreeFragment)("my-proj", [parent, child, other, otherChild], { openSet });
|
|
45
|
+
// F-open has children and is in openSet → renders with open class
|
|
46
|
+
expect(html).toMatch(/class="row open"/);
|
|
47
|
+
// F-closed has children but is NOT in openSet → no open class
|
|
48
|
+
const closedIdx = html.indexOf("Closed Feature");
|
|
49
|
+
const openIdx = html.indexOf("Open Feature");
|
|
50
|
+
// Closed Feature row must not have open class; verify the row's class attribute
|
|
51
|
+
const closedRowStart = html.lastIndexOf('<div class="row', closedIdx);
|
|
52
|
+
expect(html.slice(closedRowStart, closedIdx)).not.toContain("open");
|
|
53
|
+
// Open Feature row comes before its content
|
|
54
|
+
expect(openIdx).toBeGreaterThan(-1);
|
|
55
|
+
expect(closedIdx).toBeGreaterThan(-1);
|
|
56
|
+
});
|
|
57
|
+
it("with hideCompleted:true excludes done subtree IDs from HTML", () => {
|
|
58
|
+
const doneRoot = makeObj({
|
|
59
|
+
id: "F-done",
|
|
60
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
61
|
+
title: "Done Feature",
|
|
62
|
+
status: models_1.TrellisObjectStatus.DONE,
|
|
63
|
+
childrenIds: ["T-done-child"],
|
|
64
|
+
parent: null,
|
|
65
|
+
});
|
|
66
|
+
const doneChild = makeObj({
|
|
67
|
+
id: "T-done-child",
|
|
68
|
+
title: "Done Child",
|
|
69
|
+
parent: "F-done",
|
|
70
|
+
});
|
|
71
|
+
const openRoot = makeObj({
|
|
72
|
+
id: "F-open",
|
|
73
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
74
|
+
title: "Open Feature",
|
|
75
|
+
parent: null,
|
|
76
|
+
});
|
|
77
|
+
const html = (0, renderTreeFragment_1.renderTreeFragment)("my-proj", [doneRoot, doneChild, openRoot], { hideCompleted: true });
|
|
78
|
+
expect(html).not.toContain("F-done");
|
|
79
|
+
expect(html).not.toContain("T-done-child");
|
|
80
|
+
expect(html).toContain("F-open");
|
|
81
|
+
});
|
|
82
|
+
it("with hideCompleted:true keeps closed descendants of an open root", () => {
|
|
83
|
+
const openRoot = makeObj({
|
|
84
|
+
id: "F-open",
|
|
85
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
86
|
+
title: "Open Feature",
|
|
87
|
+
childrenIds: ["T-done-child"],
|
|
88
|
+
parent: null,
|
|
89
|
+
});
|
|
90
|
+
const doneChild = makeObj({
|
|
91
|
+
id: "T-done-child",
|
|
92
|
+
title: "Done Child Task",
|
|
93
|
+
status: models_1.TrellisObjectStatus.DONE,
|
|
94
|
+
parent: "F-open",
|
|
95
|
+
});
|
|
96
|
+
const html = (0, renderTreeFragment_1.renderTreeFragment)("my-proj", [openRoot, doneChild], {
|
|
97
|
+
hideCompleted: true,
|
|
98
|
+
});
|
|
99
|
+
expect(html).toContain("F-open");
|
|
100
|
+
expect(html).toContain("T-done-child");
|
|
101
|
+
});
|
|
102
|
+
it("falls back to computeInitialOpenSet when openSet is omitted", () => {
|
|
103
|
+
// F-parent has an in-progress child → computeInitialOpenSet will include F-parent
|
|
104
|
+
const parent = makeObj({
|
|
105
|
+
id: "F-parent",
|
|
106
|
+
type: models_1.TrellisObjectType.FEATURE,
|
|
107
|
+
title: "Parent Feature",
|
|
108
|
+
childrenIds: ["T-inprogress"],
|
|
109
|
+
parent: null,
|
|
110
|
+
});
|
|
111
|
+
const inProgress = makeObj({
|
|
112
|
+
id: "T-inprogress",
|
|
113
|
+
title: "In Progress Task",
|
|
114
|
+
status: models_1.TrellisObjectStatus.IN_PROGRESS,
|
|
115
|
+
parent: "F-parent",
|
|
116
|
+
});
|
|
117
|
+
// No options passed — should use computeInitialOpenSet
|
|
118
|
+
const html = (0, renderTreeFragment_1.renderTreeFragment)("my-proj", [parent, inProgress]);
|
|
119
|
+
// F-parent is an ancestor of an in-progress task → open class expected
|
|
120
|
+
expect(html).toMatch(/class="row open"/);
|
|
121
|
+
expect(html).toContain("Parent Feature");
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=renderTreeFragment.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderTreeFragment.test.js","sourceRoot":"","sources":["../../../../src/http/projectTreePage/__tests__/renderTreeFragment.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type TrellisObject } from "../../models";
|
|
2
|
-
/** IDs of rows that should start expanded:
|
|
2
|
+
/** IDs of rows that should start expanded: in-progress issues themselves and their ancestors. */
|
|
3
3
|
export declare function computeInitialOpenSet(objects: TrellisObject[]): Set<string>;
|
|
4
4
|
//# sourceMappingURL=computeInitialOpenSet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeInitialOpenSet.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/computeInitialOpenSet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAEvE,
|
|
1
|
+
{"version":3,"file":"computeInitialOpenSet.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/computeInitialOpenSet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAEvE,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAa3E"}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.computeInitialOpenSet = computeInitialOpenSet;
|
|
4
4
|
const models_1 = require("../../models");
|
|
5
|
-
/** IDs of rows that should start expanded:
|
|
5
|
+
/** IDs of rows that should start expanded: in-progress issues themselves and their ancestors. */
|
|
6
6
|
function computeInitialOpenSet(objects) {
|
|
7
7
|
const byId = new Map(objects.map((o) => [o.id, o]));
|
|
8
8
|
const open = new Set();
|
|
9
9
|
for (const o of objects) {
|
|
10
10
|
if (o.status !== models_1.TrellisObjectStatus.IN_PROGRESS)
|
|
11
11
|
continue;
|
|
12
|
+
open.add(o.id);
|
|
12
13
|
let parentId = o.parent;
|
|
13
14
|
while (parentId && !open.has(parentId)) {
|
|
14
15
|
open.add(parentId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeInitialOpenSet.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/computeInitialOpenSet.ts"],"names":[],"mappings":";;AAGA,
|
|
1
|
+
{"version":3,"file":"computeInitialOpenSet.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/computeInitialOpenSet.ts"],"names":[],"mappings":";;AAGA,sDAaC;AAhBD,yCAAuE;AAEvE,iGAAiG;AACjG,SAAgB,qBAAqB,CAAC,OAAwB;IAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,MAAM,KAAK,4BAAmB,CAAC,WAAW;YAAE,SAAS;QAC3D,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;QACxB,OAAO,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACnB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectTreeHandler.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/projectTreeHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AASjE,yGAAyG;AACzG,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"projectTreeHandler.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/projectTreeHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AASjE,yGAAyG;AACzG,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAsEf"}
|
|
@@ -19,7 +19,7 @@ async function projectTreeHandler(_req, res, params) {
|
|
|
19
19
|
}
|
|
20
20
|
const repo = (0, makeRepo_1.makeRepo)(key);
|
|
21
21
|
const allObjects = await repo.getObjects(true);
|
|
22
|
-
const treeHtml = (0, renderTreeFragment_1.renderTreeFragment)(key, allObjects);
|
|
22
|
+
const treeHtml = (0, renderTreeFragment_1.renderTreeFragment)(key, allObjects, { hideCompleted: true });
|
|
23
23
|
const keyEsc = (0, escapeHtml_1.escapeHtml)(key);
|
|
24
24
|
const sidebar = `<aside class="sidebar">
|
|
25
25
|
<div class="sidebar-header">
|
|
@@ -35,6 +35,10 @@ async function projectTreeHandler(_req, res, params) {
|
|
|
35
35
|
<svg class="theme-icon-light"><use href="#i-moon"/></svg>
|
|
36
36
|
<svg class="theme-icon-dark"><use href="#i-sun"/></svg>
|
|
37
37
|
</button>
|
|
38
|
+
<button class="icon-btn" id="filter-toggle" title="Toggle hide completed" aria-label="Toggle hide completed" type="button">
|
|
39
|
+
<svg class="filter-icon-on"><use href="#i-filter-on"/></svg>
|
|
40
|
+
<svg class="filter-icon-off"><use href="#i-filter-off"/></svg>
|
|
41
|
+
</button>
|
|
38
42
|
<button class="icon-btn" title="New top-level issue" type="button"
|
|
39
43
|
hx-get="/projects/${keyEsc}/issues/new" hx-target="#detail" hx-swap="innerHTML">
|
|
40
44
|
<svg><use href="#i-plus"/></svg>
|
|
@@ -55,6 +59,7 @@ async function projectTreeHandler(_req, res, params) {
|
|
|
55
59
|
|
|
56
60
|
<nav class="tree"
|
|
57
61
|
id="issue-tree"
|
|
62
|
+
data-project-key="${keyEsc}"
|
|
58
63
|
hx-trigger="refreshTree from:body"
|
|
59
64
|
hx-get="/projects/${keyEsc}/issues/search"
|
|
60
65
|
hx-swap="innerHTML">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectTreeHandler.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/projectTreeHandler.ts"],"names":[],"mappings":";;AAWA,
|
|
1
|
+
{"version":3,"file":"projectTreeHandler.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/projectTreeHandler.ts"],"names":[],"mappings":";;AAWA,gDA0EC;AArFD,qCAAqC;AAErC,yCAAiC;AACjC,uEAAoE;AACpE,0CAAuC;AACvC,8CAA2C;AAC3C,yCAAsC;AACtC,uCAAoC;AACpC,6DAA0D;AAE1D,yGAAyG;AAClG,KAAK,UAAU,kBAAkB,CACtC,IAAqB,EACrB,GAAmB,EACnB,MAA8B;IAE9B,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAEvB,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAA,gBAAI,EAAC,IAAA,+BAAc,GAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,IAAA,mBAAQ,EAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAA,uCAAkB,EAAC,GAAG,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,IAAA,uBAAU,EAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,OAAO,GAAG;;;;;;kCAMgB,MAAM;;;;;;;;;;;;;4BAaZ,MAAM;;;;;;;;;0BASR,MAAM;;;;;;0CAMU,IAAA,iBAAO,EAAC,UAAU,CAAC;;;;wBAIrC,MAAM;;wBAEN,MAAM;;MAExB,QAAQ;;SAEL,CAAC;IAER,MAAM,IAAI,GAAG;IACX,OAAO;;;;;OAKJ,CAAC;IAEN,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;IACpD,GAAG,CAAC,GAAG,CAAC,IAAA,mBAAQ,EAAC,uBAAuB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { TrellisObject } from "../../models";
|
|
2
|
-
/** Renders the hierarchical tree. Ancestors of in-progress issues start expanded; everything else collapsed.
|
|
3
|
-
|
|
2
|
+
/** Renders the hierarchical tree. Ancestors of in-progress issues start expanded; everything else collapsed.
|
|
3
|
+
* Supply `options.openSet` to override which rows start open. Pass `options.hideCompleted: true` to hide closed top-level issues (their descendants come along). */
|
|
4
|
+
export declare function renderTreeFragment(key: string, objects: TrellisObject[], options?: {
|
|
5
|
+
openSet?: Set<string>;
|
|
6
|
+
hideCompleted?: boolean;
|
|
7
|
+
}): string;
|
|
4
8
|
//# sourceMappingURL=renderTreeFragment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderTreeFragment.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/renderTreeFragment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"renderTreeFragment.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/renderTreeFragment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsClD;oKACoK;AACpK,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3D,MAAM,CAiBR"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.renderTreeFragment = renderTreeFragment;
|
|
4
|
+
const models_1 = require("../../models");
|
|
4
5
|
const computeInitialOpenSet_1 = require("./computeInitialOpenSet");
|
|
5
6
|
const treeRow_1 = require("./treeRow");
|
|
6
7
|
function buildNodes(key, objectMap, openSet, ids, depth, parentOpen) {
|
|
@@ -20,12 +21,13 @@ function buildNodes(key, objectMap, openSet, ids, depth, parentOpen) {
|
|
|
20
21
|
})
|
|
21
22
|
.join("\n");
|
|
22
23
|
}
|
|
23
|
-
/** Renders the hierarchical tree. Ancestors of in-progress issues start expanded; everything else collapsed.
|
|
24
|
-
|
|
24
|
+
/** Renders the hierarchical tree. Ancestors of in-progress issues start expanded; everything else collapsed.
|
|
25
|
+
* Supply `options.openSet` to override which rows start open. Pass `options.hideCompleted: true` to hide closed top-level issues (their descendants come along). */
|
|
26
|
+
function renderTreeFragment(key, objects, options) {
|
|
25
27
|
const objectMap = new Map(objects.map((o) => [o.id, o]));
|
|
26
|
-
const roots = objects.filter((o) => o.parent === null);
|
|
27
|
-
const openSet = (0, computeInitialOpenSet_1.computeInitialOpenSet)(objects);
|
|
28
|
-
const html = buildNodes(key, objectMap, openSet, roots.map((
|
|
28
|
+
const roots = objects.filter((o) => o.parent === null && (!options?.hideCompleted || !(0, models_1.isClosed)(o)));
|
|
29
|
+
const openSet = options?.openSet ?? (0, computeInitialOpenSet_1.computeInitialOpenSet)(objects);
|
|
30
|
+
const html = buildNodes(key, objectMap, openSet, roots.map((r) => r.id), 0, true);
|
|
29
31
|
return (html || '<p class="empty" style="padding:12px 16px;">No issues found.</p>');
|
|
30
32
|
}
|
|
31
33
|
//# sourceMappingURL=renderTreeFragment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderTreeFragment.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/renderTreeFragment.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"renderTreeFragment.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/renderTreeFragment.ts"],"names":[],"mappings":";;AAwCA,gDAqBC;AA5DD,yCAAwC;AACxC,mEAAgE;AAChE,uCAAoC;AAEpC,SAAS,UAAU,CACjB,GAAW,EACX,SAAqC,EACrC,OAAoB,EACpB,GAAa,EACb,KAAa,EACb,UAAmB;IAEnB,OAAO,GAAG;SACP,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACV,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAA,iBAAO,EAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE;YACvC,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,CAAC,UAAU;SACpB,CAAC,CAAC;QACH,MAAM,YAAY,GAChB,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACxB,CAAC,CAAC,UAAU,CACR,GAAG,EACH,SAAS,EACT,OAAO,EACP,GAAG,CAAC,WAAW,EACf,KAAK,GAAG,CAAC,EACT,MAAM,CACP;YACH,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,OAAO,GAAG,YAAY,CAAC;IAChC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;oKACoK;AACpK,SAAgB,kBAAkB,CAChC,GAAW,EACX,OAAwB,EACxB,OAA4D;IAE5D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,aAAa,IAAI,CAAC,IAAA,iBAAQ,EAAC,CAAC,CAAC,CAAC,CACtE,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAA,6CAAqB,EAAC,OAAO,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,UAAU,CACrB,GAAG,EACH,SAAS,EACT,OAAO,EACP,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACtB,CAAC,EACD,IAAI,CACL,CAAC;IACF,OAAO,CACL,IAAI,IAAI,kEAAkE,CAC3E,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchHandler.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/searchHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAiBjE,+FAA+F;AAC/F,wBAAsB,aAAa,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"searchHandler.d.ts","sourceRoot":"","sources":["../../../src/http/projectTreePage/searchHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAiBjE,+FAA+F;AAC/F,wBAAsB,aAAa,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
|
@@ -17,11 +17,23 @@ async function searchHandler(req, res, params) {
|
|
|
17
17
|
const { key } = params;
|
|
18
18
|
const url = new node_url_1.URL(req.url ?? "/", "http://localhost");
|
|
19
19
|
const q = url.searchParams.get("q") ?? "";
|
|
20
|
+
const hideDone = url.searchParams.get("hideDone");
|
|
21
|
+
const openParam = url.searchParams.get("open");
|
|
20
22
|
const repo = (0, makeRepo_1.makeRepo)(key);
|
|
21
23
|
const allObjects = await repo.getObjects(true);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
let tree;
|
|
25
|
+
if (q) {
|
|
26
|
+
tree = (0, renderFlatFragment_1.renderFlatFragment)(key, allObjects.filter((o) => matchesQuery(o, q)));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const openSet = openParam !== null
|
|
30
|
+
? new Set(openParam.split(",").filter(Boolean))
|
|
31
|
+
: undefined;
|
|
32
|
+
tree = (0, renderTreeFragment_1.renderTreeFragment)(key, allObjects, {
|
|
33
|
+
hideCompleted: hideDone === "1",
|
|
34
|
+
...(openSet ? { openSet } : {}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
25
37
|
const metaOob = `<div class="tree-meta" id="tree-meta" hx-swap-oob="true">${(0, metaBar_1.metaBar)(allObjects)}</div>`;
|
|
26
38
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
27
39
|
res.end(`${tree}\n${metaOob}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchHandler.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/searchHandler.ts"],"names":[],"mappings":";;AAkBA,
|
|
1
|
+
{"version":3,"file":"searchHandler.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/searchHandler.ts"],"names":[],"mappings":";;AAkBA,sCAmCC;AApDD,uCAA+B;AAE/B,yCAAsC;AACtC,uCAAoC;AACpC,6DAA0D;AAC1D,6DAA0D;AAE1D,SAAS,YAAY,CAAC,GAAkB,EAAE,CAAS;IACjD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9B,OAAO,CACL,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CACvC,CAAC;AACJ,CAAC;AAED,+FAA+F;AACxF,KAAK,UAAU,aAAa,CACjC,GAAoB,EACpB,GAAmB,EACnB,MAA8B;IAE9B,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IACvB,MAAM,GAAG,GAAG,IAAI,cAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;IACxD,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE/C,MAAM,IAAI,GAAG,IAAA,mBAAQ,EAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAE/C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC;QACN,IAAI,GAAG,IAAA,uCAAkB,EACvB,GAAG,EACH,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAC7C,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GACX,SAAS,KAAK,IAAI;YAChB,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,GAAG,IAAA,uCAAkB,EAAC,GAAG,EAAE,UAAU,EAAE;YACzC,aAAa,EAAE,QAAQ,KAAK,GAAG;YAC/B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,4DAA4D,IAAA,iBAAO,EAAC,UAAU,CAAC,QAAQ,CAAC;IAExG,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;IACpD,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -12,7 +12,7 @@ function treeRow(key, obj, depth, opts = {}) {
|
|
|
12
12
|
const openClass = hasChildren && opts.open ? " open" : "";
|
|
13
13
|
const hiddenAttr = opts.hidden ? " hidden" : "";
|
|
14
14
|
const indentPx = depth * 20;
|
|
15
|
-
return `<div class="row${openClass}"${hiddenAttr} style="--indent:${indentPx}px;"
|
|
15
|
+
return `<div class="row${openClass}"${hiddenAttr} data-id="${(0, escapeHtml_1.escapeHtml)(obj.id)}" style="--indent:${indentPx}px;"
|
|
16
16
|
hx-get="/projects/${(0, escapeHtml_1.escapeHtml)(key)}/issues/${(0, escapeHtml_1.escapeHtml)(obj.id)}/detail"
|
|
17
17
|
hx-target="#detail"
|
|
18
18
|
hx-swap="innerHTML"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeRow.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/treeRow.ts"],"names":[],"mappings":";;AAWA,0BAiBC;AA3BD,8CAA2C;AAC3C,yDAAsD;AACtD,qDAAkD;AAOlD,oGAAoG;AACpG,SAAgB,OAAO,CACrB,GAAW,EACX,GAAkB,EAClB,KAAa,EACb,OAAuB,EAAE;IAEzB,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;IACvD,MAAM,SAAS,GAAG,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE,CAAC;IAC5B,OAAO,kBAAkB,SAAS,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"treeRow.js","sourceRoot":"","sources":["../../../src/http/projectTreePage/treeRow.ts"],"names":[],"mappings":";;AAWA,0BAiBC;AA3BD,8CAA2C;AAC3C,yDAAsD;AACtD,qDAAkD;AAOlD,oGAAoG;AACpG,SAAgB,OAAO,CACrB,GAAW,EACX,GAAkB,EAClB,KAAa,EACb,OAAuB,EAAE;IAEzB,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;IACvD,MAAM,SAAS,GAAG,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE,CAAC;IAC5B,OAAO,kBAAkB,SAAS,IAAI,UAAU,aAAa,IAAA,uBAAU,EAAC,GAAG,CAAC,EAAE,CAAC,qBAAqB,QAAQ;sBACxF,IAAA,uBAAU,EAAC,GAAG,CAAC,WAAW,IAAA,uBAAU,EAAC,GAAG,CAAC,EAAE,CAAC;;;gBAGlD,SAAS,+DAA+D,IAAA,uBAAU,EAAC,UAAU,CAAC,kCAAkC,IAAA,uBAAU,EAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,IAAA,uBAAU,EAAC,IAAA,+BAAc,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC,8BAA8B,IAAA,uBAAU,EAAC,IAAA,mCAAgB,EAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,wBAAwB,CAAC;AAC/V,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -15,7 +15,6 @@ const configuration_1 = require("./configuration");
|
|
|
15
15
|
const repositories_1 = require("./repositories");
|
|
16
16
|
const LocalTaskTrellisService_1 = require("./services/local/LocalTaskTrellisService");
|
|
17
17
|
const tools_1 = require("./tools");
|
|
18
|
-
const resources_1 = require("./resources");
|
|
19
18
|
// Parse command line arguments
|
|
20
19
|
const program = new commander_1.Command();
|
|
21
20
|
program
|
|
@@ -89,7 +88,6 @@ A browser UI is also available; call get_ui_info to retrieve its URL whenever th
|
|
|
89
88
|
}, {
|
|
90
89
|
capabilities: {
|
|
91
90
|
tools: {},
|
|
92
|
-
resources: { listChanged: true },
|
|
93
91
|
},
|
|
94
92
|
});
|
|
95
93
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, () => {
|
|
@@ -144,15 +142,6 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, (request) => {
|
|
|
144
142
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
145
143
|
}
|
|
146
144
|
});
|
|
147
|
-
server.setRequestHandler(types_js_1.ListResourcesRequestSchema, (request) => {
|
|
148
|
-
return (0, resources_1.handleListResources)(request.params ?? {}, getRepository());
|
|
149
|
-
});
|
|
150
|
-
server.setRequestHandler(types_js_1.ListResourceTemplatesRequestSchema, () => {
|
|
151
|
-
return (0, resources_1.handleListResourceTemplates)();
|
|
152
|
-
});
|
|
153
|
-
server.setRequestHandler(types_js_1.ReadResourceRequestSchema, (request) => {
|
|
154
|
-
return (0, resources_1.handleReadResource)(request.params, getRepository());
|
|
155
|
-
});
|
|
156
145
|
async function runServer() {
|
|
157
146
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
158
147
|
await server.connect(transport);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;AAEA,wEAAmE;AACnE,wEAAiF;AACjF,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langadventurellc/task-trellis-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "An MCP server that helps AI coding agents break down projects into tasks and track their progress.",
|
|
5
5
|
"homepage": "https://github.com/langadventurellc/task-trellis-mcp#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issueResources.test.d.ts","sourceRoot":"","sources":["../../../src/resources/__tests__/issueResources.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const models_1 = require("../../models");
|
|
4
|
-
const index_1 = require("../index");
|
|
5
|
-
const mockObject = {
|
|
6
|
-
id: "T-test-task",
|
|
7
|
-
type: models_1.TrellisObjectType.TASK,
|
|
8
|
-
title: "Test Task",
|
|
9
|
-
status: models_1.TrellisObjectStatus.OPEN,
|
|
10
|
-
priority: models_1.TrellisObjectPriority.MEDIUM,
|
|
11
|
-
parent: "F-test-feature",
|
|
12
|
-
prerequisites: [],
|
|
13
|
-
affectedFiles: new Map(),
|
|
14
|
-
log: [],
|
|
15
|
-
schema: "v1.0",
|
|
16
|
-
childrenIds: [],
|
|
17
|
-
body: "Task body",
|
|
18
|
-
created: "2026-01-01T00:00:00Z",
|
|
19
|
-
updated: "2026-01-01T00:00:00Z",
|
|
20
|
-
};
|
|
21
|
-
describe("buildIssueUri", () => {
|
|
22
|
-
it("returns trellis://issue/<id>", () => {
|
|
23
|
-
expect((0, index_1.buildIssueUri)("T-test-task")).toBe("trellis://issue/T-test-task");
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
describe("parseIssueUri", () => {
|
|
27
|
-
it("extracts the issue id from a valid URI", () => {
|
|
28
|
-
expect((0, index_1.parseIssueUri)("trellis://issue/T-test-task")).toBe("T-test-task");
|
|
29
|
-
});
|
|
30
|
-
it("returns null for wrong scheme", () => {
|
|
31
|
-
expect((0, index_1.parseIssueUri)("http://issue/T-test-task")).toBeNull();
|
|
32
|
-
});
|
|
33
|
-
it("returns null for wrong case (Trellis://)", () => {
|
|
34
|
-
expect((0, index_1.parseIssueUri)("Trellis://issue/T-test-task")).toBeNull();
|
|
35
|
-
});
|
|
36
|
-
it("returns null when issue/ segment is missing", () => {
|
|
37
|
-
expect((0, index_1.parseIssueUri)("trellis://T-test-task")).toBeNull();
|
|
38
|
-
});
|
|
39
|
-
it("returns null for empty id (trailing slash only)", () => {
|
|
40
|
-
expect((0, index_1.parseIssueUri)("trellis://issue/")).toBeNull();
|
|
41
|
-
});
|
|
42
|
-
it("returns null when a query string is present", () => {
|
|
43
|
-
expect((0, index_1.parseIssueUri)("trellis://issue/T-test-task?foo=bar")).toBeNull();
|
|
44
|
-
});
|
|
45
|
-
it("returns null when a fragment is present", () => {
|
|
46
|
-
expect((0, index_1.parseIssueUri)("trellis://issue/T-test-task#anchor")).toBeNull();
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
describe("toResource", () => {
|
|
50
|
-
it("returns the correct resource shape without a size field", () => {
|
|
51
|
-
const resource = (0, index_1.toResource)(mockObject);
|
|
52
|
-
expect(resource).toEqual({
|
|
53
|
-
uri: "trellis://issue/T-test-task",
|
|
54
|
-
name: "T-test-task",
|
|
55
|
-
title: "Test Task",
|
|
56
|
-
description: "Test Task [open]",
|
|
57
|
-
mimeType: "text/markdown",
|
|
58
|
-
});
|
|
59
|
-
expect(resource).not.toHaveProperty("size");
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe("encodeCursor / decodeCursor", () => {
|
|
63
|
-
it("round-trips a non-negative integer offset", () => {
|
|
64
|
-
const cursor = (0, index_1.encodeCursor)(42);
|
|
65
|
-
expect((0, index_1.decodeCursor)(cursor)).toBe(42);
|
|
66
|
-
});
|
|
67
|
-
it("round-trips offset 0", () => {
|
|
68
|
-
expect((0, index_1.decodeCursor)((0, index_1.encodeCursor)(0))).toBe(0);
|
|
69
|
-
});
|
|
70
|
-
it("encodeCursor throws on a negative offset", () => {
|
|
71
|
-
expect(() => (0, index_1.encodeCursor)(-1)).toThrow();
|
|
72
|
-
});
|
|
73
|
-
it("encodeCursor throws on a non-integer offset", () => {
|
|
74
|
-
expect(() => (0, index_1.encodeCursor)(1.5)).toThrow();
|
|
75
|
-
});
|
|
76
|
-
it("decodeCursor throws on invalid base64 payload", () => {
|
|
77
|
-
const badCursor = Buffer.from("not-a-number").toString("base64");
|
|
78
|
-
expect(() => (0, index_1.decodeCursor)(badCursor)).toThrow();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
function makeMockRepository() {
|
|
82
|
-
return {
|
|
83
|
-
getObjectById: jest.fn(),
|
|
84
|
-
getObjects: jest.fn(),
|
|
85
|
-
saveObject: jest.fn(),
|
|
86
|
-
deleteObject: jest.fn(),
|
|
87
|
-
getChildrenOf: jest.fn(),
|
|
88
|
-
getAttachmentsFolder: jest.fn(),
|
|
89
|
-
listAttachments: jest.fn(),
|
|
90
|
-
copyAttachment: jest.fn(),
|
|
91
|
-
deleteAttachment: jest.fn(),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
function makeObject(id, status = models_1.TrellisObjectStatus.OPEN) {
|
|
95
|
-
return {
|
|
96
|
-
id,
|
|
97
|
-
type: models_1.TrellisObjectType.TASK,
|
|
98
|
-
title: `Title ${id}`,
|
|
99
|
-
status,
|
|
100
|
-
priority: models_1.TrellisObjectPriority.MEDIUM,
|
|
101
|
-
parent: null,
|
|
102
|
-
prerequisites: [],
|
|
103
|
-
affectedFiles: new Map(),
|
|
104
|
-
log: [],
|
|
105
|
-
schema: "v1.0",
|
|
106
|
-
childrenIds: [],
|
|
107
|
-
body: "",
|
|
108
|
-
created: "2026-01-01T00:00:00Z",
|
|
109
|
-
updated: "2026-01-01T00:00:00Z",
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
describe("handleListResources", () => {
|
|
113
|
-
it("returns correct resource shape for each object", async () => {
|
|
114
|
-
const repo = makeMockRepository();
|
|
115
|
-
repo.getObjects.mockResolvedValue([makeObject("T-alpha")]);
|
|
116
|
-
const { resources } = await (0, index_1.handleListResources)({}, repo);
|
|
117
|
-
expect(resources).toHaveLength(1);
|
|
118
|
-
expect(resources[0]).toEqual({
|
|
119
|
-
uri: "trellis://issue/T-alpha",
|
|
120
|
-
name: "T-alpha",
|
|
121
|
-
title: "Title T-alpha",
|
|
122
|
-
description: "Title T-alpha [open]",
|
|
123
|
-
mimeType: "text/markdown",
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
it("calls getObjects with false to exclude closed issues", async () => {
|
|
127
|
-
const repo = makeMockRepository();
|
|
128
|
-
repo.getObjects.mockResolvedValue([]);
|
|
129
|
-
await (0, index_1.handleListResources)({}, repo);
|
|
130
|
-
expect(repo.getObjects).toHaveBeenCalledWith(false);
|
|
131
|
-
});
|
|
132
|
-
it("includes draft, open, and in-progress objects", async () => {
|
|
133
|
-
const repo = makeMockRepository();
|
|
134
|
-
repo.getObjects.mockResolvedValue([
|
|
135
|
-
makeObject("T-a", models_1.TrellisObjectStatus.DRAFT),
|
|
136
|
-
makeObject("T-b", models_1.TrellisObjectStatus.OPEN),
|
|
137
|
-
makeObject("T-c", models_1.TrellisObjectStatus.IN_PROGRESS),
|
|
138
|
-
]);
|
|
139
|
-
const { resources } = await (0, index_1.handleListResources)({}, repo);
|
|
140
|
-
const ids = resources.map((r) => r.name);
|
|
141
|
-
expect(ids).toContain("T-a");
|
|
142
|
-
expect(ids).toContain("T-b");
|
|
143
|
-
expect(ids).toContain("T-c");
|
|
144
|
-
});
|
|
145
|
-
it("paginates across two pages for 150 items", async () => {
|
|
146
|
-
const repo = makeMockRepository();
|
|
147
|
-
const items = Array.from({ length: 150 }, (_, i) => makeObject(`T-${String(i).padStart(3, "0")}`));
|
|
148
|
-
repo.getObjects.mockResolvedValue(items);
|
|
149
|
-
const page1 = await (0, index_1.handleListResources)({}, repo);
|
|
150
|
-
expect(page1.resources).toHaveLength(100);
|
|
151
|
-
expect(page1.nextCursor).toBeDefined();
|
|
152
|
-
const page2 = await (0, index_1.handleListResources)({ cursor: page1.nextCursor }, repo);
|
|
153
|
-
expect(page2.resources).toHaveLength(50);
|
|
154
|
-
expect(page2.nextCursor).toBeUndefined();
|
|
155
|
-
});
|
|
156
|
-
it("returns empty resources and no nextCursor when getObjects returns []", async () => {
|
|
157
|
-
const repo = makeMockRepository();
|
|
158
|
-
repo.getObjects.mockResolvedValue([]);
|
|
159
|
-
const result = await (0, index_1.handleListResources)({}, repo);
|
|
160
|
-
expect(result).toEqual({ resources: [] });
|
|
161
|
-
expect(result.nextCursor).toBeUndefined();
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
describe("handleListResourceTemplates", () => {
|
|
165
|
-
it("returns the trellis-issue template", () => {
|
|
166
|
-
const { resourceTemplates } = (0, index_1.handleListResourceTemplates)();
|
|
167
|
-
expect(resourceTemplates).toHaveLength(1);
|
|
168
|
-
expect(resourceTemplates[0]).toEqual({
|
|
169
|
-
uriTemplate: "trellis://issue/{id}",
|
|
170
|
-
name: "trellis-issue",
|
|
171
|
-
title: "Trellis Issue",
|
|
172
|
-
description: "A Trellis issue (project, epic, feature, or task) referenced by ID",
|
|
173
|
-
mimeType: "text/markdown",
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
describe("handleReadResource", () => {
|
|
178
|
-
it("returns minimal payload for a known id", async () => {
|
|
179
|
-
const repo = makeMockRepository();
|
|
180
|
-
const obj = makeObject("T-known", models_1.TrellisObjectStatus.IN_PROGRESS);
|
|
181
|
-
obj.body = "should not appear";
|
|
182
|
-
repo.getObjectById.mockResolvedValue(obj);
|
|
183
|
-
const result = await (0, index_1.handleReadResource)({ uri: "trellis://issue/T-known" }, repo);
|
|
184
|
-
const text = result.contents[0].text;
|
|
185
|
-
expect(text).toContain("Title T-known");
|
|
186
|
-
expect(text).toContain("T-known");
|
|
187
|
-
expect(text).toContain("in-progress");
|
|
188
|
-
expect(text).not.toContain("should not appear");
|
|
189
|
-
expect(text).not.toContain("prerequisites");
|
|
190
|
-
expect(text).not.toContain("parent");
|
|
191
|
-
expect(text).not.toContain("log");
|
|
192
|
-
});
|
|
193
|
-
it("throws with the id when the issue is not found", async () => {
|
|
194
|
-
const repo = makeMockRepository();
|
|
195
|
-
repo.getObjectById.mockResolvedValue(null);
|
|
196
|
-
await expect((0, index_1.handleReadResource)({ uri: "trellis://issue/T-missing" }, repo)).rejects.toThrow("Trellis issue not found: T-missing");
|
|
197
|
-
});
|
|
198
|
-
it("throws before calling repository when URI has no issue/ segment", async () => {
|
|
199
|
-
const repo = makeMockRepository();
|
|
200
|
-
await expect((0, index_1.handleReadResource)({ uri: "trellis://T-no-segment" }, repo)).rejects.toThrow();
|
|
201
|
-
expect(repo.getObjectById).not.toHaveBeenCalled();
|
|
202
|
-
});
|
|
203
|
-
it("throws before calling repository for http:// scheme", async () => {
|
|
204
|
-
const repo = makeMockRepository();
|
|
205
|
-
await expect((0, index_1.handleReadResource)({ uri: "http://issue/T-wrong-scheme" }, repo)).rejects.toThrow();
|
|
206
|
-
expect(repo.getObjectById).not.toHaveBeenCalled();
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
//# sourceMappingURL=issueResources.test.js.map
|