@docyrus/docyrus 0.0.43 → 0.0.45
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 +116 -83
- package/agent-loader.js +30 -21
- package/agent-loader.js.map +2 -2
- package/main.js +1238 -1189
- package/main.js.map +4 -4
- package/package.json +1 -1
- package/resources/pi-agent/extensions/tasks.ts +41 -12
- package/resources/pi-agent/prompts/agent-system.md +2 -1
- package/resources/pi-agent/prompts/coder-system.md +3 -2
- package/server-loader.js +675 -494
- package/server-loader.js.map +3 -3
package/main.js
CHANGED
|
@@ -111,17 +111,17 @@ var require_visit = __commonJS({
|
|
|
111
111
|
visit2.BREAK = BREAK;
|
|
112
112
|
visit2.SKIP = SKIP2;
|
|
113
113
|
visit2.REMOVE = REMOVE;
|
|
114
|
-
function visit_(key, node2, visitor,
|
|
115
|
-
const ctrl = callVisitor(key, node2, visitor,
|
|
114
|
+
function visit_(key, node2, visitor, path6) {
|
|
115
|
+
const ctrl = callVisitor(key, node2, visitor, path6);
|
|
116
116
|
if (identity3.isNode(ctrl) || identity3.isPair(ctrl)) {
|
|
117
|
-
replaceNode(key,
|
|
118
|
-
return visit_(key, ctrl, visitor,
|
|
117
|
+
replaceNode(key, path6, ctrl);
|
|
118
|
+
return visit_(key, ctrl, visitor, path6);
|
|
119
119
|
}
|
|
120
120
|
if (typeof ctrl !== "symbol") {
|
|
121
121
|
if (identity3.isCollection(node2)) {
|
|
122
|
-
|
|
122
|
+
path6 = Object.freeze(path6.concat(node2));
|
|
123
123
|
for (let i2 = 0; i2 < node2.items.length; ++i2) {
|
|
124
|
-
const ci = visit_(i2, node2.items[i2], visitor,
|
|
124
|
+
const ci = visit_(i2, node2.items[i2], visitor, path6);
|
|
125
125
|
if (typeof ci === "number")
|
|
126
126
|
i2 = ci - 1;
|
|
127
127
|
else if (ci === BREAK)
|
|
@@ -132,13 +132,13 @@ var require_visit = __commonJS({
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
} else if (identity3.isPair(node2)) {
|
|
135
|
-
|
|
136
|
-
const ck = visit_("key", node2.key, visitor,
|
|
135
|
+
path6 = Object.freeze(path6.concat(node2));
|
|
136
|
+
const ck = visit_("key", node2.key, visitor, path6);
|
|
137
137
|
if (ck === BREAK)
|
|
138
138
|
return BREAK;
|
|
139
139
|
else if (ck === REMOVE)
|
|
140
140
|
node2.key = null;
|
|
141
|
-
const cv = visit_("value", node2.value, visitor,
|
|
141
|
+
const cv = visit_("value", node2.value, visitor, path6);
|
|
142
142
|
if (cv === BREAK)
|
|
143
143
|
return BREAK;
|
|
144
144
|
else if (cv === REMOVE)
|
|
@@ -159,17 +159,17 @@ var require_visit = __commonJS({
|
|
|
159
159
|
visitAsync.BREAK = BREAK;
|
|
160
160
|
visitAsync.SKIP = SKIP2;
|
|
161
161
|
visitAsync.REMOVE = REMOVE;
|
|
162
|
-
async function visitAsync_(key, node2, visitor,
|
|
163
|
-
const ctrl = await callVisitor(key, node2, visitor,
|
|
162
|
+
async function visitAsync_(key, node2, visitor, path6) {
|
|
163
|
+
const ctrl = await callVisitor(key, node2, visitor, path6);
|
|
164
164
|
if (identity3.isNode(ctrl) || identity3.isPair(ctrl)) {
|
|
165
|
-
replaceNode(key,
|
|
166
|
-
return visitAsync_(key, ctrl, visitor,
|
|
165
|
+
replaceNode(key, path6, ctrl);
|
|
166
|
+
return visitAsync_(key, ctrl, visitor, path6);
|
|
167
167
|
}
|
|
168
168
|
if (typeof ctrl !== "symbol") {
|
|
169
169
|
if (identity3.isCollection(node2)) {
|
|
170
|
-
|
|
170
|
+
path6 = Object.freeze(path6.concat(node2));
|
|
171
171
|
for (let i2 = 0; i2 < node2.items.length; ++i2) {
|
|
172
|
-
const ci = await visitAsync_(i2, node2.items[i2], visitor,
|
|
172
|
+
const ci = await visitAsync_(i2, node2.items[i2], visitor, path6);
|
|
173
173
|
if (typeof ci === "number")
|
|
174
174
|
i2 = ci - 1;
|
|
175
175
|
else if (ci === BREAK)
|
|
@@ -180,13 +180,13 @@ var require_visit = __commonJS({
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
} else if (identity3.isPair(node2)) {
|
|
183
|
-
|
|
184
|
-
const ck = await visitAsync_("key", node2.key, visitor,
|
|
183
|
+
path6 = Object.freeze(path6.concat(node2));
|
|
184
|
+
const ck = await visitAsync_("key", node2.key, visitor, path6);
|
|
185
185
|
if (ck === BREAK)
|
|
186
186
|
return BREAK;
|
|
187
187
|
else if (ck === REMOVE)
|
|
188
188
|
node2.key = null;
|
|
189
|
-
const cv = await visitAsync_("value", node2.value, visitor,
|
|
189
|
+
const cv = await visitAsync_("value", node2.value, visitor, path6);
|
|
190
190
|
if (cv === BREAK)
|
|
191
191
|
return BREAK;
|
|
192
192
|
else if (cv === REMOVE)
|
|
@@ -213,23 +213,23 @@ var require_visit = __commonJS({
|
|
|
213
213
|
}
|
|
214
214
|
return visitor;
|
|
215
215
|
}
|
|
216
|
-
function callVisitor(key, node2, visitor,
|
|
216
|
+
function callVisitor(key, node2, visitor, path6) {
|
|
217
217
|
if (typeof visitor === "function")
|
|
218
|
-
return visitor(key, node2,
|
|
218
|
+
return visitor(key, node2, path6);
|
|
219
219
|
if (identity3.isMap(node2))
|
|
220
|
-
return visitor.Map?.(key, node2,
|
|
220
|
+
return visitor.Map?.(key, node2, path6);
|
|
221
221
|
if (identity3.isSeq(node2))
|
|
222
|
-
return visitor.Seq?.(key, node2,
|
|
222
|
+
return visitor.Seq?.(key, node2, path6);
|
|
223
223
|
if (identity3.isPair(node2))
|
|
224
|
-
return visitor.Pair?.(key, node2,
|
|
224
|
+
return visitor.Pair?.(key, node2, path6);
|
|
225
225
|
if (identity3.isScalar(node2))
|
|
226
|
-
return visitor.Scalar?.(key, node2,
|
|
226
|
+
return visitor.Scalar?.(key, node2, path6);
|
|
227
227
|
if (identity3.isAlias(node2))
|
|
228
|
-
return visitor.Alias?.(key, node2,
|
|
228
|
+
return visitor.Alias?.(key, node2, path6);
|
|
229
229
|
return void 0;
|
|
230
230
|
}
|
|
231
|
-
function replaceNode(key,
|
|
232
|
-
const parent =
|
|
231
|
+
function replaceNode(key, path6, node2) {
|
|
232
|
+
const parent = path6[path6.length - 1];
|
|
233
233
|
if (identity3.isCollection(parent)) {
|
|
234
234
|
parent.items[key] = node2;
|
|
235
235
|
} else if (identity3.isPair(parent)) {
|
|
@@ -837,10 +837,10 @@ var require_Collection = __commonJS({
|
|
|
837
837
|
var createNode = require_createNode();
|
|
838
838
|
var identity3 = require_identity();
|
|
839
839
|
var Node2 = require_Node();
|
|
840
|
-
function collectionFromPath(schema,
|
|
840
|
+
function collectionFromPath(schema, path6, value2) {
|
|
841
841
|
let v = value2;
|
|
842
|
-
for (let i2 =
|
|
843
|
-
const k =
|
|
842
|
+
for (let i2 = path6.length - 1; i2 >= 0; --i2) {
|
|
843
|
+
const k = path6[i2];
|
|
844
844
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
845
845
|
const a = [];
|
|
846
846
|
a[k] = v;
|
|
@@ -859,7 +859,7 @@ var require_Collection = __commonJS({
|
|
|
859
859
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
860
860
|
});
|
|
861
861
|
}
|
|
862
|
-
var isEmptyPath = (
|
|
862
|
+
var isEmptyPath = (path6) => path6 == null || typeof path6 === "object" && !!path6[Symbol.iterator]().next().done;
|
|
863
863
|
var Collection = class extends Node2.NodeBase {
|
|
864
864
|
constructor(type, schema) {
|
|
865
865
|
super(type);
|
|
@@ -889,11 +889,11 @@ var require_Collection = __commonJS({
|
|
|
889
889
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
890
890
|
* that already exists in the map.
|
|
891
891
|
*/
|
|
892
|
-
addIn(
|
|
893
|
-
if (isEmptyPath(
|
|
892
|
+
addIn(path6, value2) {
|
|
893
|
+
if (isEmptyPath(path6))
|
|
894
894
|
this.add(value2);
|
|
895
895
|
else {
|
|
896
|
-
const [key, ...rest] =
|
|
896
|
+
const [key, ...rest] = path6;
|
|
897
897
|
const node2 = this.get(key, true);
|
|
898
898
|
if (identity3.isCollection(node2))
|
|
899
899
|
node2.addIn(rest, value2);
|
|
@@ -907,8 +907,8 @@ var require_Collection = __commonJS({
|
|
|
907
907
|
* Removes a value from the collection.
|
|
908
908
|
* @returns `true` if the item was found and removed.
|
|
909
909
|
*/
|
|
910
|
-
deleteIn(
|
|
911
|
-
const [key, ...rest] =
|
|
910
|
+
deleteIn(path6) {
|
|
911
|
+
const [key, ...rest] = path6;
|
|
912
912
|
if (rest.length === 0)
|
|
913
913
|
return this.delete(key);
|
|
914
914
|
const node2 = this.get(key, true);
|
|
@@ -922,8 +922,8 @@ var require_Collection = __commonJS({
|
|
|
922
922
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
923
923
|
* `true` (collections are always returned intact).
|
|
924
924
|
*/
|
|
925
|
-
getIn(
|
|
926
|
-
const [key, ...rest] =
|
|
925
|
+
getIn(path6, keepScalar) {
|
|
926
|
+
const [key, ...rest] = path6;
|
|
927
927
|
const node2 = this.get(key, true);
|
|
928
928
|
if (rest.length === 0)
|
|
929
929
|
return !keepScalar && identity3.isScalar(node2) ? node2.value : node2;
|
|
@@ -941,8 +941,8 @@ var require_Collection = __commonJS({
|
|
|
941
941
|
/**
|
|
942
942
|
* Checks if the collection includes a value with the key `key`.
|
|
943
943
|
*/
|
|
944
|
-
hasIn(
|
|
945
|
-
const [key, ...rest] =
|
|
944
|
+
hasIn(path6) {
|
|
945
|
+
const [key, ...rest] = path6;
|
|
946
946
|
if (rest.length === 0)
|
|
947
947
|
return this.has(key);
|
|
948
948
|
const node2 = this.get(key, true);
|
|
@@ -952,8 +952,8 @@ var require_Collection = __commonJS({
|
|
|
952
952
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
953
953
|
* boolean to add/remove the item from the set.
|
|
954
954
|
*/
|
|
955
|
-
setIn(
|
|
956
|
-
const [key, ...rest] =
|
|
955
|
+
setIn(path6, value2) {
|
|
956
|
+
const [key, ...rest] = path6;
|
|
957
957
|
if (rest.length === 0) {
|
|
958
958
|
this.set(key, value2);
|
|
959
959
|
} else {
|
|
@@ -3465,9 +3465,9 @@ var require_Document = __commonJS({
|
|
|
3465
3465
|
this.contents.add(value2);
|
|
3466
3466
|
}
|
|
3467
3467
|
/** Adds a value to the document. */
|
|
3468
|
-
addIn(
|
|
3468
|
+
addIn(path6, value2) {
|
|
3469
3469
|
if (assertCollection(this.contents))
|
|
3470
|
-
this.contents.addIn(
|
|
3470
|
+
this.contents.addIn(path6, value2);
|
|
3471
3471
|
}
|
|
3472
3472
|
/**
|
|
3473
3473
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3542,14 +3542,14 @@ var require_Document = __commonJS({
|
|
|
3542
3542
|
* Removes a value from the document.
|
|
3543
3543
|
* @returns `true` if the item was found and removed.
|
|
3544
3544
|
*/
|
|
3545
|
-
deleteIn(
|
|
3546
|
-
if (Collection.isEmptyPath(
|
|
3545
|
+
deleteIn(path6) {
|
|
3546
|
+
if (Collection.isEmptyPath(path6)) {
|
|
3547
3547
|
if (this.contents == null)
|
|
3548
3548
|
return false;
|
|
3549
3549
|
this.contents = null;
|
|
3550
3550
|
return true;
|
|
3551
3551
|
}
|
|
3552
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3552
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path6) : false;
|
|
3553
3553
|
}
|
|
3554
3554
|
/**
|
|
3555
3555
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3564,10 +3564,10 @@ var require_Document = __commonJS({
|
|
|
3564
3564
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3565
3565
|
* `true` (collections are always returned intact).
|
|
3566
3566
|
*/
|
|
3567
|
-
getIn(
|
|
3568
|
-
if (Collection.isEmptyPath(
|
|
3567
|
+
getIn(path6, keepScalar) {
|
|
3568
|
+
if (Collection.isEmptyPath(path6))
|
|
3569
3569
|
return !keepScalar && identity3.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3570
|
-
return identity3.isCollection(this.contents) ? this.contents.getIn(
|
|
3570
|
+
return identity3.isCollection(this.contents) ? this.contents.getIn(path6, keepScalar) : void 0;
|
|
3571
3571
|
}
|
|
3572
3572
|
/**
|
|
3573
3573
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3578,10 +3578,10 @@ var require_Document = __commonJS({
|
|
|
3578
3578
|
/**
|
|
3579
3579
|
* Checks if the document includes a value at `path`.
|
|
3580
3580
|
*/
|
|
3581
|
-
hasIn(
|
|
3582
|
-
if (Collection.isEmptyPath(
|
|
3581
|
+
hasIn(path6) {
|
|
3582
|
+
if (Collection.isEmptyPath(path6))
|
|
3583
3583
|
return this.contents !== void 0;
|
|
3584
|
-
return identity3.isCollection(this.contents) ? this.contents.hasIn(
|
|
3584
|
+
return identity3.isCollection(this.contents) ? this.contents.hasIn(path6) : false;
|
|
3585
3585
|
}
|
|
3586
3586
|
/**
|
|
3587
3587
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3598,13 +3598,13 @@ var require_Document = __commonJS({
|
|
|
3598
3598
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3599
3599
|
* boolean to add/remove the item from the set.
|
|
3600
3600
|
*/
|
|
3601
|
-
setIn(
|
|
3602
|
-
if (Collection.isEmptyPath(
|
|
3601
|
+
setIn(path6, value2) {
|
|
3602
|
+
if (Collection.isEmptyPath(path6)) {
|
|
3603
3603
|
this.contents = value2;
|
|
3604
3604
|
} else if (this.contents == null) {
|
|
3605
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3605
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path6), value2);
|
|
3606
3606
|
} else if (assertCollection(this.contents)) {
|
|
3607
|
-
this.contents.setIn(
|
|
3607
|
+
this.contents.setIn(path6, value2);
|
|
3608
3608
|
}
|
|
3609
3609
|
}
|
|
3610
3610
|
/**
|
|
@@ -5561,9 +5561,9 @@ var require_cst_visit = __commonJS({
|
|
|
5561
5561
|
visit2.BREAK = BREAK;
|
|
5562
5562
|
visit2.SKIP = SKIP2;
|
|
5563
5563
|
visit2.REMOVE = REMOVE;
|
|
5564
|
-
visit2.itemAtPath = (cst,
|
|
5564
|
+
visit2.itemAtPath = (cst, path6) => {
|
|
5565
5565
|
let item = cst;
|
|
5566
|
-
for (const [field, index2] of
|
|
5566
|
+
for (const [field, index2] of path6) {
|
|
5567
5567
|
const tok = item?.[field];
|
|
5568
5568
|
if (tok && "items" in tok) {
|
|
5569
5569
|
item = tok.items[index2];
|
|
@@ -5572,23 +5572,23 @@ var require_cst_visit = __commonJS({
|
|
|
5572
5572
|
}
|
|
5573
5573
|
return item;
|
|
5574
5574
|
};
|
|
5575
|
-
visit2.parentCollection = (cst,
|
|
5576
|
-
const parent = visit2.itemAtPath(cst,
|
|
5577
|
-
const field =
|
|
5575
|
+
visit2.parentCollection = (cst, path6) => {
|
|
5576
|
+
const parent = visit2.itemAtPath(cst, path6.slice(0, -1));
|
|
5577
|
+
const field = path6[path6.length - 1][0];
|
|
5578
5578
|
const coll = parent?.[field];
|
|
5579
5579
|
if (coll && "items" in coll)
|
|
5580
5580
|
return coll;
|
|
5581
5581
|
throw new Error("Parent collection not found");
|
|
5582
5582
|
};
|
|
5583
|
-
function _visit(
|
|
5584
|
-
let ctrl = visitor(item,
|
|
5583
|
+
function _visit(path6, item, visitor) {
|
|
5584
|
+
let ctrl = visitor(item, path6);
|
|
5585
5585
|
if (typeof ctrl === "symbol")
|
|
5586
5586
|
return ctrl;
|
|
5587
5587
|
for (const field of ["key", "value"]) {
|
|
5588
5588
|
const token = item[field];
|
|
5589
5589
|
if (token && "items" in token) {
|
|
5590
5590
|
for (let i2 = 0; i2 < token.items.length; ++i2) {
|
|
5591
|
-
const ci = _visit(Object.freeze(
|
|
5591
|
+
const ci = _visit(Object.freeze(path6.concat([[field, i2]])), token.items[i2], visitor);
|
|
5592
5592
|
if (typeof ci === "number")
|
|
5593
5593
|
i2 = ci - 1;
|
|
5594
5594
|
else if (ci === BREAK)
|
|
@@ -5599,10 +5599,10 @@ var require_cst_visit = __commonJS({
|
|
|
5599
5599
|
}
|
|
5600
5600
|
}
|
|
5601
5601
|
if (typeof ctrl === "function" && field === "key")
|
|
5602
|
-
ctrl = ctrl(item,
|
|
5602
|
+
ctrl = ctrl(item, path6);
|
|
5603
5603
|
}
|
|
5604
5604
|
}
|
|
5605
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5605
|
+
return typeof ctrl === "function" ? ctrl(item, path6) : ctrl;
|
|
5606
5606
|
}
|
|
5607
5607
|
exports2.visit = visit2;
|
|
5608
5608
|
}
|
|
@@ -10529,8 +10529,8 @@ var require_utils = __commonJS({
|
|
|
10529
10529
|
}
|
|
10530
10530
|
return ind;
|
|
10531
10531
|
}
|
|
10532
|
-
function removeDotSegments(
|
|
10533
|
-
let input =
|
|
10532
|
+
function removeDotSegments(path6) {
|
|
10533
|
+
let input = path6;
|
|
10534
10534
|
const output = [];
|
|
10535
10535
|
let nextSlash = -1;
|
|
10536
10536
|
let len = 0;
|
|
@@ -10729,8 +10729,8 @@ var require_schemes = __commonJS({
|
|
|
10729
10729
|
wsComponent.secure = void 0;
|
|
10730
10730
|
}
|
|
10731
10731
|
if (wsComponent.resourceName) {
|
|
10732
|
-
const [
|
|
10733
|
-
wsComponent.path =
|
|
10732
|
+
const [path6, query] = wsComponent.resourceName.split("?");
|
|
10733
|
+
wsComponent.path = path6 && path6 !== "/" ? path6 : void 0;
|
|
10734
10734
|
wsComponent.query = query;
|
|
10735
10735
|
wsComponent.resourceName = void 0;
|
|
10736
10736
|
}
|
|
@@ -61639,15 +61639,15 @@ var require_route = __commonJS({
|
|
|
61639
61639
|
};
|
|
61640
61640
|
}
|
|
61641
61641
|
function wrapConversion(toModel, graph) {
|
|
61642
|
-
const
|
|
61642
|
+
const path6 = [graph[toModel].parent, toModel];
|
|
61643
61643
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
61644
61644
|
let cur = graph[toModel].parent;
|
|
61645
61645
|
while (graph[cur].parent) {
|
|
61646
|
-
|
|
61646
|
+
path6.unshift(graph[cur].parent);
|
|
61647
61647
|
fn = link3(conversions[graph[cur].parent][cur], fn);
|
|
61648
61648
|
cur = graph[cur].parent;
|
|
61649
61649
|
}
|
|
61650
|
-
fn.conversion =
|
|
61650
|
+
fn.conversion = path6;
|
|
61651
61651
|
return fn;
|
|
61652
61652
|
}
|
|
61653
61653
|
module2.exports = function(fromModel) {
|
|
@@ -76272,11 +76272,11 @@ var require_commonjs3 = __commonJS({
|
|
|
76272
76272
|
return (f) => f.length === len && f !== "." && f !== "..";
|
|
76273
76273
|
};
|
|
76274
76274
|
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
76275
|
-
var
|
|
76275
|
+
var path6 = {
|
|
76276
76276
|
win32: { sep: "\\" },
|
|
76277
76277
|
posix: { sep: "/" }
|
|
76278
76278
|
};
|
|
76279
|
-
exports2.sep = defaultPlatform === "win32" ?
|
|
76279
|
+
exports2.sep = defaultPlatform === "win32" ? path6.win32.sep : path6.posix.sep;
|
|
76280
76280
|
exports2.minimatch.sep = exports2.sep;
|
|
76281
76281
|
exports2.GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
76282
76282
|
exports2.minimatch.GLOBSTAR = exports2.GLOBSTAR;
|
|
@@ -77047,7 +77047,7 @@ var require_lib4 = __commonJS({
|
|
|
77047
77047
|
"../../node_modules/.pnpm/ignore-walk@8.0.0/node_modules/ignore-walk/lib/index.js"(exports2, module2) {
|
|
77048
77048
|
"use strict";
|
|
77049
77049
|
var fs7 = require("fs");
|
|
77050
|
-
var
|
|
77050
|
+
var path6 = require("path");
|
|
77051
77051
|
var EE = require("events").EventEmitter;
|
|
77052
77052
|
var Minimatch = require_commonjs3().Minimatch;
|
|
77053
77053
|
var Walker = class _Walker extends EE {
|
|
@@ -77056,7 +77056,7 @@ var require_lib4 = __commonJS({
|
|
|
77056
77056
|
super(opts);
|
|
77057
77057
|
this.isSymbolicLink = opts.isSymbolicLink;
|
|
77058
77058
|
this.path = opts.path || process.cwd();
|
|
77059
|
-
this.basename =
|
|
77059
|
+
this.basename = path6.basename(this.path);
|
|
77060
77060
|
this.ignoreFiles = opts.ignoreFiles || [".ignore"];
|
|
77061
77061
|
this.ignoreRules = {};
|
|
77062
77062
|
this.parent = opts.parent || null;
|
|
@@ -77122,7 +77122,7 @@ var require_lib4 = __commonJS({
|
|
|
77122
77122
|
newIg.forEach((e) => this.addIgnoreFile(e, then));
|
|
77123
77123
|
}
|
|
77124
77124
|
addIgnoreFile(file2, then) {
|
|
77125
|
-
const ig =
|
|
77125
|
+
const ig = path6.resolve(this.path, file2);
|
|
77126
77126
|
fs7.readFile(ig, "utf8", (er, data) => er ? this.emit("error", er) : this.onReadIgnoreFile(file2, data, then));
|
|
77127
77127
|
}
|
|
77128
77128
|
onReadIgnoreFile(file2, data, then) {
|
|
@@ -77244,7 +77244,7 @@ var require_lib4 = __commonJS({
|
|
|
77244
77244
|
return this;
|
|
77245
77245
|
}
|
|
77246
77246
|
addIgnoreFile(file2, then) {
|
|
77247
|
-
const ig =
|
|
77247
|
+
const ig = path6.resolve(this.path, file2);
|
|
77248
77248
|
this.onReadIgnoreFile(file2, fs7.readFileSync(ig, "utf8"), then);
|
|
77249
77249
|
}
|
|
77250
77250
|
stat({ entry, file: file2, dir }, then) {
|
|
@@ -85621,8 +85621,8 @@ function assertNonEmpty(part, name2) {
|
|
|
85621
85621
|
throw new Error("`" + name2 + "` cannot be empty");
|
|
85622
85622
|
}
|
|
85623
85623
|
}
|
|
85624
|
-
function assertPath(
|
|
85625
|
-
if (!
|
|
85624
|
+
function assertPath(path6, name2) {
|
|
85625
|
+
if (!path6) {
|
|
85626
85626
|
throw new Error("Setting `" + name2 + "` requires `path` to be set too");
|
|
85627
85627
|
}
|
|
85628
85628
|
}
|
|
@@ -85808,13 +85808,13 @@ var init_lib10 = __esm({
|
|
|
85808
85808
|
* @returns {undefined}
|
|
85809
85809
|
* Nothing.
|
|
85810
85810
|
*/
|
|
85811
|
-
set path(
|
|
85812
|
-
if (isUrl(
|
|
85813
|
-
|
|
85811
|
+
set path(path6) {
|
|
85812
|
+
if (isUrl(path6)) {
|
|
85813
|
+
path6 = (0, import_node_url.fileURLToPath)(path6);
|
|
85814
85814
|
}
|
|
85815
|
-
assertNonEmpty(
|
|
85816
|
-
if (this.path !==
|
|
85817
|
-
this.history.push(
|
|
85815
|
+
assertNonEmpty(path6, "path");
|
|
85816
|
+
if (this.path !== path6) {
|
|
85817
|
+
this.history.push(path6);
|
|
85818
85818
|
}
|
|
85819
85819
|
}
|
|
85820
85820
|
/**
|
|
@@ -88717,14 +88717,14 @@ var require_util3 = __commonJS({
|
|
|
88717
88717
|
}
|
|
88718
88718
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
88719
88719
|
let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
88720
|
-
let
|
|
88720
|
+
let path6 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
88721
88721
|
if (origin[origin.length - 1] === "/") {
|
|
88722
88722
|
origin = origin.slice(0, origin.length - 1);
|
|
88723
88723
|
}
|
|
88724
|
-
if (
|
|
88725
|
-
|
|
88724
|
+
if (path6 && path6[0] !== "/") {
|
|
88725
|
+
path6 = `/${path6}`;
|
|
88726
88726
|
}
|
|
88727
|
-
return new URL(`${origin}${
|
|
88727
|
+
return new URL(`${origin}${path6}`);
|
|
88728
88728
|
}
|
|
88729
88729
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
88730
88730
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -89545,9 +89545,9 @@ var require_diagnostics = __commonJS({
|
|
|
89545
89545
|
"undici:client:sendHeaders",
|
|
89546
89546
|
(evt) => {
|
|
89547
89547
|
const {
|
|
89548
|
-
request: { method, path:
|
|
89548
|
+
request: { method, path: path6, origin }
|
|
89549
89549
|
} = evt;
|
|
89550
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
89550
|
+
debugLog("sending request to %s %s%s", method, origin, path6);
|
|
89551
89551
|
}
|
|
89552
89552
|
);
|
|
89553
89553
|
}
|
|
@@ -89565,14 +89565,14 @@ var require_diagnostics = __commonJS({
|
|
|
89565
89565
|
"undici:request:headers",
|
|
89566
89566
|
(evt) => {
|
|
89567
89567
|
const {
|
|
89568
|
-
request: { method, path:
|
|
89568
|
+
request: { method, path: path6, origin },
|
|
89569
89569
|
response: { statusCode }
|
|
89570
89570
|
} = evt;
|
|
89571
89571
|
debugLog(
|
|
89572
89572
|
"received response to %s %s%s - HTTP %d",
|
|
89573
89573
|
method,
|
|
89574
89574
|
origin,
|
|
89575
|
-
|
|
89575
|
+
path6,
|
|
89576
89576
|
statusCode
|
|
89577
89577
|
);
|
|
89578
89578
|
}
|
|
@@ -89581,23 +89581,23 @@ var require_diagnostics = __commonJS({
|
|
|
89581
89581
|
"undici:request:trailers",
|
|
89582
89582
|
(evt) => {
|
|
89583
89583
|
const {
|
|
89584
|
-
request: { method, path:
|
|
89584
|
+
request: { method, path: path6, origin }
|
|
89585
89585
|
} = evt;
|
|
89586
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
89586
|
+
debugLog("trailers received from %s %s%s", method, origin, path6);
|
|
89587
89587
|
}
|
|
89588
89588
|
);
|
|
89589
89589
|
diagnosticsChannel.subscribe(
|
|
89590
89590
|
"undici:request:error",
|
|
89591
89591
|
(evt) => {
|
|
89592
89592
|
const {
|
|
89593
|
-
request: { method, path:
|
|
89593
|
+
request: { method, path: path6, origin },
|
|
89594
89594
|
error: error48
|
|
89595
89595
|
} = evt;
|
|
89596
89596
|
debugLog(
|
|
89597
89597
|
"request to %s %s%s errored - %s",
|
|
89598
89598
|
method,
|
|
89599
89599
|
origin,
|
|
89600
|
-
|
|
89600
|
+
path6,
|
|
89601
89601
|
error48.message
|
|
89602
89602
|
);
|
|
89603
89603
|
}
|
|
@@ -89700,7 +89700,7 @@ var require_request = __commonJS({
|
|
|
89700
89700
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
89701
89701
|
var Request = class {
|
|
89702
89702
|
constructor(origin, {
|
|
89703
|
-
path:
|
|
89703
|
+
path: path6,
|
|
89704
89704
|
method,
|
|
89705
89705
|
body: body2,
|
|
89706
89706
|
headers,
|
|
@@ -89717,11 +89717,11 @@ var require_request = __commonJS({
|
|
|
89717
89717
|
maxRedirections,
|
|
89718
89718
|
typeOfService
|
|
89719
89719
|
}, handler2) {
|
|
89720
|
-
if (typeof
|
|
89720
|
+
if (typeof path6 !== "string") {
|
|
89721
89721
|
throw new InvalidArgumentError("path must be a string");
|
|
89722
|
-
} else if (
|
|
89722
|
+
} else if (path6[0] !== "/" && !(path6.startsWith("http://") || path6.startsWith("https://")) && method !== "CONNECT") {
|
|
89723
89723
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
89724
|
-
} else if (invalidPathRegex.test(
|
|
89724
|
+
} else if (invalidPathRegex.test(path6)) {
|
|
89725
89725
|
throw new InvalidArgumentError("invalid request path");
|
|
89726
89726
|
}
|
|
89727
89727
|
if (typeof method !== "string") {
|
|
@@ -89796,7 +89796,7 @@ var require_request = __commonJS({
|
|
|
89796
89796
|
this.completed = false;
|
|
89797
89797
|
this.aborted = false;
|
|
89798
89798
|
this.upgrade = upgrade || null;
|
|
89799
|
-
this.path = query ? serializePathWithQuery(
|
|
89799
|
+
this.path = query ? serializePathWithQuery(path6, query) : path6;
|
|
89800
89800
|
this.origin = origin;
|
|
89801
89801
|
this.protocol = getProtocolFromUrlString(origin);
|
|
89802
89802
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -94835,7 +94835,7 @@ var require_client_h1 = __commonJS({
|
|
|
94835
94835
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
94836
94836
|
}
|
|
94837
94837
|
function writeH1(client, request) {
|
|
94838
|
-
const { method, path:
|
|
94838
|
+
const { method, path: path6, host, upgrade, blocking, reset } = request;
|
|
94839
94839
|
let { body: body2, headers, contentLength } = request;
|
|
94840
94840
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
94841
94841
|
if (util2.isFormDataLike(body2)) {
|
|
@@ -94904,7 +94904,7 @@ var require_client_h1 = __commonJS({
|
|
|
94904
94904
|
if (socket.setTypeOfService) {
|
|
94905
94905
|
socket.setTypeOfService(request.typeOfService);
|
|
94906
94906
|
}
|
|
94907
|
-
let header = `${method} ${
|
|
94907
|
+
let header = `${method} ${path6} HTTP/1.1\r
|
|
94908
94908
|
`;
|
|
94909
94909
|
if (typeof host === "string") {
|
|
94910
94910
|
header += `host: ${host}\r
|
|
@@ -95557,7 +95557,7 @@ var require_client_h2 = __commonJS({
|
|
|
95557
95557
|
function writeH2(client, request) {
|
|
95558
95558
|
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
|
|
95559
95559
|
const session = client[kHTTP2Session];
|
|
95560
|
-
const { method, path:
|
|
95560
|
+
const { method, path: path6, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
|
|
95561
95561
|
let { body: body2 } = request;
|
|
95562
95562
|
if (upgrade != null && upgrade !== "websocket") {
|
|
95563
95563
|
util2.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -95625,7 +95625,7 @@ var require_client_h2 = __commonJS({
|
|
|
95625
95625
|
}
|
|
95626
95626
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
95627
95627
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
95628
|
-
headers[HTTP2_HEADER_PATH] =
|
|
95628
|
+
headers[HTTP2_HEADER_PATH] = path6;
|
|
95629
95629
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
95630
95630
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
95631
95631
|
} else {
|
|
@@ -95666,7 +95666,7 @@ var require_client_h2 = __commonJS({
|
|
|
95666
95666
|
stream.setTimeout(requestTimeout);
|
|
95667
95667
|
return true;
|
|
95668
95668
|
}
|
|
95669
|
-
headers[HTTP2_HEADER_PATH] =
|
|
95669
|
+
headers[HTTP2_HEADER_PATH] = path6;
|
|
95670
95670
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
95671
95671
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
95672
95672
|
if (body2 && typeof body2.read === "function") {
|
|
@@ -97968,10 +97968,10 @@ var require_proxy_agent = __commonJS({
|
|
|
97968
97968
|
};
|
|
97969
97969
|
const {
|
|
97970
97970
|
origin,
|
|
97971
|
-
path:
|
|
97971
|
+
path: path6 = "/",
|
|
97972
97972
|
headers = {}
|
|
97973
97973
|
} = opts;
|
|
97974
|
-
opts.path = origin +
|
|
97974
|
+
opts.path = origin + path6;
|
|
97975
97975
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
97976
97976
|
const { host } = new URL(origin);
|
|
97977
97977
|
headers.host = host;
|
|
@@ -100034,20 +100034,20 @@ var require_mock_utils = __commonJS({
|
|
|
100034
100034
|
}
|
|
100035
100035
|
return normalizedQp;
|
|
100036
100036
|
}
|
|
100037
|
-
function safeUrl(
|
|
100038
|
-
if (typeof
|
|
100039
|
-
return
|
|
100037
|
+
function safeUrl(path6) {
|
|
100038
|
+
if (typeof path6 !== "string") {
|
|
100039
|
+
return path6;
|
|
100040
100040
|
}
|
|
100041
|
-
const pathSegments =
|
|
100041
|
+
const pathSegments = path6.split("?", 3);
|
|
100042
100042
|
if (pathSegments.length !== 2) {
|
|
100043
|
-
return
|
|
100043
|
+
return path6;
|
|
100044
100044
|
}
|
|
100045
100045
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
100046
100046
|
qp.sort();
|
|
100047
100047
|
return [...pathSegments, qp.toString()].join("?");
|
|
100048
100048
|
}
|
|
100049
|
-
function matchKey(mockDispatch2, { path:
|
|
100050
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
100049
|
+
function matchKey(mockDispatch2, { path: path6, method, body: body2, headers }) {
|
|
100050
|
+
const pathMatch = matchValue(mockDispatch2.path, path6);
|
|
100051
100051
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
100052
100052
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body2) : true;
|
|
100053
100053
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -100072,8 +100072,8 @@ var require_mock_utils = __commonJS({
|
|
|
100072
100072
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
100073
100073
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
100074
100074
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
100075
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
100076
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
100075
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path6, ignoreTrailingSlash }) => {
|
|
100076
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path6)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path6), resolvedPath);
|
|
100077
100077
|
});
|
|
100078
100078
|
if (matchedMockDispatches.length === 0) {
|
|
100079
100079
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -100112,19 +100112,19 @@ var require_mock_utils = __commonJS({
|
|
|
100112
100112
|
mockDispatches.splice(index2, 1);
|
|
100113
100113
|
}
|
|
100114
100114
|
}
|
|
100115
|
-
function removeTrailingSlash(
|
|
100116
|
-
while (
|
|
100117
|
-
|
|
100115
|
+
function removeTrailingSlash(path6) {
|
|
100116
|
+
while (path6.endsWith("/")) {
|
|
100117
|
+
path6 = path6.slice(0, -1);
|
|
100118
100118
|
}
|
|
100119
|
-
if (
|
|
100120
|
-
|
|
100119
|
+
if (path6.length === 0) {
|
|
100120
|
+
path6 = "/";
|
|
100121
100121
|
}
|
|
100122
|
-
return
|
|
100122
|
+
return path6;
|
|
100123
100123
|
}
|
|
100124
100124
|
function buildKey(opts) {
|
|
100125
|
-
const { path:
|
|
100125
|
+
const { path: path6, method, body: body2, headers, query } = opts;
|
|
100126
100126
|
return {
|
|
100127
|
-
path:
|
|
100127
|
+
path: path6,
|
|
100128
100128
|
method,
|
|
100129
100129
|
body: body2,
|
|
100130
100130
|
headers,
|
|
@@ -100814,10 +100814,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
100814
100814
|
}
|
|
100815
100815
|
format(pendingInterceptors) {
|
|
100816
100816
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
100817
|
-
({ method, path:
|
|
100817
|
+
({ method, path: path6, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
100818
100818
|
Method: method,
|
|
100819
100819
|
Origin: origin,
|
|
100820
|
-
Path:
|
|
100820
|
+
Path: path6,
|
|
100821
100821
|
"Status code": statusCode,
|
|
100822
100822
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
100823
100823
|
Invocations: timesInvoked,
|
|
@@ -100899,9 +100899,9 @@ var require_mock_agent = __commonJS({
|
|
|
100899
100899
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
100900
100900
|
const dispatchOpts = { ...opts };
|
|
100901
100901
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
100902
|
-
const [
|
|
100902
|
+
const [path6, searchParams] = dispatchOpts.path.split("?");
|
|
100903
100903
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
100904
|
-
dispatchOpts.path = `${
|
|
100904
|
+
dispatchOpts.path = `${path6}?${normalizedSearchParams}`;
|
|
100905
100905
|
}
|
|
100906
100906
|
return this[kAgent].dispatch(dispatchOpts, handler2);
|
|
100907
100907
|
}
|
|
@@ -101302,12 +101302,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
101302
101302
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
101303
101303
|
*/
|
|
101304
101304
|
async loadSnapshots(filePath) {
|
|
101305
|
-
const
|
|
101306
|
-
if (!
|
|
101305
|
+
const path6 = filePath || this.#snapshotPath;
|
|
101306
|
+
if (!path6) {
|
|
101307
101307
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
101308
101308
|
}
|
|
101309
101309
|
try {
|
|
101310
|
-
const data = await readFile17(resolve2(
|
|
101310
|
+
const data = await readFile17(resolve2(path6), "utf8");
|
|
101311
101311
|
const parsed = JSON.parse(data);
|
|
101312
101312
|
if (Array.isArray(parsed)) {
|
|
101313
101313
|
this.#snapshots.clear();
|
|
@@ -101321,7 +101321,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
101321
101321
|
if (error48.code === "ENOENT") {
|
|
101322
101322
|
this.#snapshots.clear();
|
|
101323
101323
|
} else {
|
|
101324
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
101324
|
+
throw new UndiciError(`Failed to load snapshots from ${path6}`, { cause: error48 });
|
|
101325
101325
|
}
|
|
101326
101326
|
}
|
|
101327
101327
|
}
|
|
@@ -101332,11 +101332,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
101332
101332
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
101333
101333
|
*/
|
|
101334
101334
|
async saveSnapshots(filePath) {
|
|
101335
|
-
const
|
|
101336
|
-
if (!
|
|
101335
|
+
const path6 = filePath || this.#snapshotPath;
|
|
101336
|
+
if (!path6) {
|
|
101337
101337
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
101338
101338
|
}
|
|
101339
|
-
const resolvedPath = resolve2(
|
|
101339
|
+
const resolvedPath = resolve2(path6);
|
|
101340
101340
|
await mkdir10(dirname13(resolvedPath), { recursive: true });
|
|
101341
101341
|
const data = Array.from(this.#snapshots.entries()).map(([hash3, snapshot]) => ({
|
|
101342
101342
|
hash: hash3,
|
|
@@ -101961,15 +101961,15 @@ var require_redirect_handler = __commonJS({
|
|
|
101961
101961
|
return;
|
|
101962
101962
|
}
|
|
101963
101963
|
const { origin, pathname, search: search2 } = util2.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
101964
|
-
const
|
|
101965
|
-
const redirectUrlString = `${origin}${
|
|
101964
|
+
const path6 = search2 ? `${pathname}${search2}` : pathname;
|
|
101965
|
+
const redirectUrlString = `${origin}${path6}`;
|
|
101966
101966
|
for (const historyUrl of this.history) {
|
|
101967
101967
|
if (historyUrl.toString() === redirectUrlString) {
|
|
101968
101968
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
101969
101969
|
}
|
|
101970
101970
|
}
|
|
101971
101971
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
101972
|
-
this.opts.path =
|
|
101972
|
+
this.opts.path = path6;
|
|
101973
101973
|
this.opts.origin = origin;
|
|
101974
101974
|
this.opts.query = null;
|
|
101975
101975
|
}
|
|
@@ -108176,11 +108176,11 @@ var require_fetch = __commonJS({
|
|
|
108176
108176
|
function dispatch({ body: body2 }) {
|
|
108177
108177
|
const url2 = requestCurrentURL(request);
|
|
108178
108178
|
const agent = fetchParams.controller.dispatcher;
|
|
108179
|
-
const
|
|
108179
|
+
const path6 = url2.pathname + url2.search;
|
|
108180
108180
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
108181
108181
|
return new Promise((resolve2, reject) => agent.dispatch(
|
|
108182
108182
|
{
|
|
108183
|
-
path: hasTrailingQuestionMark ? `${
|
|
108183
|
+
path: hasTrailingQuestionMark ? `${path6}?` : path6,
|
|
108184
108184
|
origin: url2.origin,
|
|
108185
108185
|
method: request.method,
|
|
108186
108186
|
body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body2,
|
|
@@ -109127,9 +109127,9 @@ var require_util6 = __commonJS({
|
|
|
109127
109127
|
}
|
|
109128
109128
|
}
|
|
109129
109129
|
}
|
|
109130
|
-
function validateCookiePath(
|
|
109131
|
-
for (let i2 = 0; i2 <
|
|
109132
|
-
const code =
|
|
109130
|
+
function validateCookiePath(path6) {
|
|
109131
|
+
for (let i2 = 0; i2 < path6.length; ++i2) {
|
|
109132
|
+
const code = path6.charCodeAt(i2);
|
|
109133
109133
|
if (code < 32 || // exclude CTLs (0-31)
|
|
109134
109134
|
code === 127 || // DEL
|
|
109135
109135
|
code === 59) {
|
|
@@ -112299,11 +112299,11 @@ var require_undici = __commonJS({
|
|
|
112299
112299
|
if (typeof opts.path !== "string") {
|
|
112300
112300
|
throw new InvalidArgumentError("invalid opts.path");
|
|
112301
112301
|
}
|
|
112302
|
-
let
|
|
112302
|
+
let path6 = opts.path;
|
|
112303
112303
|
if (!opts.path.startsWith("/")) {
|
|
112304
|
-
|
|
112304
|
+
path6 = `/${path6}`;
|
|
112305
112305
|
}
|
|
112306
|
-
url2 = new URL(util2.parseOrigin(url2).origin +
|
|
112306
|
+
url2 = new URL(util2.parseOrigin(url2).origin + path6);
|
|
112307
112307
|
} else {
|
|
112308
112308
|
if (!opts) {
|
|
112309
112309
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -113187,10 +113187,10 @@ function mergeDefs(...defs) {
|
|
|
113187
113187
|
function cloneDef(schema) {
|
|
113188
113188
|
return mergeDefs(schema._zod.def);
|
|
113189
113189
|
}
|
|
113190
|
-
function getElementAtPath(obj,
|
|
113191
|
-
if (!
|
|
113190
|
+
function getElementAtPath(obj, path6) {
|
|
113191
|
+
if (!path6)
|
|
113192
113192
|
return obj;
|
|
113193
|
-
return
|
|
113193
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
113194
113194
|
}
|
|
113195
113195
|
function promiseAllObject(promisesObj) {
|
|
113196
113196
|
const keys = Object.keys(promisesObj);
|
|
@@ -113573,11 +113573,11 @@ function aborted(x, startIndex = 0) {
|
|
|
113573
113573
|
}
|
|
113574
113574
|
return false;
|
|
113575
113575
|
}
|
|
113576
|
-
function prefixIssues(
|
|
113576
|
+
function prefixIssues(path6, issues) {
|
|
113577
113577
|
return issues.map((iss) => {
|
|
113578
113578
|
var _a2;
|
|
113579
113579
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
113580
|
-
iss.path.unshift(
|
|
113580
|
+
iss.path.unshift(path6);
|
|
113581
113581
|
return iss;
|
|
113582
113582
|
});
|
|
113583
113583
|
}
|
|
@@ -113760,7 +113760,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
113760
113760
|
}
|
|
113761
113761
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
113762
113762
|
const result = { errors: [] };
|
|
113763
|
-
const processError = (error49,
|
|
113763
|
+
const processError = (error49, path6 = []) => {
|
|
113764
113764
|
var _a2, _b;
|
|
113765
113765
|
for (const issue2 of error49.issues) {
|
|
113766
113766
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -113770,7 +113770,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
113770
113770
|
} else if (issue2.code === "invalid_element") {
|
|
113771
113771
|
processError({ issues: issue2.issues }, issue2.path);
|
|
113772
113772
|
} else {
|
|
113773
|
-
const fullpath = [...
|
|
113773
|
+
const fullpath = [...path6, ...issue2.path];
|
|
113774
113774
|
if (fullpath.length === 0) {
|
|
113775
113775
|
result.errors.push(mapper(issue2));
|
|
113776
113776
|
continue;
|
|
@@ -113802,8 +113802,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
113802
113802
|
}
|
|
113803
113803
|
function toDotPath(_path) {
|
|
113804
113804
|
const segs = [];
|
|
113805
|
-
const
|
|
113806
|
-
for (const seg of
|
|
113805
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
113806
|
+
for (const seg of path6) {
|
|
113807
113807
|
if (typeof seg === "number")
|
|
113808
113808
|
segs.push(`[${seg}]`);
|
|
113809
113809
|
else if (typeof seg === "symbol")
|
|
@@ -125780,13 +125780,13 @@ function resolveRef(ref, ctx) {
|
|
|
125780
125780
|
if (!ref.startsWith("#")) {
|
|
125781
125781
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
125782
125782
|
}
|
|
125783
|
-
const
|
|
125784
|
-
if (
|
|
125783
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
125784
|
+
if (path6.length === 0) {
|
|
125785
125785
|
return ctx.rootSchema;
|
|
125786
125786
|
}
|
|
125787
125787
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
125788
|
-
if (
|
|
125789
|
-
const key =
|
|
125788
|
+
if (path6[0] === defsKey) {
|
|
125789
|
+
const key = path6[1];
|
|
125790
125790
|
if (!key || !ctx.defs[key]) {
|
|
125791
125791
|
throw new Error(`Reference not found: ${ref}`);
|
|
125792
125792
|
}
|
|
@@ -126626,26 +126626,26 @@ function applyReplacer(root, replacer) {
|
|
|
126626
126626
|
if (replacedRoot === void 0) return transformChildren(root, replacer, []);
|
|
126627
126627
|
return transformChildren(normalizeValue(replacedRoot), replacer, []);
|
|
126628
126628
|
}
|
|
126629
|
-
function transformChildren(value2, replacer,
|
|
126630
|
-
if (isJsonObject(value2)) return transformObject(value2, replacer,
|
|
126631
|
-
if (isJsonArray(value2)) return transformArray(value2, replacer,
|
|
126629
|
+
function transformChildren(value2, replacer, path6) {
|
|
126630
|
+
if (isJsonObject(value2)) return transformObject(value2, replacer, path6);
|
|
126631
|
+
if (isJsonArray(value2)) return transformArray(value2, replacer, path6);
|
|
126632
126632
|
return value2;
|
|
126633
126633
|
}
|
|
126634
|
-
function transformObject(obj, replacer,
|
|
126634
|
+
function transformObject(obj, replacer, path6) {
|
|
126635
126635
|
const result = {};
|
|
126636
126636
|
for (const [key, value2] of Object.entries(obj)) {
|
|
126637
|
-
const childPath = [...
|
|
126637
|
+
const childPath = [...path6, key];
|
|
126638
126638
|
const replacedValue = replacer(key, value2, childPath);
|
|
126639
126639
|
if (replacedValue === void 0) continue;
|
|
126640
126640
|
result[key] = transformChildren(normalizeValue(replacedValue), replacer, childPath);
|
|
126641
126641
|
}
|
|
126642
126642
|
return result;
|
|
126643
126643
|
}
|
|
126644
|
-
function transformArray(arr, replacer,
|
|
126644
|
+
function transformArray(arr, replacer, path6) {
|
|
126645
126645
|
const result = [];
|
|
126646
126646
|
for (let i2 = 0; i2 < arr.length; i2++) {
|
|
126647
126647
|
const value2 = arr[i2];
|
|
126648
|
-
const childPath = [...
|
|
126648
|
+
const childPath = [...path6, i2];
|
|
126649
126649
|
const replacedValue = replacer(String(i2), value2, childPath);
|
|
126650
126650
|
if (replacedValue === void 0) continue;
|
|
126651
126651
|
const normalizedValue = normalizeValue(replacedValue);
|
|
@@ -126713,33 +126713,33 @@ function columnarTable(items) {
|
|
|
126713
126713
|
const keys = [...new Set(items.flatMap(Object.keys))];
|
|
126714
126714
|
return table(keys, items.map((item) => keys.map((k) => String(item[k] ?? ""))));
|
|
126715
126715
|
}
|
|
126716
|
-
function formatMarkdown(value2,
|
|
126716
|
+
function formatMarkdown(value2, path6 = []) {
|
|
126717
126717
|
if (isScalar(value2)) {
|
|
126718
|
-
if (
|
|
126718
|
+
if (path6.length === 0)
|
|
126719
126719
|
return String(value2);
|
|
126720
|
-
return `## ${
|
|
126720
|
+
return `## ${path6.join(".")}
|
|
126721
126721
|
|
|
126722
126722
|
${String(value2)}`;
|
|
126723
126723
|
}
|
|
126724
126724
|
if (Array.isArray(value2)) {
|
|
126725
126725
|
if (isArrayOfObjects2(value2)) {
|
|
126726
126726
|
const table2 = columnarTable(value2);
|
|
126727
|
-
if (
|
|
126727
|
+
if (path6.length === 0)
|
|
126728
126728
|
return table2;
|
|
126729
|
-
return `## ${
|
|
126729
|
+
return `## ${path6.join(".")}
|
|
126730
126730
|
|
|
126731
126731
|
${table2}`;
|
|
126732
126732
|
}
|
|
126733
|
-
return formatMarkdown(String(value2),
|
|
126733
|
+
return formatMarkdown(String(value2), path6);
|
|
126734
126734
|
}
|
|
126735
126735
|
const obj = value2;
|
|
126736
126736
|
const entries = Object.entries(obj);
|
|
126737
|
-
if (
|
|
126737
|
+
if (path6.length === 0 && isFlat(obj))
|
|
126738
126738
|
return kvTable(obj);
|
|
126739
|
-
const needsHeadings =
|
|
126739
|
+
const needsHeadings = path6.length > 0 || entries.length > 1 || entries.some(([, v]) => !isScalar(v));
|
|
126740
126740
|
if (needsHeadings) {
|
|
126741
126741
|
const sections = entries.map(([key, val]) => {
|
|
126742
|
-
const childPath = [...
|
|
126742
|
+
const childPath = [...path6, key];
|
|
126743
126743
|
if (isScalar(val))
|
|
126744
126744
|
return `## ${childPath.join(".")}
|
|
126745
126745
|
|
|
@@ -127353,8 +127353,8 @@ function getErrorMap2() {
|
|
|
127353
127353
|
|
|
127354
127354
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/parseUtil.js
|
|
127355
127355
|
var makeIssue = (params) => {
|
|
127356
|
-
const { data, path:
|
|
127357
|
-
const fullPath = [...
|
|
127356
|
+
const { data, path: path6, errorMaps, issueData } = params;
|
|
127357
|
+
const fullPath = [...path6, ...issueData.path || []];
|
|
127358
127358
|
const fullIssue = {
|
|
127359
127359
|
...issueData,
|
|
127360
127360
|
path: fullPath
|
|
@@ -127469,11 +127469,11 @@ var errorUtil;
|
|
|
127469
127469
|
|
|
127470
127470
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/types.js
|
|
127471
127471
|
var ParseInputLazyPath = class {
|
|
127472
|
-
constructor(parent, value2,
|
|
127472
|
+
constructor(parent, value2, path6, key) {
|
|
127473
127473
|
this._cachedPath = [];
|
|
127474
127474
|
this.parent = parent;
|
|
127475
127475
|
this.data = value2;
|
|
127476
|
-
this._path =
|
|
127476
|
+
this._path = path6;
|
|
127477
127477
|
this._key = key;
|
|
127478
127478
|
}
|
|
127479
127479
|
get path() {
|
|
@@ -136608,12 +136608,12 @@ function isAsyncGenerator(value2) {
|
|
|
136608
136608
|
function collectTools(commands, prefix) {
|
|
136609
136609
|
const result = [];
|
|
136610
136610
|
for (const [name2, entry] of commands) {
|
|
136611
|
-
const
|
|
136611
|
+
const path6 = [...prefix, name2];
|
|
136612
136612
|
if ("_group" in entry && entry._group)
|
|
136613
|
-
result.push(...collectTools(entry.commands,
|
|
136613
|
+
result.push(...collectTools(entry.commands, path6));
|
|
136614
136614
|
else {
|
|
136615
136615
|
result.push({
|
|
136616
|
-
name:
|
|
136616
|
+
name: path6.join("_"),
|
|
136617
136617
|
description: entry.description,
|
|
136618
136618
|
inputSchema: buildToolSchema(entry.args, entry.options),
|
|
136619
136619
|
command: entry
|
|
@@ -137758,7 +137758,7 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137758
137758
|
exit2(1);
|
|
137759
137759
|
return;
|
|
137760
137760
|
}
|
|
137761
|
-
const { command, path:
|
|
137761
|
+
const { command, path: path6, rest } = effective;
|
|
137762
137762
|
try {
|
|
137763
137763
|
const { args: args2, options: parsedOptions } = parse3(rest, {
|
|
137764
137764
|
alias: command.alias,
|
|
@@ -137784,7 +137784,7 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137784
137784
|
if (isAsyncGenerator2(result)) {
|
|
137785
137785
|
await handleStreaming(result, {
|
|
137786
137786
|
name: name2,
|
|
137787
|
-
path:
|
|
137787
|
+
path: path6,
|
|
137788
137788
|
start: start2,
|
|
137789
137789
|
format: format2,
|
|
137790
137790
|
formatExplicit,
|
|
@@ -137805,7 +137805,7 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137805
137805
|
ok: true,
|
|
137806
137806
|
data: awaited.data,
|
|
137807
137807
|
meta: {
|
|
137808
|
-
command:
|
|
137808
|
+
command: path6,
|
|
137809
137809
|
duration: `${Math.round(performance.now() - start2)}ms`,
|
|
137810
137810
|
...cta ? { cta } : void 0
|
|
137811
137811
|
}
|
|
@@ -137819,7 +137819,7 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137819
137819
|
...awaited.retryable !== void 0 ? { retryable: awaited.retryable } : void 0
|
|
137820
137820
|
},
|
|
137821
137821
|
meta: {
|
|
137822
|
-
command:
|
|
137822
|
+
command: path6,
|
|
137823
137823
|
duration: `${Math.round(performance.now() - start2)}ms`,
|
|
137824
137824
|
...cta ? { cta } : void 0
|
|
137825
137825
|
}
|
|
@@ -137831,7 +137831,7 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137831
137831
|
ok: true,
|
|
137832
137832
|
data: awaited,
|
|
137833
137833
|
meta: {
|
|
137834
|
-
command:
|
|
137834
|
+
command: path6,
|
|
137835
137835
|
duration: `${Math.round(performance.now() - start2)}ms`
|
|
137836
137836
|
}
|
|
137837
137837
|
});
|
|
@@ -137846,12 +137846,12 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137846
137846
|
...error48 instanceof ValidationError ? { fieldErrors: error48.fieldErrors } : void 0
|
|
137847
137847
|
},
|
|
137848
137848
|
meta: {
|
|
137849
|
-
command:
|
|
137849
|
+
command: path6,
|
|
137850
137850
|
duration: `${Math.round(performance.now() - start2)}ms`
|
|
137851
137851
|
}
|
|
137852
137852
|
};
|
|
137853
137853
|
if (human && !formatExplicit && error48 instanceof ValidationError) {
|
|
137854
|
-
writeln(formatHumanValidationError(name2,
|
|
137854
|
+
writeln(formatHumanValidationError(name2, path6, command, error48));
|
|
137855
137855
|
exit2(1);
|
|
137856
137856
|
return;
|
|
137857
137857
|
}
|
|
@@ -137859,13 +137859,13 @@ async function serveImpl(name2, commands, argv, options2 = {}) {
|
|
|
137859
137859
|
exit2(1);
|
|
137860
137860
|
}
|
|
137861
137861
|
}
|
|
137862
|
-
function formatHumanValidationError(cli2,
|
|
137862
|
+
function formatHumanValidationError(cli2, path6, command, error48) {
|
|
137863
137863
|
const lines = [];
|
|
137864
137864
|
for (const fe of error48.fieldErrors)
|
|
137865
137865
|
lines.push(`Error: missing required argument <${fe.path}>`);
|
|
137866
137866
|
lines.push("See below for usage.");
|
|
137867
137867
|
lines.push("");
|
|
137868
|
-
lines.push(formatCommand(
|
|
137868
|
+
lines.push(formatCommand(path6 === cli2 ? cli2 : `${cli2} ${path6}`, {
|
|
137869
137869
|
alias: command.alias,
|
|
137870
137870
|
description: command.description,
|
|
137871
137871
|
args: command.args,
|
|
@@ -137882,7 +137882,7 @@ function resolveCommand(commands, tokens) {
|
|
|
137882
137882
|
if (!first || !commands.has(first))
|
|
137883
137883
|
return { error: first ?? "(none)", path: "" };
|
|
137884
137884
|
let entry = commands.get(first);
|
|
137885
|
-
const
|
|
137885
|
+
const path6 = [first];
|
|
137886
137886
|
let remaining = rest;
|
|
137887
137887
|
let inheritedOutputPolicy;
|
|
137888
137888
|
while (isGroup(entry)) {
|
|
@@ -137892,22 +137892,22 @@ function resolveCommand(commands, tokens) {
|
|
|
137892
137892
|
if (!next)
|
|
137893
137893
|
return {
|
|
137894
137894
|
help: true,
|
|
137895
|
-
path:
|
|
137895
|
+
path: path6.join(" "),
|
|
137896
137896
|
description: entry.description,
|
|
137897
137897
|
commands: entry.commands
|
|
137898
137898
|
};
|
|
137899
137899
|
const child = entry.commands.get(next);
|
|
137900
137900
|
if (!child) {
|
|
137901
|
-
return { error: next, path:
|
|
137901
|
+
return { error: next, path: path6.join(" ") };
|
|
137902
137902
|
}
|
|
137903
|
-
|
|
137903
|
+
path6.push(next);
|
|
137904
137904
|
remaining = remaining.slice(1);
|
|
137905
137905
|
entry = child;
|
|
137906
137906
|
}
|
|
137907
137907
|
const outputPolicy = entry.outputPolicy ?? inheritedOutputPolicy;
|
|
137908
137908
|
return {
|
|
137909
137909
|
command: entry,
|
|
137910
|
-
path:
|
|
137910
|
+
path: path6.join(" "),
|
|
137911
137911
|
rest: remaining,
|
|
137912
137912
|
...outputPolicy ? { outputPolicy } : void 0
|
|
137913
137913
|
};
|
|
@@ -138172,11 +138172,11 @@ function buildManifest(commands, prefix = []) {
|
|
|
138172
138172
|
function collectCommands(commands, prefix) {
|
|
138173
138173
|
const result = [];
|
|
138174
138174
|
for (const [name2, entry] of commands) {
|
|
138175
|
-
const
|
|
138175
|
+
const path6 = [...prefix, name2];
|
|
138176
138176
|
if (isGroup(entry)) {
|
|
138177
|
-
result.push(...collectCommands(entry.commands,
|
|
138177
|
+
result.push(...collectCommands(entry.commands, path6));
|
|
138178
138178
|
} else {
|
|
138179
|
-
const cmd = { name:
|
|
138179
|
+
const cmd = { name: path6.join(" ") };
|
|
138180
138180
|
if (entry.description)
|
|
138181
138181
|
cmd.description = entry.description;
|
|
138182
138182
|
const inputSchema = buildInputSchema(entry.args, entry.env, entry.options);
|
|
@@ -138194,7 +138194,7 @@ function collectCommands(commands, prefix) {
|
|
|
138194
138194
|
}
|
|
138195
138195
|
const examples = formatExamples(entry.examples);
|
|
138196
138196
|
if (examples) {
|
|
138197
|
-
const cmdName =
|
|
138197
|
+
const cmdName = path6.join(" ");
|
|
138198
138198
|
cmd.examples = examples.map((e) => ({
|
|
138199
138199
|
...e,
|
|
138200
138200
|
command: e.command ? `${cmdName} ${e.command}` : cmdName
|
|
@@ -138208,13 +138208,13 @@ function collectCommands(commands, prefix) {
|
|
|
138208
138208
|
function collectSkillCommands(commands, prefix, groups) {
|
|
138209
138209
|
const result = [];
|
|
138210
138210
|
for (const [name2, entry] of commands) {
|
|
138211
|
-
const
|
|
138211
|
+
const path6 = [...prefix, name2];
|
|
138212
138212
|
if (isGroup(entry)) {
|
|
138213
138213
|
if (entry.description)
|
|
138214
|
-
groups.set(
|
|
138215
|
-
result.push(...collectSkillCommands(entry.commands,
|
|
138214
|
+
groups.set(path6.join(" "), entry.description);
|
|
138215
|
+
result.push(...collectSkillCommands(entry.commands, path6, groups));
|
|
138216
138216
|
} else {
|
|
138217
|
-
const cmd = { name:
|
|
138217
|
+
const cmd = { name: path6.join(" ") };
|
|
138218
138218
|
if (entry.description)
|
|
138219
138219
|
cmd.description = entry.description;
|
|
138220
138220
|
if (entry.args)
|
|
@@ -138229,7 +138229,7 @@ function collectSkillCommands(commands, prefix, groups) {
|
|
|
138229
138229
|
cmd.output = entry.output;
|
|
138230
138230
|
const examples = formatExamples(entry.examples);
|
|
138231
138231
|
if (examples) {
|
|
138232
|
-
const cmdName =
|
|
138232
|
+
const cmdName = path6.join(" ");
|
|
138233
138233
|
cmd.examples = examples.map((e) => ({
|
|
138234
138234
|
...e,
|
|
138235
138235
|
command: e.command ? `${cmdName} ${e.command}` : cmdName
|
|
@@ -138273,7 +138273,7 @@ function buildInputSchema(args2, env2, options2) {
|
|
|
138273
138273
|
// package.json
|
|
138274
138274
|
var package_default = {
|
|
138275
138275
|
name: "@docyrus/docyrus",
|
|
138276
|
-
version: "0.0.
|
|
138276
|
+
version: "0.0.45",
|
|
138277
138277
|
private: false,
|
|
138278
138278
|
description: "Docyrus API CLI",
|
|
138279
138279
|
main: "./main.js",
|
|
@@ -138731,7 +138731,7 @@ function createConnectCli(dependencies) {
|
|
|
138731
138731
|
const apiClient = dependencies.createApiClient(apiBaseUrl);
|
|
138732
138732
|
const { appSlug, actionKey } = context.args;
|
|
138733
138733
|
const body2 = context.options.params ? parseJsonParams(context.options.params) : {};
|
|
138734
|
-
const
|
|
138734
|
+
const path6 = `/v1/apps/${encodeURIComponent(appSlug)}/actions/${encodeURIComponent(actionKey)}/run`;
|
|
138735
138735
|
const headers = {};
|
|
138736
138736
|
if (context.options.connectionId) {
|
|
138737
138737
|
headers["x-connection-id"] = context.options.connectionId;
|
|
@@ -138746,7 +138746,7 @@ function createConnectCli(dependencies) {
|
|
|
138746
138746
|
payload: {
|
|
138747
138747
|
dryRun: true,
|
|
138748
138748
|
method: "POST",
|
|
138749
|
-
path:
|
|
138749
|
+
path: path6,
|
|
138750
138750
|
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
138751
138751
|
body: body2
|
|
138752
138752
|
}
|
|
@@ -138754,7 +138754,7 @@ function createConnectCli(dependencies) {
|
|
|
138754
138754
|
}
|
|
138755
138755
|
const response = await apiClient.request({
|
|
138756
138756
|
method: "POST",
|
|
138757
|
-
path:
|
|
138757
|
+
path: path6,
|
|
138758
138758
|
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
138759
138759
|
body: body2
|
|
138760
138760
|
});
|
|
@@ -138918,10 +138918,10 @@ function createAiCli(dependencies) {
|
|
|
138918
138918
|
const deploymentId = context.options.deploymentId?.trim() || void 0;
|
|
138919
138919
|
const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
|
|
138920
138920
|
const apiClient = dependencies.createApiClient(apiBaseUrl);
|
|
138921
|
-
const
|
|
138921
|
+
const path6 = deploymentId ? `/ai/agents/${agentId}/deployments/${deploymentId}/chat` : `/ai/agents/${agentId}/chat`;
|
|
138922
138922
|
const response = await apiClient.request({
|
|
138923
138923
|
method: "POST",
|
|
138924
|
-
path:
|
|
138924
|
+
path: path6,
|
|
138925
138925
|
body: {
|
|
138926
138926
|
messages: [
|
|
138927
138927
|
{
|
|
@@ -139901,7 +139901,7 @@ async function readDataInput(params) {
|
|
|
139901
139901
|
data,
|
|
139902
139902
|
fromFile,
|
|
139903
139903
|
readStdin: readStdin2 = readStdinText,
|
|
139904
|
-
readFileFn = async (
|
|
139904
|
+
readFileFn = async (path6, encoding) => await (0, import_promises2.readFile)(path6, encoding)
|
|
139905
139905
|
} = params;
|
|
139906
139906
|
const trimmedData = data?.trim();
|
|
139907
139907
|
const trimmedFromFile = fromFile?.trim();
|
|
@@ -140598,8 +140598,8 @@ function getEntities(document4) {
|
|
|
140598
140598
|
}
|
|
140599
140599
|
function extractNamespaces(paths) {
|
|
140600
140600
|
const namespaces = /* @__PURE__ */ new Set();
|
|
140601
|
-
for (const
|
|
140602
|
-
const segments =
|
|
140601
|
+
for (const path6 of Object.keys(paths)) {
|
|
140602
|
+
const segments = path6.split("/").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
140603
140603
|
if (segments.length === 0) {
|
|
140604
140604
|
continue;
|
|
140605
140605
|
}
|
|
@@ -140621,8 +140621,8 @@ function getPathOperation(pathItem, method) {
|
|
|
140621
140621
|
function toEndpointMethodEntries(paths, pathFilter) {
|
|
140622
140622
|
const entries = [];
|
|
140623
140623
|
const sortedPaths = Object.keys(paths).filter(pathFilter).sort((left, right) => left.localeCompare(right));
|
|
140624
|
-
for (const
|
|
140625
|
-
const pathItem = paths[
|
|
140624
|
+
for (const path6 of sortedPaths) {
|
|
140625
|
+
const pathItem = paths[path6];
|
|
140626
140626
|
if (!isRecord2(pathItem)) {
|
|
140627
140627
|
continue;
|
|
140628
140628
|
}
|
|
@@ -140635,7 +140635,7 @@ function toEndpointMethodEntries(paths, pathFilter) {
|
|
|
140635
140635
|
const summaryValue = operation.summary;
|
|
140636
140636
|
const description = typeof descriptionValue === "string" ? descriptionValue : typeof summaryValue === "string" ? summaryValue : void 0;
|
|
140637
140637
|
entries.push({
|
|
140638
|
-
path: toOutputPath(
|
|
140638
|
+
path: toOutputPath(path6),
|
|
140639
140639
|
method,
|
|
140640
140640
|
description
|
|
140641
140641
|
});
|
|
@@ -140761,7 +140761,7 @@ function createDiscoverCli(dependencies) {
|
|
|
140761
140761
|
const candidates = buildPathCandidates(context.args.prefix);
|
|
140762
140762
|
const endpoints = toEndpointMethodEntries(
|
|
140763
140763
|
paths,
|
|
140764
|
-
(
|
|
140764
|
+
(path6) => candidates.some((candidate) => path6.startsWith(candidate))
|
|
140765
140765
|
);
|
|
140766
140766
|
return await injectContext({
|
|
140767
140767
|
apiBaseUrl,
|
|
@@ -140858,7 +140858,7 @@ function createDiscoverCli(dependencies) {
|
|
|
140858
140858
|
const loweredTerm = term.toLowerCase();
|
|
140859
140859
|
const matchingEndpoints = toEndpointMethodEntries(
|
|
140860
140860
|
pathMap,
|
|
140861
|
-
(
|
|
140861
|
+
(path6) => path6.toLowerCase().includes(loweredTerm)
|
|
140862
140862
|
);
|
|
140863
140863
|
const matchingEntities = entityNames.filter((entityName) => entityName.toLowerCase().includes(loweredTerm));
|
|
140864
140864
|
return {
|
|
@@ -143227,11 +143227,11 @@ var Module2 = (() => {
|
|
|
143227
143227
|
throw toThrow;
|
|
143228
143228
|
}, "quit_");
|
|
143229
143229
|
var scriptDirectory = "";
|
|
143230
|
-
function locateFile(
|
|
143230
|
+
function locateFile(path6) {
|
|
143231
143231
|
if (Module["locateFile"]) {
|
|
143232
|
-
return Module["locateFile"](
|
|
143232
|
+
return Module["locateFile"](path6, scriptDirectory);
|
|
143233
143233
|
}
|
|
143234
|
-
return scriptDirectory +
|
|
143234
|
+
return scriptDirectory + path6;
|
|
143235
143235
|
}
|
|
143236
143236
|
__name(locateFile, "locateFile");
|
|
143237
143237
|
var readAsync, readBinary;
|
|
@@ -146388,6 +146388,23 @@ function normalizeDeploymentName(params) {
|
|
|
146388
146388
|
return params.defaultModel;
|
|
146389
146389
|
}
|
|
146390
146390
|
async function resolveKnowledgeProviderFromAgentRuntime(params) {
|
|
146391
|
+
if (params.docyrusApi) {
|
|
146392
|
+
const { apiBaseUrl, accessToken } = params.docyrusApi;
|
|
146393
|
+
const gatewayBase = apiBaseUrl.replace(/\/+$/u, "") + "/ai/gateway";
|
|
146394
|
+
return {
|
|
146395
|
+
provider: {
|
|
146396
|
+
providerId: "docyrus-api",
|
|
146397
|
+
apiBase: gatewayBase,
|
|
146398
|
+
model: DEFAULT_EMBEDDING_MODEL,
|
|
146399
|
+
dimensions: DEFAULT_DIMENSIONS,
|
|
146400
|
+
key: accessToken,
|
|
146401
|
+
headers: (key) => ({
|
|
146402
|
+
Authorization: `Bearer ${key}`,
|
|
146403
|
+
"Content-Type": "application/json"
|
|
146404
|
+
})
|
|
146405
|
+
}
|
|
146406
|
+
};
|
|
146407
|
+
}
|
|
146391
146408
|
const agentRootPath = resolveDocyrusPiAgentRootPath(params.settingsRootPath);
|
|
146392
146409
|
const authState = readJsonFile((0, import_node_path14.join)(agentRootPath, "auth.json")) || {};
|
|
146393
146410
|
const envStore = new AgentEnvStore((0, import_node_path14.join)(agentRootPath, "env.json"));
|
|
@@ -146704,9 +146721,9 @@ function shouldUseKnowledgeColors() {
|
|
|
146704
146721
|
}
|
|
146705
146722
|
|
|
146706
146723
|
// src/knowledge/init.ts
|
|
146707
|
-
var
|
|
146708
|
-
var
|
|
146709
|
-
var
|
|
146724
|
+
var import_node_fs8 = require("node:fs");
|
|
146725
|
+
var import_promises12 = require("node:fs/promises");
|
|
146726
|
+
var import_node_path16 = require("node:path");
|
|
146710
146727
|
init_graph();
|
|
146711
146728
|
|
|
146712
146729
|
// src/knowledge/bootstrap.ts
|
|
@@ -147118,754 +147135,6 @@ async function generateInitialKnowledge(params) {
|
|
|
147118
147135
|
};
|
|
147119
147136
|
}
|
|
147120
147137
|
|
|
147121
|
-
// src/project-plan/graph.ts
|
|
147122
|
-
var import_node_crypto5 = require("node:crypto");
|
|
147123
|
-
var import_node_fs9 = require("node:fs");
|
|
147124
|
-
var import_promises13 = __toESM(require("node:fs/promises"));
|
|
147125
|
-
var import_node_path17 = __toESM(require("node:path"));
|
|
147126
|
-
init_graph();
|
|
147127
|
-
|
|
147128
|
-
// src/project-plan/localTodos.ts
|
|
147129
|
-
var import_node_crypto4 = __toESM(require("node:crypto"));
|
|
147130
|
-
var import_node_fs8 = require("node:fs");
|
|
147131
|
-
var import_promises12 = __toESM(require("node:fs/promises"));
|
|
147132
|
-
var import_node_path16 = __toESM(require("node:path"));
|
|
147133
|
-
var TODO_DIR_NAME = ".pi/todos";
|
|
147134
|
-
var TODO_PATH_ENV = "PI_TODO_PATH";
|
|
147135
|
-
function resolveTodosDirectory(root) {
|
|
147136
|
-
const overridePath = process.env[TODO_PATH_ENV]?.trim();
|
|
147137
|
-
if (overridePath) {
|
|
147138
|
-
return import_node_path16.default.resolve(root, overridePath);
|
|
147139
|
-
}
|
|
147140
|
-
return import_node_path16.default.resolve(root, TODO_DIR_NAME);
|
|
147141
|
-
}
|
|
147142
|
-
function getTodoFilePath(todosDir, id) {
|
|
147143
|
-
return import_node_path16.default.join(todosDir, `${id}.md`);
|
|
147144
|
-
}
|
|
147145
|
-
function splitFrontMatter(content3) {
|
|
147146
|
-
if (!content3.startsWith("{")) {
|
|
147147
|
-
return {
|
|
147148
|
-
frontMatter: "",
|
|
147149
|
-
body: content3
|
|
147150
|
-
};
|
|
147151
|
-
}
|
|
147152
|
-
let depth = 0;
|
|
147153
|
-
let inString = false;
|
|
147154
|
-
let escaped = false;
|
|
147155
|
-
let endIndex = -1;
|
|
147156
|
-
for (let index2 = 0; index2 < content3.length; index2 += 1) {
|
|
147157
|
-
const char = content3[index2];
|
|
147158
|
-
if (inString) {
|
|
147159
|
-
if (escaped) {
|
|
147160
|
-
escaped = false;
|
|
147161
|
-
continue;
|
|
147162
|
-
}
|
|
147163
|
-
if (char === "\\") {
|
|
147164
|
-
escaped = true;
|
|
147165
|
-
continue;
|
|
147166
|
-
}
|
|
147167
|
-
if (char === '"') {
|
|
147168
|
-
inString = false;
|
|
147169
|
-
}
|
|
147170
|
-
continue;
|
|
147171
|
-
}
|
|
147172
|
-
if (char === '"') {
|
|
147173
|
-
inString = true;
|
|
147174
|
-
continue;
|
|
147175
|
-
}
|
|
147176
|
-
if (char === "{") {
|
|
147177
|
-
depth += 1;
|
|
147178
|
-
continue;
|
|
147179
|
-
}
|
|
147180
|
-
if (char === "}") {
|
|
147181
|
-
depth -= 1;
|
|
147182
|
-
if (depth === 0) {
|
|
147183
|
-
endIndex = index2;
|
|
147184
|
-
break;
|
|
147185
|
-
}
|
|
147186
|
-
}
|
|
147187
|
-
}
|
|
147188
|
-
if (endIndex === -1) {
|
|
147189
|
-
return {
|
|
147190
|
-
frontMatter: "",
|
|
147191
|
-
body: content3
|
|
147192
|
-
};
|
|
147193
|
-
}
|
|
147194
|
-
return {
|
|
147195
|
-
frontMatter: content3.slice(0, endIndex + 1),
|
|
147196
|
-
body: content3.slice(endIndex + 1).replace(/^\r?\n+/u, "")
|
|
147197
|
-
};
|
|
147198
|
-
}
|
|
147199
|
-
function parseLocalTodoFrontMatter(frontMatter, idFallback) {
|
|
147200
|
-
const base = {
|
|
147201
|
-
id: idFallback,
|
|
147202
|
-
title: "",
|
|
147203
|
-
tags: [],
|
|
147204
|
-
status: "open",
|
|
147205
|
-
created_at: ""
|
|
147206
|
-
};
|
|
147207
|
-
if (!frontMatter.trim()) {
|
|
147208
|
-
return base;
|
|
147209
|
-
}
|
|
147210
|
-
try {
|
|
147211
|
-
const parsed = JSON.parse(frontMatter);
|
|
147212
|
-
return {
|
|
147213
|
-
id: typeof parsed.id === "string" && parsed.id.trim() ? parsed.id.trim() : idFallback,
|
|
147214
|
-
title: typeof parsed.title === "string" ? parsed.title : "",
|
|
147215
|
-
tags: Array.isArray(parsed.tags) ? parsed.tags.filter((value2) => typeof value2 === "string") : [],
|
|
147216
|
-
status: typeof parsed.status === "string" && parsed.status.trim() ? parsed.status.trim() : "open",
|
|
147217
|
-
created_at: typeof parsed.created_at === "string" ? parsed.created_at : "",
|
|
147218
|
-
assigned_to_session: typeof parsed.assigned_to_session === "string" && parsed.assigned_to_session.trim() ? parsed.assigned_to_session.trim() : void 0,
|
|
147219
|
-
parent_task_id: typeof parsed.parent_task_id === "string" && parsed.parent_task_id.trim() ? parsed.parent_task_id.trim() : void 0
|
|
147220
|
-
};
|
|
147221
|
-
} catch {
|
|
147222
|
-
return base;
|
|
147223
|
-
}
|
|
147224
|
-
}
|
|
147225
|
-
function serializeLocalTodo(record2) {
|
|
147226
|
-
const frontMatter = JSON.stringify(
|
|
147227
|
-
{
|
|
147228
|
-
id: record2.id,
|
|
147229
|
-
title: record2.title,
|
|
147230
|
-
tags: record2.tags,
|
|
147231
|
-
status: record2.status,
|
|
147232
|
-
created_at: record2.created_at,
|
|
147233
|
-
assigned_to_session: record2.assigned_to_session || void 0,
|
|
147234
|
-
parent_task_id: record2.parent_task_id || void 0
|
|
147235
|
-
},
|
|
147236
|
-
null,
|
|
147237
|
-
2
|
|
147238
|
-
);
|
|
147239
|
-
const trimmedBody = record2.body.trim();
|
|
147240
|
-
return trimmedBody ? `${frontMatter}
|
|
147241
|
-
|
|
147242
|
-
${trimmedBody}
|
|
147243
|
-
` : `${frontMatter}
|
|
147244
|
-
`;
|
|
147245
|
-
}
|
|
147246
|
-
async function generateTodoId(todosDir) {
|
|
147247
|
-
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
147248
|
-
const id = import_node_crypto4.default.randomBytes(4).toString("hex");
|
|
147249
|
-
if (!(0, import_node_fs8.existsSync)(getTodoFilePath(todosDir, id))) {
|
|
147250
|
-
return id;
|
|
147251
|
-
}
|
|
147252
|
-
}
|
|
147253
|
-
throw new Error("Failed to generate linked todo id.");
|
|
147254
|
-
}
|
|
147255
|
-
async function listLinkedTodosByTask(root) {
|
|
147256
|
-
const todosDir = resolveTodosDirectory(root);
|
|
147257
|
-
const result = /* @__PURE__ */ new Map();
|
|
147258
|
-
let entries = [];
|
|
147259
|
-
try {
|
|
147260
|
-
entries = await import_promises12.default.readdir(todosDir);
|
|
147261
|
-
} catch {
|
|
147262
|
-
return result;
|
|
147263
|
-
}
|
|
147264
|
-
for (const entry of entries) {
|
|
147265
|
-
if (!entry.endsWith(".md")) {
|
|
147266
|
-
continue;
|
|
147267
|
-
}
|
|
147268
|
-
const id = entry.slice(0, -3);
|
|
147269
|
-
const filePath = getTodoFilePath(todosDir, id);
|
|
147270
|
-
try {
|
|
147271
|
-
const raw = await import_promises12.default.readFile(filePath, "utf8");
|
|
147272
|
-
const { frontMatter } = splitFrontMatter(raw);
|
|
147273
|
-
const parsed = parseLocalTodoFrontMatter(frontMatter, id);
|
|
147274
|
-
if (!parsed.parent_task_id) {
|
|
147275
|
-
continue;
|
|
147276
|
-
}
|
|
147277
|
-
const existing = result.get(parsed.parent_task_id) || [];
|
|
147278
|
-
existing.push({
|
|
147279
|
-
id,
|
|
147280
|
-
title: parsed.title,
|
|
147281
|
-
status: parsed.status,
|
|
147282
|
-
filePath: import_node_path16.default.relative(root, filePath),
|
|
147283
|
-
parentTaskId: parsed.parent_task_id
|
|
147284
|
-
});
|
|
147285
|
-
result.set(parsed.parent_task_id, existing);
|
|
147286
|
-
} catch {
|
|
147287
|
-
}
|
|
147288
|
-
}
|
|
147289
|
-
for (const linkedTodos of result.values()) {
|
|
147290
|
-
linkedTodos.sort((left, right) => left.title.localeCompare(right.title) || left.id.localeCompare(right.id));
|
|
147291
|
-
}
|
|
147292
|
-
return result;
|
|
147293
|
-
}
|
|
147294
|
-
async function createLinkedTodo(params) {
|
|
147295
|
-
const todosDir = resolveTodosDirectory(params.root);
|
|
147296
|
-
await import_promises12.default.mkdir(todosDir, {
|
|
147297
|
-
recursive: true
|
|
147298
|
-
});
|
|
147299
|
-
const id = await generateTodoId(todosDir);
|
|
147300
|
-
const filePath = getTodoFilePath(todosDir, id);
|
|
147301
|
-
const todo = {
|
|
147302
|
-
id,
|
|
147303
|
-
title: params.title,
|
|
147304
|
-
tags: [],
|
|
147305
|
-
status: "open",
|
|
147306
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
147307
|
-
parent_task_id: params.parentTaskId,
|
|
147308
|
-
body: params.body ?? ""
|
|
147309
|
-
};
|
|
147310
|
-
await import_promises12.default.writeFile(filePath, serializeLocalTodo(todo), "utf8");
|
|
147311
|
-
return {
|
|
147312
|
-
id,
|
|
147313
|
-
title: todo.title,
|
|
147314
|
-
status: todo.status,
|
|
147315
|
-
filePath: import_node_path16.default.relative(params.root, filePath),
|
|
147316
|
-
parentTaskId: params.parentTaskId
|
|
147317
|
-
};
|
|
147318
|
-
}
|
|
147319
|
-
|
|
147320
|
-
// src/project-plan/types.ts
|
|
147321
|
-
var PROJECT_TASK_TYPES = [
|
|
147322
|
-
"bug-fix",
|
|
147323
|
-
"new-implementation",
|
|
147324
|
-
"api-test",
|
|
147325
|
-
"browser-automation-test",
|
|
147326
|
-
"work"
|
|
147327
|
-
];
|
|
147328
|
-
var PROJECT_TASK_ASSIGNEES = [
|
|
147329
|
-
"agent",
|
|
147330
|
-
"user"
|
|
147331
|
-
];
|
|
147332
|
-
var PROJECT_TASK_STATUSES = [
|
|
147333
|
-
"planned",
|
|
147334
|
-
"in_progress",
|
|
147335
|
-
"blocked",
|
|
147336
|
-
"done"
|
|
147337
|
-
];
|
|
147338
|
-
|
|
147339
|
-
// src/project-plan/graph.ts
|
|
147340
|
-
var PROJECT_PLAN_DIR_SEGMENTS = ["docyrus", "project-plan"];
|
|
147341
|
-
var PROJECT_PLAN_JSON_FILE_NAME = "project-plan.json";
|
|
147342
|
-
var PROJECT_PLAN_MARKDOWN_FILE_NAME = "PROJECT_PLAN.md";
|
|
147343
|
-
var DEFAULT_ROUTE_TARGETS = {
|
|
147344
|
-
features: {
|
|
147345
|
-
heading: "Features",
|
|
147346
|
-
filePathSuffix: "docyrus/knowledge/features/features.md"
|
|
147347
|
-
},
|
|
147348
|
-
testing: {
|
|
147349
|
-
heading: "Testing",
|
|
147350
|
-
filePathSuffix: "docyrus/knowledge/testing/testing.md"
|
|
147351
|
-
},
|
|
147352
|
-
architecture: {
|
|
147353
|
-
heading: "Architecture",
|
|
147354
|
-
filePathSuffix: "docyrus/knowledge/architecture/architecture.md"
|
|
147355
|
-
},
|
|
147356
|
-
workflows: {
|
|
147357
|
-
heading: "Workflows",
|
|
147358
|
-
filePathSuffix: "docyrus/knowledge/workflows/workflows.md"
|
|
147359
|
-
}
|
|
147360
|
-
};
|
|
147361
|
-
function isRecord3(value2) {
|
|
147362
|
-
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
147363
|
-
}
|
|
147364
|
-
function isNonEmptyString(value2) {
|
|
147365
|
-
return typeof value2 === "string" && value2.trim().length > 0;
|
|
147366
|
-
}
|
|
147367
|
-
function normalizeStringArray(value2) {
|
|
147368
|
-
if (!Array.isArray(value2)) {
|
|
147369
|
-
return [];
|
|
147370
|
-
}
|
|
147371
|
-
return value2.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
147372
|
-
}
|
|
147373
|
-
function slugify2(value2) {
|
|
147374
|
-
const slug = value2.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 80);
|
|
147375
|
-
return slug || "item";
|
|
147376
|
-
}
|
|
147377
|
-
function hashParts(parts2) {
|
|
147378
|
-
return (0, import_node_crypto5.createHash)("sha1").update(parts2.join("::")).digest("hex").slice(0, 12);
|
|
147379
|
-
}
|
|
147380
|
-
function normalizeFeatureId(sectionId, slug) {
|
|
147381
|
-
return `feature-${hashParts([sectionId, slug])}`;
|
|
147382
|
-
}
|
|
147383
|
-
function normalizeTaskId(featureId, type, title) {
|
|
147384
|
-
return `task-${hashParts([featureId, type, slugify2(title)])}`;
|
|
147385
|
-
}
|
|
147386
|
-
function compareStrings(left, right) {
|
|
147387
|
-
return left.localeCompare(right);
|
|
147388
|
-
}
|
|
147389
|
-
function sortGraph(graph) {
|
|
147390
|
-
return {
|
|
147391
|
-
version: 1,
|
|
147392
|
-
sections: [...graph.sections].sort((left, right) => compareStrings(left.sectionId, right.sectionId)),
|
|
147393
|
-
features: [...graph.features].sort((left, right) => {
|
|
147394
|
-
return compareStrings(left.sectionId, right.sectionId) || compareStrings(left.title, right.title) || compareStrings(left.id, right.id);
|
|
147395
|
-
}),
|
|
147396
|
-
tasks: [...graph.tasks].sort((left, right) => {
|
|
147397
|
-
return compareStrings(left.sectionId, right.sectionId) || compareStrings(left.featureId, right.featureId) || compareStrings(left.title, right.title) || compareStrings(left.id, right.id);
|
|
147398
|
-
})
|
|
147399
|
-
};
|
|
147400
|
-
}
|
|
147401
|
-
function resolveProjectPlanDirectory(root) {
|
|
147402
|
-
return import_node_path17.default.join(root, ...PROJECT_PLAN_DIR_SEGMENTS);
|
|
147403
|
-
}
|
|
147404
|
-
function resolveProjectPlanGraphPath(root) {
|
|
147405
|
-
return import_node_path17.default.join(resolveProjectPlanDirectory(root), PROJECT_PLAN_JSON_FILE_NAME);
|
|
147406
|
-
}
|
|
147407
|
-
function resolveProjectPlanMarkdownPath(root) {
|
|
147408
|
-
return import_node_path17.default.join(resolveProjectPlanDirectory(root), PROJECT_PLAN_MARKDOWN_FILE_NAME);
|
|
147409
|
-
}
|
|
147410
|
-
function createEmptyProjectPlanGraph() {
|
|
147411
|
-
return {
|
|
147412
|
-
version: 1,
|
|
147413
|
-
sections: [],
|
|
147414
|
-
features: [],
|
|
147415
|
-
tasks: []
|
|
147416
|
-
};
|
|
147417
|
-
}
|
|
147418
|
-
async function readKnowledgeSections(root) {
|
|
147419
|
-
const knowledgeDir = import_node_path17.default.join(root, "docyrus", "knowledge");
|
|
147420
|
-
if (!(0, import_node_fs9.existsSync)(knowledgeDir)) {
|
|
147421
|
-
return [];
|
|
147422
|
-
}
|
|
147423
|
-
return flattenSections(await loadAllSections(knowledgeDir));
|
|
147424
|
-
}
|
|
147425
|
-
function parseProjectPlanGraph(rawValue) {
|
|
147426
|
-
if (!isRecord3(rawValue)) {
|
|
147427
|
-
return createEmptyProjectPlanGraph();
|
|
147428
|
-
}
|
|
147429
|
-
const sections = Array.isArray(rawValue.sections) ? rawValue.sections.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
147430
|
-
sectionId: isNonEmptyString(value2.sectionId) ? value2.sectionId.trim() : ""
|
|
147431
|
-
})).filter((value2) => value2.sectionId.length > 0) : [];
|
|
147432
|
-
const features = Array.isArray(rawValue.features) ? rawValue.features.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
147433
|
-
id: isNonEmptyString(value2.id) ? value2.id.trim() : "",
|
|
147434
|
-
title: isNonEmptyString(value2.title) ? value2.title.trim() : "",
|
|
147435
|
-
slug: isNonEmptyString(value2.slug) ? value2.slug.trim() : "",
|
|
147436
|
-
summary: typeof value2.summary === "string" ? value2.summary.trim() : "",
|
|
147437
|
-
sectionId: isNonEmptyString(value2.sectionId) ? value2.sectionId.trim() : ""
|
|
147438
|
-
})).filter((value2) => value2.id.length > 0) : [];
|
|
147439
|
-
const tasks = Array.isArray(rawValue.tasks) ? rawValue.tasks.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
147440
|
-
id: isNonEmptyString(value2.id) ? value2.id.trim() : "",
|
|
147441
|
-
title: isNonEmptyString(value2.title) ? value2.title.trim() : "",
|
|
147442
|
-
summary: typeof value2.summary === "string" ? value2.summary.trim() : "",
|
|
147443
|
-
type: typeof value2.type === "string" ? value2.type : "work",
|
|
147444
|
-
assignee: typeof value2.assignee === "string" ? value2.assignee : "agent",
|
|
147445
|
-
status: typeof value2.status === "string" ? value2.status : "planned",
|
|
147446
|
-
acceptanceCriteria: normalizeStringArray(value2.acceptanceCriteria),
|
|
147447
|
-
featureId: isNonEmptyString(value2.featureId) ? value2.featureId.trim() : "",
|
|
147448
|
-
sectionId: isNonEmptyString(value2.sectionId) ? value2.sectionId.trim() : ""
|
|
147449
|
-
})).filter((value2) => value2.id.length > 0) : [];
|
|
147450
|
-
return sortGraph({
|
|
147451
|
-
version: 1,
|
|
147452
|
-
sections,
|
|
147453
|
-
features,
|
|
147454
|
-
tasks
|
|
147455
|
-
});
|
|
147456
|
-
}
|
|
147457
|
-
async function readProjectPlanGraph(root) {
|
|
147458
|
-
const graphPath = resolveProjectPlanGraphPath(root);
|
|
147459
|
-
if (!(0, import_node_fs9.existsSync)(graphPath)) {
|
|
147460
|
-
return createEmptyProjectPlanGraph();
|
|
147461
|
-
}
|
|
147462
|
-
const raw = await import_promises13.default.readFile(graphPath, "utf8");
|
|
147463
|
-
return parseProjectPlanGraph(JSON.parse(raw));
|
|
147464
|
-
}
|
|
147465
|
-
function deriveFeatureStatus(tasks) {
|
|
147466
|
-
if (tasks.length === 0) {
|
|
147467
|
-
return "planned";
|
|
147468
|
-
}
|
|
147469
|
-
if (tasks.every((task) => task.status === "done")) {
|
|
147470
|
-
return "done";
|
|
147471
|
-
}
|
|
147472
|
-
if (tasks.some((task) => task.status === "in_progress")) {
|
|
147473
|
-
return "in_progress";
|
|
147474
|
-
}
|
|
147475
|
-
if (tasks.some((task) => task.status === "blocked")) {
|
|
147476
|
-
return "blocked";
|
|
147477
|
-
}
|
|
147478
|
-
return "planned";
|
|
147479
|
-
}
|
|
147480
|
-
function deriveSectionStatus(features) {
|
|
147481
|
-
if (features.length === 0) {
|
|
147482
|
-
return "planned";
|
|
147483
|
-
}
|
|
147484
|
-
if (features.every((feature) => feature.status === "done")) {
|
|
147485
|
-
return "done";
|
|
147486
|
-
}
|
|
147487
|
-
if (features.some((feature) => feature.status === "in_progress")) {
|
|
147488
|
-
return "in_progress";
|
|
147489
|
-
}
|
|
147490
|
-
if (features.some((feature) => feature.status === "blocked")) {
|
|
147491
|
-
return "blocked";
|
|
147492
|
-
}
|
|
147493
|
-
return "planned";
|
|
147494
|
-
}
|
|
147495
|
-
function findKnowledgeSectionTitle(knowledgeSections, sectionId) {
|
|
147496
|
-
const section2 = knowledgeSections.find((item) => item.id === sectionId);
|
|
147497
|
-
if (!section2) {
|
|
147498
|
-
return {
|
|
147499
|
-
heading: sectionId,
|
|
147500
|
-
filePath: ""
|
|
147501
|
-
};
|
|
147502
|
-
}
|
|
147503
|
-
return {
|
|
147504
|
-
heading: section2.heading,
|
|
147505
|
-
filePath: section2.filePath
|
|
147506
|
-
};
|
|
147507
|
-
}
|
|
147508
|
-
async function buildProjectPlanHierarchy(root, graph) {
|
|
147509
|
-
const knowledgeSections = await readKnowledgeSections(root);
|
|
147510
|
-
const currentGraph = graph ?? await readProjectPlanGraph(root);
|
|
147511
|
-
const linkedTodos = await listLinkedTodosByTask(root);
|
|
147512
|
-
const featureMap = /* @__PURE__ */ new Map();
|
|
147513
|
-
for (const feature of currentGraph.features) {
|
|
147514
|
-
const featureTasks = currentGraph.tasks.filter((task) => task.featureId === feature.id).map((task) => {
|
|
147515
|
-
const taskLinkedTodos = linkedTodos.get(task.id) || [];
|
|
147516
|
-
return {
|
|
147517
|
-
...task,
|
|
147518
|
-
linkedTodos: taskLinkedTodos,
|
|
147519
|
-
linkedTodoCount: taskLinkedTodos.length
|
|
147520
|
-
};
|
|
147521
|
-
});
|
|
147522
|
-
featureMap.set(feature.id, {
|
|
147523
|
-
...feature,
|
|
147524
|
-
status: deriveFeatureStatus(featureTasks),
|
|
147525
|
-
taskCount: featureTasks.length,
|
|
147526
|
-
tasks: featureTasks
|
|
147527
|
-
});
|
|
147528
|
-
}
|
|
147529
|
-
const sections = currentGraph.sections.map((section2) => {
|
|
147530
|
-
const features = currentGraph.features.filter((feature) => feature.sectionId === section2.sectionId).map((feature) => featureMap.get(feature.id)).filter((feature) => Boolean(feature));
|
|
147531
|
-
const knowledgeMetadata = findKnowledgeSectionTitle(knowledgeSections, section2.sectionId);
|
|
147532
|
-
const taskCount = features.reduce((count, feature) => count + feature.taskCount, 0);
|
|
147533
|
-
return {
|
|
147534
|
-
sectionId: section2.sectionId,
|
|
147535
|
-
heading: knowledgeMetadata.heading,
|
|
147536
|
-
filePath: knowledgeMetadata.filePath,
|
|
147537
|
-
status: deriveSectionStatus(features),
|
|
147538
|
-
featureCount: features.length,
|
|
147539
|
-
taskCount,
|
|
147540
|
-
features
|
|
147541
|
-
};
|
|
147542
|
-
});
|
|
147543
|
-
return {
|
|
147544
|
-
sections
|
|
147545
|
-
};
|
|
147546
|
-
}
|
|
147547
|
-
function formatAcceptanceCriteria(criteria) {
|
|
147548
|
-
if (criteria.length === 0) {
|
|
147549
|
-
return ["- None yet"];
|
|
147550
|
-
}
|
|
147551
|
-
return criteria.map((item) => `- ${item}`);
|
|
147552
|
-
}
|
|
147553
|
-
async function renderProjectPlanMarkdown(root, graph) {
|
|
147554
|
-
const hierarchy = await buildProjectPlanHierarchy(root, graph);
|
|
147555
|
-
const lines = [
|
|
147556
|
-
"# Project Plan",
|
|
147557
|
-
"",
|
|
147558
|
-
"This file is derived from `docyrus/project-plan/project-plan.json`.",
|
|
147559
|
-
""
|
|
147560
|
-
];
|
|
147561
|
-
const populatedSections = hierarchy.sections.filter((section2) => section2.features.length > 0);
|
|
147562
|
-
if (populatedSections.length === 0) {
|
|
147563
|
-
lines.push("No planned features or tasks yet.");
|
|
147564
|
-
lines.push("");
|
|
147565
|
-
return `${lines.join("\n")}`;
|
|
147566
|
-
}
|
|
147567
|
-
for (const section2 of populatedSections) {
|
|
147568
|
-
lines.push(`## ${section2.heading}`);
|
|
147569
|
-
lines.push("");
|
|
147570
|
-
lines.push(`- Section ID: \`${section2.sectionId}\``);
|
|
147571
|
-
lines.push(`- Status: \`${section2.status}\``);
|
|
147572
|
-
lines.push(`- Features: ${section2.featureCount}`);
|
|
147573
|
-
lines.push(`- Tasks: ${section2.taskCount}`);
|
|
147574
|
-
lines.push("");
|
|
147575
|
-
for (const feature of section2.features) {
|
|
147576
|
-
lines.push(`### ${feature.title}`);
|
|
147577
|
-
lines.push("");
|
|
147578
|
-
lines.push(`- Feature ID: \`${feature.id}\``);
|
|
147579
|
-
lines.push(`- Status: \`${feature.status}\``);
|
|
147580
|
-
lines.push(`- Slug: \`${feature.slug}\``);
|
|
147581
|
-
if (feature.summary) {
|
|
147582
|
-
lines.push(`- Summary: ${feature.summary}`);
|
|
147583
|
-
}
|
|
147584
|
-
lines.push("");
|
|
147585
|
-
for (const task of feature.tasks) {
|
|
147586
|
-
lines.push(`#### ${task.title}`);
|
|
147587
|
-
lines.push("");
|
|
147588
|
-
lines.push(`- Task ID: \`${task.id}\``);
|
|
147589
|
-
lines.push(`- Type: \`${task.type}\``);
|
|
147590
|
-
lines.push(`- Assignee: \`${task.assignee}\``);
|
|
147591
|
-
lines.push(`- Status: \`${task.status}\``);
|
|
147592
|
-
if (task.summary) {
|
|
147593
|
-
lines.push(`- Summary: ${task.summary}`);
|
|
147594
|
-
}
|
|
147595
|
-
lines.push("- Acceptance Criteria:");
|
|
147596
|
-
lines.push(...formatAcceptanceCriteria(task.acceptanceCriteria));
|
|
147597
|
-
lines.push("");
|
|
147598
|
-
}
|
|
147599
|
-
}
|
|
147600
|
-
}
|
|
147601
|
-
return `${lines.join("\n").trimEnd()}
|
|
147602
|
-
`;
|
|
147603
|
-
}
|
|
147604
|
-
async function writeProjectPlanFiles(root, graph) {
|
|
147605
|
-
const graphPath = resolveProjectPlanGraphPath(root);
|
|
147606
|
-
const markdownPath = resolveProjectPlanMarkdownPath(root);
|
|
147607
|
-
await import_promises13.default.mkdir(import_node_path17.default.dirname(graphPath), {
|
|
147608
|
-
recursive: true
|
|
147609
|
-
});
|
|
147610
|
-
const sortedGraph = sortGraph(graph);
|
|
147611
|
-
await import_promises13.default.writeFile(graphPath, `${JSON.stringify(sortedGraph, null, 2)}
|
|
147612
|
-
`, "utf8");
|
|
147613
|
-
await import_promises13.default.writeFile(markdownPath, await renderProjectPlanMarkdown(root, sortedGraph), "utf8");
|
|
147614
|
-
return {
|
|
147615
|
-
graph: sortedGraph,
|
|
147616
|
-
graphPath,
|
|
147617
|
-
markdownPath
|
|
147618
|
-
};
|
|
147619
|
-
}
|
|
147620
|
-
function buildProjectPlanCheckError(code, message, target) {
|
|
147621
|
-
return {
|
|
147622
|
-
code,
|
|
147623
|
-
message,
|
|
147624
|
-
target
|
|
147625
|
-
};
|
|
147626
|
-
}
|
|
147627
|
-
async function validateProjectPlanGraph(root, graph) {
|
|
147628
|
-
const currentGraph = graph ?? await readProjectPlanGraph(root);
|
|
147629
|
-
const errors = [];
|
|
147630
|
-
const knowledgeSections = await readKnowledgeSections(root);
|
|
147631
|
-
const knowledgeSectionIds = new Set(knowledgeSections.map((section2) => section2.id));
|
|
147632
|
-
const sectionIds = /* @__PURE__ */ new Set();
|
|
147633
|
-
const featureIds = /* @__PURE__ */ new Set();
|
|
147634
|
-
const featureMap = /* @__PURE__ */ new Map();
|
|
147635
|
-
for (const section2 of currentGraph.sections) {
|
|
147636
|
-
if (!section2.sectionId) {
|
|
147637
|
-
errors.push(buildProjectPlanCheckError("section_missing_id", "Project plan section is missing `sectionId`."));
|
|
147638
|
-
continue;
|
|
147639
|
-
}
|
|
147640
|
-
if (sectionIds.has(section2.sectionId)) {
|
|
147641
|
-
errors.push(buildProjectPlanCheckError("duplicate_section", `Duplicate section id "${section2.sectionId}"`, section2.sectionId));
|
|
147642
|
-
continue;
|
|
147643
|
-
}
|
|
147644
|
-
sectionIds.add(section2.sectionId);
|
|
147645
|
-
if (!knowledgeSectionIds.has(section2.sectionId)) {
|
|
147646
|
-
errors.push(buildProjectPlanCheckError(
|
|
147647
|
-
"unknown_knowledge_section",
|
|
147648
|
-
`Project plan section "${section2.sectionId}" does not exist in docyrus/knowledge.`,
|
|
147649
|
-
section2.sectionId
|
|
147650
|
-
));
|
|
147651
|
-
}
|
|
147652
|
-
}
|
|
147653
|
-
const allowedTypes = new Set(PROJECT_TASK_TYPES);
|
|
147654
|
-
const allowedAssignees = new Set(PROJECT_TASK_ASSIGNEES);
|
|
147655
|
-
const allowedStatuses = new Set(PROJECT_TASK_STATUSES);
|
|
147656
|
-
for (const feature of currentGraph.features) {
|
|
147657
|
-
if (!feature.id) {
|
|
147658
|
-
errors.push(buildProjectPlanCheckError("feature_missing_id", "Project plan feature is missing `id`."));
|
|
147659
|
-
continue;
|
|
147660
|
-
}
|
|
147661
|
-
if (featureIds.has(feature.id)) {
|
|
147662
|
-
errors.push(buildProjectPlanCheckError("duplicate_feature", `Duplicate feature id "${feature.id}"`, feature.id));
|
|
147663
|
-
continue;
|
|
147664
|
-
}
|
|
147665
|
-
featureIds.add(feature.id);
|
|
147666
|
-
featureMap.set(feature.id, feature);
|
|
147667
|
-
if (!feature.sectionId) {
|
|
147668
|
-
errors.push(buildProjectPlanCheckError("feature_missing_section", `Feature "${feature.id}" is missing \`sectionId\`.`, feature.id));
|
|
147669
|
-
continue;
|
|
147670
|
-
}
|
|
147671
|
-
if (!sectionIds.has(feature.sectionId)) {
|
|
147672
|
-
errors.push(buildProjectPlanCheckError(
|
|
147673
|
-
"feature_unknown_section",
|
|
147674
|
-
`Feature "${feature.id}" references unknown section "${feature.sectionId}".`,
|
|
147675
|
-
feature.id
|
|
147676
|
-
));
|
|
147677
|
-
}
|
|
147678
|
-
if (!feature.title.trim()) {
|
|
147679
|
-
errors.push(buildProjectPlanCheckError("feature_missing_title", `Feature "${feature.id}" is missing a title.`, feature.id));
|
|
147680
|
-
}
|
|
147681
|
-
if (!feature.slug.trim()) {
|
|
147682
|
-
errors.push(buildProjectPlanCheckError("feature_missing_slug", `Feature "${feature.id}" is missing a slug.`, feature.id));
|
|
147683
|
-
}
|
|
147684
|
-
}
|
|
147685
|
-
const taskIds = /* @__PURE__ */ new Set();
|
|
147686
|
-
for (const task of currentGraph.tasks) {
|
|
147687
|
-
if (!task.id) {
|
|
147688
|
-
errors.push(buildProjectPlanCheckError("task_missing_id", "Project plan task is missing `id`."));
|
|
147689
|
-
continue;
|
|
147690
|
-
}
|
|
147691
|
-
if (taskIds.has(task.id)) {
|
|
147692
|
-
errors.push(buildProjectPlanCheckError("duplicate_task", `Duplicate task id "${task.id}"`, task.id));
|
|
147693
|
-
continue;
|
|
147694
|
-
}
|
|
147695
|
-
taskIds.add(task.id);
|
|
147696
|
-
const feature = featureMap.get(task.featureId);
|
|
147697
|
-
if (!feature) {
|
|
147698
|
-
errors.push(buildProjectPlanCheckError(
|
|
147699
|
-
"task_unknown_feature",
|
|
147700
|
-
`Task "${task.id}" references unknown feature "${task.featureId}".`,
|
|
147701
|
-
task.id
|
|
147702
|
-
));
|
|
147703
|
-
continue;
|
|
147704
|
-
}
|
|
147705
|
-
if (!task.title.trim()) {
|
|
147706
|
-
errors.push(buildProjectPlanCheckError("task_missing_title", `Task "${task.id}" is missing a title.`, task.id));
|
|
147707
|
-
}
|
|
147708
|
-
if (!allowedTypes.has(task.type)) {
|
|
147709
|
-
errors.push(buildProjectPlanCheckError(
|
|
147710
|
-
"task_invalid_type",
|
|
147711
|
-
`Task "${task.id}" has invalid type "${task.type}".`,
|
|
147712
|
-
task.id
|
|
147713
|
-
));
|
|
147714
|
-
}
|
|
147715
|
-
if (!allowedAssignees.has(task.assignee)) {
|
|
147716
|
-
errors.push(buildProjectPlanCheckError(
|
|
147717
|
-
"task_invalid_assignee",
|
|
147718
|
-
`Task "${task.id}" has invalid assignee "${task.assignee}".`,
|
|
147719
|
-
task.id
|
|
147720
|
-
));
|
|
147721
|
-
}
|
|
147722
|
-
if (!allowedStatuses.has(task.status)) {
|
|
147723
|
-
errors.push(buildProjectPlanCheckError(
|
|
147724
|
-
"task_invalid_status",
|
|
147725
|
-
`Task "${task.id}" has invalid status "${task.status}".`,
|
|
147726
|
-
task.id
|
|
147727
|
-
));
|
|
147728
|
-
}
|
|
147729
|
-
if (!sectionIds.has(task.sectionId)) {
|
|
147730
|
-
errors.push(buildProjectPlanCheckError(
|
|
147731
|
-
"task_unknown_section",
|
|
147732
|
-
`Task "${task.id}" references unknown section "${task.sectionId}".`,
|
|
147733
|
-
task.id
|
|
147734
|
-
));
|
|
147735
|
-
}
|
|
147736
|
-
if (task.sectionId !== feature.sectionId) {
|
|
147737
|
-
errors.push(buildProjectPlanCheckError(
|
|
147738
|
-
"task_section_mismatch",
|
|
147739
|
-
`Task "${task.id}" section "${task.sectionId}" does not match feature "${feature.id}" section "${feature.sectionId}".`,
|
|
147740
|
-
task.id
|
|
147741
|
-
));
|
|
147742
|
-
}
|
|
147743
|
-
}
|
|
147744
|
-
return {
|
|
147745
|
-
ok: errors.length === 0,
|
|
147746
|
-
errors
|
|
147747
|
-
};
|
|
147748
|
-
}
|
|
147749
|
-
async function resolveKnowledgeSectionIds(root) {
|
|
147750
|
-
const sections = await readKnowledgeSections(root);
|
|
147751
|
-
return sections.map((section2) => section2.id).sort(compareStrings);
|
|
147752
|
-
}
|
|
147753
|
-
async function syncProjectPlanSectionsFromKnowledge(root) {
|
|
147754
|
-
const currentGraph = await readProjectPlanGraph(root);
|
|
147755
|
-
const knowledgeSectionIds = await resolveKnowledgeSectionIds(root);
|
|
147756
|
-
const syncedGraph = {
|
|
147757
|
-
...currentGraph,
|
|
147758
|
-
sections: knowledgeSectionIds.map((sectionId) => ({
|
|
147759
|
-
sectionId
|
|
147760
|
-
}))
|
|
147761
|
-
};
|
|
147762
|
-
return writeProjectPlanFiles(root, syncedGraph);
|
|
147763
|
-
}
|
|
147764
|
-
async function ensureProjectPlanGraph(root) {
|
|
147765
|
-
const graphPath = resolveProjectPlanGraphPath(root);
|
|
147766
|
-
if (!(0, import_node_fs9.existsSync)(graphPath)) {
|
|
147767
|
-
return syncProjectPlanSectionsFromKnowledge(root);
|
|
147768
|
-
}
|
|
147769
|
-
const graph = await readProjectPlanGraph(root);
|
|
147770
|
-
return writeProjectPlanFiles(root, graph);
|
|
147771
|
-
}
|
|
147772
|
-
async function upsertProjectPlanFeature(params) {
|
|
147773
|
-
const state = await ensureProjectPlanGraph(params.root);
|
|
147774
|
-
const slug = slugify2(params.slug?.trim() || params.title);
|
|
147775
|
-
const featureId = params.featureId?.trim() || normalizeFeatureId(params.sectionId, slug);
|
|
147776
|
-
const graph = state.graph;
|
|
147777
|
-
const existing = graph.features.find((feature) => feature.id === featureId) || graph.features.find((feature) => feature.sectionId === params.sectionId && feature.slug === slug);
|
|
147778
|
-
const nextFeature = {
|
|
147779
|
-
id: existing?.id || featureId,
|
|
147780
|
-
title: params.title.trim(),
|
|
147781
|
-
slug,
|
|
147782
|
-
summary: params.summary?.trim() || "",
|
|
147783
|
-
sectionId: params.sectionId
|
|
147784
|
-
};
|
|
147785
|
-
const nextFeatures = existing ? graph.features.map((feature) => feature.id === existing.id ? nextFeature : feature) : [...graph.features, nextFeature];
|
|
147786
|
-
await writeProjectPlanFiles(params.root, {
|
|
147787
|
-
...graph,
|
|
147788
|
-
features: nextFeatures
|
|
147789
|
-
});
|
|
147790
|
-
return nextFeature;
|
|
147791
|
-
}
|
|
147792
|
-
async function getProjectPlanTask(params) {
|
|
147793
|
-
const graph = await readProjectPlanGraph(params.root);
|
|
147794
|
-
const linkedTodos = await listLinkedTodosByTask(params.root);
|
|
147795
|
-
const task = graph.tasks.find((item) => item.id === params.taskId);
|
|
147796
|
-
if (!task) {
|
|
147797
|
-
return null;
|
|
147798
|
-
}
|
|
147799
|
-
const taskLinkedTodos = linkedTodos.get(task.id) || [];
|
|
147800
|
-
return {
|
|
147801
|
-
...task,
|
|
147802
|
-
linkedTodos: taskLinkedTodos,
|
|
147803
|
-
linkedTodoCount: taskLinkedTodos.length
|
|
147804
|
-
};
|
|
147805
|
-
}
|
|
147806
|
-
async function upsertProjectPlanTask(params) {
|
|
147807
|
-
const state = await ensureProjectPlanGraph(params.root);
|
|
147808
|
-
const graph = state.graph;
|
|
147809
|
-
const feature = graph.features.find((item) => item.id === params.featureId);
|
|
147810
|
-
if (!feature) {
|
|
147811
|
-
throw new Error(`Feature "${params.featureId}" not found.`);
|
|
147812
|
-
}
|
|
147813
|
-
const sectionId = params.sectionId?.trim() || feature.sectionId;
|
|
147814
|
-
const taskId = params.taskId?.trim() || normalizeTaskId(feature.id, params.type, params.title);
|
|
147815
|
-
const existing = graph.tasks.find((task) => task.id === taskId) || graph.tasks.find((task) => task.featureId === feature.id && task.type === params.type && task.title === params.title.trim());
|
|
147816
|
-
const nextTask = {
|
|
147817
|
-
id: existing?.id || taskId,
|
|
147818
|
-
title: params.title.trim(),
|
|
147819
|
-
summary: params.summary?.trim() || "",
|
|
147820
|
-
type: params.type,
|
|
147821
|
-
assignee: params.assignee,
|
|
147822
|
-
status: params.status || "planned",
|
|
147823
|
-
acceptanceCriteria: [...new Set((params.acceptanceCriteria || []).map((item) => item.trim()).filter(Boolean))],
|
|
147824
|
-
featureId: feature.id,
|
|
147825
|
-
sectionId
|
|
147826
|
-
};
|
|
147827
|
-
const nextTasks = existing ? graph.tasks.map((task) => task.id === existing.id ? nextTask : task) : [...graph.tasks, nextTask];
|
|
147828
|
-
await writeProjectPlanFiles(params.root, {
|
|
147829
|
-
...graph,
|
|
147830
|
-
tasks: nextTasks
|
|
147831
|
-
});
|
|
147832
|
-
return nextTask;
|
|
147833
|
-
}
|
|
147834
|
-
async function updateProjectPlanTaskStatus(params) {
|
|
147835
|
-
const graph = await readProjectPlanGraph(params.root);
|
|
147836
|
-
const task = graph.tasks.find((item) => item.id === params.taskId);
|
|
147837
|
-
if (!task) {
|
|
147838
|
-
throw new Error(`Task "${params.taskId}" not found.`);
|
|
147839
|
-
}
|
|
147840
|
-
const nextTask = {
|
|
147841
|
-
...task,
|
|
147842
|
-
status: params.status
|
|
147843
|
-
};
|
|
147844
|
-
await writeProjectPlanFiles(params.root, {
|
|
147845
|
-
...graph,
|
|
147846
|
-
tasks: graph.tasks.map((item) => item.id === task.id ? nextTask : item)
|
|
147847
|
-
});
|
|
147848
|
-
return nextTask;
|
|
147849
|
-
}
|
|
147850
|
-
async function resolveDefaultProjectPlanRoutes(root) {
|
|
147851
|
-
const sections = await readKnowledgeSections(root);
|
|
147852
|
-
const resolveRoute = (key) => {
|
|
147853
|
-
const candidate = sections.find((section2) => {
|
|
147854
|
-
return section2.heading === DEFAULT_ROUTE_TARGETS[key].heading && section2.filePath === DEFAULT_ROUTE_TARGETS[key].filePathSuffix && section2.depth === 1;
|
|
147855
|
-
}) || sections.find((section2) => section2.heading === DEFAULT_ROUTE_TARGETS[key].heading);
|
|
147856
|
-
if (!candidate) {
|
|
147857
|
-
throw new Error(`Unable to resolve the default knowledge section for ${key}.`);
|
|
147858
|
-
}
|
|
147859
|
-
return candidate.id;
|
|
147860
|
-
};
|
|
147861
|
-
return {
|
|
147862
|
-
featuresSectionId: resolveRoute("features"),
|
|
147863
|
-
testingSectionId: resolveRoute("testing"),
|
|
147864
|
-
architectureSectionId: resolveRoute("architecture"),
|
|
147865
|
-
workflowsSectionId: resolveRoute("workflows")
|
|
147866
|
-
};
|
|
147867
|
-
}
|
|
147868
|
-
|
|
147869
147138
|
// src/knowledge/init.ts
|
|
147870
147139
|
var MARKER_BEGIN = "%% docyrus-knowledge:begin %%";
|
|
147871
147140
|
var MARKER_END = "%% docyrus-knowledge:end %%";
|
|
@@ -147877,60 +147146,60 @@ ${content3}${content3.endsWith("\n") ? "" : "\n"}${MARKER_END}
|
|
|
147877
147146
|
`;
|
|
147878
147147
|
}
|
|
147879
147148
|
async function ensureDirectory(pathValue) {
|
|
147880
|
-
await (0,
|
|
147149
|
+
await (0, import_promises12.mkdir)(pathValue, {
|
|
147881
147150
|
recursive: true,
|
|
147882
147151
|
mode: 493
|
|
147883
147152
|
});
|
|
147884
147153
|
}
|
|
147885
147154
|
async function writeIfMissing(filePath, content3) {
|
|
147886
|
-
if ((0,
|
|
147155
|
+
if ((0, import_node_fs8.existsSync)(filePath)) {
|
|
147887
147156
|
return "kept";
|
|
147888
147157
|
}
|
|
147889
|
-
await ensureDirectory((0,
|
|
147890
|
-
await (0,
|
|
147158
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147159
|
+
await (0, import_promises12.writeFile)(filePath, content3, "utf8");
|
|
147891
147160
|
return "created";
|
|
147892
147161
|
}
|
|
147893
147162
|
async function writeOrUpdate(filePath, content3) {
|
|
147894
|
-
if (!(0,
|
|
147895
|
-
await ensureDirectory((0,
|
|
147896
|
-
await (0,
|
|
147163
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) {
|
|
147164
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147165
|
+
await (0, import_promises12.writeFile)(filePath, content3, "utf8");
|
|
147897
147166
|
return "created";
|
|
147898
147167
|
}
|
|
147899
|
-
const current = await (0,
|
|
147168
|
+
const current = await (0, import_promises12.readFile)(filePath, "utf8");
|
|
147900
147169
|
if (current === content3) {
|
|
147901
147170
|
return "kept";
|
|
147902
147171
|
}
|
|
147903
|
-
await ensureDirectory((0,
|
|
147904
|
-
await (0,
|
|
147172
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147173
|
+
await (0, import_promises12.writeFile)(filePath, content3, "utf8");
|
|
147905
147174
|
return "updated";
|
|
147906
147175
|
}
|
|
147907
147176
|
async function upsertManagedBlock(filePath, content3) {
|
|
147908
147177
|
const wrapped = wrapManagedBlock(content3);
|
|
147909
|
-
if (!(0,
|
|
147910
|
-
await ensureDirectory((0,
|
|
147911
|
-
await (0,
|
|
147178
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) {
|
|
147179
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147180
|
+
await (0, import_promises12.writeFile)(filePath, wrapped, "utf8");
|
|
147912
147181
|
return "created";
|
|
147913
147182
|
}
|
|
147914
|
-
const current = await (0,
|
|
147183
|
+
const current = await (0, import_promises12.readFile)(filePath, "utf8");
|
|
147915
147184
|
const beginIndex = current.indexOf(MARKER_BEGIN);
|
|
147916
147185
|
const endIndex = current.indexOf(MARKER_END);
|
|
147917
147186
|
if (beginIndex !== -1 && endIndex !== -1 && endIndex > beginIndex) {
|
|
147918
147187
|
const replaceEnd = current[endIndex + MARKER_END.length] === "\n" ? endIndex + MARKER_END.length + 1 : endIndex + MARKER_END.length;
|
|
147919
147188
|
const updated = `${current.slice(0, beginIndex)}${wrapped}${current.slice(replaceEnd)}`;
|
|
147920
|
-
await (0,
|
|
147189
|
+
await (0, import_promises12.writeFile)(filePath, updated, "utf8");
|
|
147921
147190
|
return "updated";
|
|
147922
147191
|
}
|
|
147923
147192
|
const separator = current.endsWith("\n") ? "\n" : "\n\n";
|
|
147924
|
-
await (0,
|
|
147193
|
+
await (0, import_promises12.writeFile)(filePath, `${current}${separator}${wrapped}`, "utf8");
|
|
147925
147194
|
return "appended";
|
|
147926
147195
|
}
|
|
147927
147196
|
function normalizeObject(value2) {
|
|
147928
147197
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) ? { ...value2 } : {};
|
|
147929
147198
|
}
|
|
147930
147199
|
async function updateJsonFile(filePath, updater) {
|
|
147931
|
-
const current = (0,
|
|
147932
|
-
await ensureDirectory((0,
|
|
147933
|
-
await (0,
|
|
147200
|
+
const current = (0, import_node_fs8.existsSync)(filePath) ? normalizeObject(JSON.parse((0, import_node_fs8.readFileSync)(filePath, "utf8"))) : {};
|
|
147201
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147202
|
+
await (0, import_promises12.writeFile)(filePath, `${JSON.stringify(updater(current), null, 2)}
|
|
147934
147203
|
`, "utf8");
|
|
147935
147204
|
}
|
|
147936
147205
|
function wrapHookBlock(content3) {
|
|
@@ -147940,17 +147209,17 @@ ${content3}${content3.endsWith("\n") ? "" : "\n"}${HOOK_MARKER_END}
|
|
|
147940
147209
|
}
|
|
147941
147210
|
async function upsertShellHook(filePath, content3, shellHeader) {
|
|
147942
147211
|
const wrapped = wrapHookBlock(content3);
|
|
147943
|
-
if (!(0,
|
|
147944
|
-
await ensureDirectory((0,
|
|
147212
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) {
|
|
147213
|
+
await ensureDirectory((0, import_node_path16.dirname)(filePath));
|
|
147945
147214
|
const initial = `${shellHeader || ""}${wrapped}`;
|
|
147946
|
-
await (0,
|
|
147215
|
+
await (0, import_promises12.writeFile)(filePath, initial, {
|
|
147947
147216
|
encoding: "utf8",
|
|
147948
147217
|
mode: 493
|
|
147949
147218
|
});
|
|
147950
|
-
await (0,
|
|
147219
|
+
await (0, import_promises12.chmod)(filePath, 493);
|
|
147951
147220
|
return "created";
|
|
147952
147221
|
}
|
|
147953
|
-
const current = await (0,
|
|
147222
|
+
const current = await (0, import_promises12.readFile)(filePath, "utf8");
|
|
147954
147223
|
const beginIndex = current.indexOf(HOOK_MARKER_BEGIN);
|
|
147955
147224
|
const endIndex = current.indexOf(HOOK_MARKER_END);
|
|
147956
147225
|
if (beginIndex !== -1 && endIndex !== -1 && endIndex > beginIndex) {
|
|
@@ -147959,13 +147228,13 @@ async function upsertShellHook(filePath, content3, shellHeader) {
|
|
|
147959
147228
|
if (nextContent === current) {
|
|
147960
147229
|
return "kept";
|
|
147961
147230
|
}
|
|
147962
|
-
await (0,
|
|
147963
|
-
await (0,
|
|
147231
|
+
await (0, import_promises12.writeFile)(filePath, nextContent, "utf8");
|
|
147232
|
+
await (0, import_promises12.chmod)(filePath, 493);
|
|
147964
147233
|
return "updated";
|
|
147965
147234
|
}
|
|
147966
147235
|
const separator = current.endsWith("\n") ? "\n" : "\n\n";
|
|
147967
|
-
await (0,
|
|
147968
|
-
await (0,
|
|
147236
|
+
await (0, import_promises12.writeFile)(filePath, `${current}${separator}${wrapped}`, "utf8");
|
|
147237
|
+
await (0, import_promises12.chmod)(filePath, 493);
|
|
147969
147238
|
return "appended";
|
|
147970
147239
|
}
|
|
147971
147240
|
function buildKnowledgeDocumentTemplate() {
|
|
@@ -148059,34 +147328,33 @@ function syncCursorHooks(settings, commandPrefix) {
|
|
|
148059
147328
|
};
|
|
148060
147329
|
}
|
|
148061
147330
|
async function initializeKnowledgeRepo(params) {
|
|
148062
|
-
const root = (0,
|
|
147331
|
+
const root = (0, import_node_path16.resolve)(params.root || process.cwd());
|
|
148063
147332
|
const knowledgeDir = getKnowledgeDirectory(root);
|
|
148064
|
-
const knowledgeFile = (0,
|
|
147333
|
+
const knowledgeFile = (0, import_node_path16.join)(knowledgeDir, "knowledge.md");
|
|
148065
147334
|
await ensureDirectory(knowledgeDir);
|
|
148066
147335
|
const knowledgeFileStatus = await writeIfMissing(knowledgeFile, `${buildKnowledgeDocumentTemplate()}
|
|
148067
147336
|
`);
|
|
148068
|
-
const agentsStatus = await upsertManagedBlock((0,
|
|
148069
|
-
const claudeStatus = await upsertManagedBlock((0,
|
|
148070
|
-
const cursorRulesStatus = await writeOrUpdate((0,
|
|
147337
|
+
const agentsStatus = await upsertManagedBlock((0, import_node_path16.join)(root, "AGENTS.md"), buildAgentsTemplate(params.commandPrefix));
|
|
147338
|
+
const claudeStatus = await upsertManagedBlock((0, import_node_path16.join)(root, "CLAUDE.md"), buildAgentsTemplate(params.commandPrefix));
|
|
147339
|
+
const cursorRulesStatus = await writeOrUpdate((0, import_node_path16.join)(root, ".cursor", "rules", "docyrus-knowledge.md"), `${buildCursorRulesTemplate(params.commandPrefix)}
|
|
148071
147340
|
`);
|
|
148072
147341
|
const bootstrap = (await generateInitialKnowledge({
|
|
148073
147342
|
root,
|
|
148074
147343
|
brief: params.brief
|
|
148075
147344
|
})).files;
|
|
148076
|
-
|
|
148077
|
-
await updateJsonFile((0,
|
|
148078
|
-
await updateJsonFile((0, import_node_path18.join)(root, ".cursor", "hooks.json"), (value2) => syncCursorHooks(value2, params.commandPrefix));
|
|
147345
|
+
await updateJsonFile((0, import_node_path16.join)(root, ".claude", "settings.json"), (value2) => syncClaudeHooks(value2, params.commandPrefix));
|
|
147346
|
+
await updateJsonFile((0, import_node_path16.join)(root, ".cursor", "hooks.json"), (value2) => syncCursorHooks(value2, params.commandPrefix));
|
|
148079
147347
|
let huskyHookStatus;
|
|
148080
|
-
const huskyDir = (0,
|
|
148081
|
-
if ((0,
|
|
148082
|
-
const huskyHookPath = (0,
|
|
148083
|
-
const huskyHeader = (0,
|
|
147348
|
+
const huskyDir = (0, import_node_path16.join)(root, ".husky");
|
|
147349
|
+
if ((0, import_node_fs8.existsSync)(huskyDir)) {
|
|
147350
|
+
const huskyHookPath = (0, import_node_path16.join)(huskyDir, "pre-commit");
|
|
147351
|
+
const huskyHeader = (0, import_node_fs8.existsSync)((0, import_node_path16.join)(huskyDir, "_", "h")) ? '#!/usr/bin/env sh\n. "$(dirname -- "$0")/_/h"\n\n' : void 0;
|
|
148084
147352
|
huskyHookStatus = await upsertShellHook(huskyHookPath, `${params.commandPrefix} knowledge pre-commit
|
|
148085
147353
|
`, huskyHeader);
|
|
148086
147354
|
}
|
|
148087
147355
|
let gitHookStatus;
|
|
148088
147356
|
if (!huskyHookStatus && params.installGitHook) {
|
|
148089
|
-
const gitHookPath = (0,
|
|
147357
|
+
const gitHookPath = (0, import_node_path16.join)(root, ".git", "hooks", "pre-commit");
|
|
148090
147358
|
gitHookStatus = await upsertShellHook(gitHookPath, `${params.commandPrefix} knowledge pre-commit
|
|
148091
147359
|
`, "#!/usr/bin/env sh\n\n");
|
|
148092
147360
|
}
|
|
@@ -148094,8 +147362,6 @@ async function initializeKnowledgeRepo(params) {
|
|
|
148094
147362
|
root,
|
|
148095
147363
|
knowledgeDir,
|
|
148096
147364
|
knowledgeFile,
|
|
148097
|
-
projectPlanGraphPath: projectPlan.graphPath,
|
|
148098
|
-
projectPlanMarkdownPath: projectPlan.markdownPath,
|
|
148099
147365
|
agentsStatus,
|
|
148100
147366
|
claudeStatus,
|
|
148101
147367
|
cursorRulesStatus,
|
|
@@ -148110,9 +147376,9 @@ async function initializeKnowledgeRepo(params) {
|
|
|
148110
147376
|
init_graph();
|
|
148111
147377
|
|
|
148112
147378
|
// src/knowledge/validation.ts
|
|
148113
|
-
var
|
|
148114
|
-
var
|
|
148115
|
-
var
|
|
147379
|
+
var import_node_fs9 = require("node:fs");
|
|
147380
|
+
var import_promises13 = require("node:fs/promises");
|
|
147381
|
+
var import_node_path17 = require("node:path");
|
|
148116
147382
|
init_graph();
|
|
148117
147383
|
var MAX_BODY_LENGTH = 250;
|
|
148118
147384
|
function bodyTextLength(body2) {
|
|
@@ -148145,15 +147411,15 @@ async function tryResolveSourceRef(target, projectRoot) {
|
|
|
148145
147411
|
const hashIndex = target.indexOf("#");
|
|
148146
147412
|
const filePart = hashIndex === -1 ? target : target.slice(0, hashIndex);
|
|
148147
147413
|
const symbolPart = hashIndex === -1 ? "" : target.slice(hashIndex + 1);
|
|
148148
|
-
const extension2 = (0,
|
|
147414
|
+
const extension2 = (0, import_node_path17.extname)(filePart);
|
|
148149
147415
|
if (!SOURCE_EXTENSIONS.has(extension2)) {
|
|
148150
147416
|
if (extension2 && hashIndex !== -1) {
|
|
148151
147417
|
return `broken link [[${target}]] - unsupported file extension "${extension2}"`;
|
|
148152
147418
|
}
|
|
148153
147419
|
return `broken link [[${target}]] - no matching section found`;
|
|
148154
147420
|
}
|
|
148155
|
-
const absolutePath = (0,
|
|
148156
|
-
if (!(0,
|
|
147421
|
+
const absolutePath = (0, import_node_path17.join)(projectRoot, filePart);
|
|
147422
|
+
if (!(0, import_node_fs9.existsSync)(absolutePath)) {
|
|
148157
147423
|
return `broken link [[${target}]] - file "${filePart}" not found`;
|
|
148158
147424
|
}
|
|
148159
147425
|
if (!symbolPart) {
|
|
@@ -148170,7 +147436,7 @@ async function tryResolveSourceRef(target, projectRoot) {
|
|
|
148170
147436
|
}
|
|
148171
147437
|
async function checkKnowledgeMarkdown(knowledgeDir) {
|
|
148172
147438
|
clearSymbolCache();
|
|
148173
|
-
const projectRoot = (0,
|
|
147439
|
+
const projectRoot = (0, import_node_path17.dirname)((0, import_node_path17.dirname)(knowledgeDir));
|
|
148174
147440
|
const files = await listKnowledgeFiles(knowledgeDir);
|
|
148175
147441
|
const sections = await loadAllSections(knowledgeDir);
|
|
148176
147442
|
const flat = flattenSections(sections);
|
|
@@ -148179,9 +147445,9 @@ async function checkKnowledgeMarkdown(knowledgeDir) {
|
|
|
148179
147445
|
const fileIndex = buildFileIndex(sections);
|
|
148180
147446
|
const errors = [];
|
|
148181
147447
|
for (const filePath of files) {
|
|
148182
|
-
const content3 = await (0,
|
|
147448
|
+
const content3 = await (0, import_promises13.readFile)(filePath, "utf8");
|
|
148183
147449
|
const refs = extractRefs(filePath, content3, projectRoot);
|
|
148184
|
-
const displayPath = (0,
|
|
147450
|
+
const displayPath = (0, import_node_path17.relative)(process.cwd(), filePath);
|
|
148185
147451
|
for (const ref of refs) {
|
|
148186
147452
|
const resolved = resolveRef2(ref.target, sectionIds, fileIndex, canonicalSectionIds);
|
|
148187
147453
|
if (resolved.ambiguous) {
|
|
@@ -148213,7 +147479,7 @@ async function checkKnowledgeMarkdown(knowledgeDir) {
|
|
|
148213
147479
|
};
|
|
148214
147480
|
}
|
|
148215
147481
|
async function checkKnowledgeCodeRefs(knowledgeDir) {
|
|
148216
|
-
const projectRoot = (0,
|
|
147482
|
+
const projectRoot = (0, import_node_path17.dirname)((0, import_node_path17.dirname)(knowledgeDir));
|
|
148217
147483
|
const sections = await loadAllSections(knowledgeDir);
|
|
148218
147484
|
const flat = flattenSections(sections);
|
|
148219
147485
|
const sectionIds = new Set(flat.map((section2) => section2.id.toLowerCase()));
|
|
@@ -148225,7 +147491,7 @@ async function checkKnowledgeCodeRefs(knowledgeDir) {
|
|
|
148225
147491
|
for (const ref of scan.refs) {
|
|
148226
147492
|
const resolved = resolveRef2(ref.target, sectionIds, fileIndex, canonicalSectionIds);
|
|
148227
147493
|
mentionedSections.add(resolved.resolved.toLowerCase());
|
|
148228
|
-
const displayPath = (0,
|
|
147494
|
+
const displayPath = (0, import_node_path17.relative)(process.cwd(), (0, import_node_path17.join)(projectRoot, ref.file));
|
|
148229
147495
|
if (resolved.ambiguous) {
|
|
148230
147496
|
errors.push({
|
|
148231
147497
|
file: displayPath,
|
|
@@ -148245,12 +147511,12 @@ async function checkKnowledgeCodeRefs(knowledgeDir) {
|
|
|
148245
147511
|
}
|
|
148246
147512
|
}
|
|
148247
147513
|
for (const filePath of await listKnowledgeFiles(knowledgeDir)) {
|
|
148248
|
-
const content3 = await (0,
|
|
147514
|
+
const content3 = await (0, import_promises13.readFile)(filePath, "utf8");
|
|
148249
147515
|
if (!parseFrontmatter(content3).requireCodeMention) {
|
|
148250
147516
|
continue;
|
|
148251
147517
|
}
|
|
148252
147518
|
const leafSections = flattenSections(parseSections(filePath, content3, projectRoot)).filter((section2) => section2.children.length === 0);
|
|
148253
|
-
const displayPath = (0,
|
|
147519
|
+
const displayPath = (0, import_node_path17.relative)(process.cwd(), filePath);
|
|
148254
147520
|
for (const section2 of leafSections) {
|
|
148255
147521
|
if (!mentionedSections.has(section2.id.toLowerCase())) {
|
|
148256
147522
|
errors.push({
|
|
@@ -148274,7 +147540,7 @@ async function checkKnowledgeIndex(knowledgeDir) {
|
|
|
148274
147540
|
const name2 = pathValue.includes("/") ? pathValue.slice(pathValue.lastIndexOf("/") + 1) : pathValue;
|
|
148275
147541
|
if (!name2.endsWith(".md")) {
|
|
148276
147542
|
errors.push({
|
|
148277
|
-
dir: `${(0,
|
|
147543
|
+
dir: `${(0, import_node_path17.basename)(knowledgeDir)}/`,
|
|
148278
147544
|
message: `"${pathValue}" is not a .md file - only markdown files belong in docyrus/knowledge/`
|
|
148279
147545
|
});
|
|
148280
147546
|
}
|
|
@@ -148288,7 +147554,7 @@ async function checkKnowledgeIndex(knowledgeDir) {
|
|
|
148288
147554
|
}
|
|
148289
147555
|
}
|
|
148290
147556
|
for (const dir of dirs) {
|
|
148291
|
-
const dirName = dir === "" ? (0,
|
|
147557
|
+
const dirName = dir === "" ? (0, import_node_path17.basename)(knowledgeDir) : dir.split("/").pop() || (0, import_node_path17.basename)(knowledgeDir);
|
|
148292
147558
|
const indexFileName = dirName.endsWith(".md") ? dirName : `${dirName}.md`;
|
|
148293
147559
|
const indexRelPath = dir === "" ? indexFileName : `${dir}/${indexFileName}`;
|
|
148294
147560
|
const prefix = dir === "" ? "" : `${dir}/`;
|
|
@@ -148297,11 +147563,11 @@ async function checkKnowledgeIndex(knowledgeDir) {
|
|
|
148297
147563
|
if (children.length === 0) {
|
|
148298
147564
|
continue;
|
|
148299
147565
|
}
|
|
148300
|
-
const indexFullPath = (0,
|
|
148301
|
-
const displayDir = dir === "" ? `${(0,
|
|
147566
|
+
const indexFullPath = (0, import_node_path17.join)(knowledgeDir, indexRelPath);
|
|
147567
|
+
const displayDir = dir === "" ? `${(0, import_node_path17.basename)(knowledgeDir)}/` : `${dir}/`;
|
|
148302
147568
|
let content3;
|
|
148303
147569
|
try {
|
|
148304
|
-
content3 = await (0,
|
|
147570
|
+
content3 = await (0, import_promises13.readFile)(indexFullPath, "utf8");
|
|
148305
147571
|
} catch {
|
|
148306
147572
|
errors.push({
|
|
148307
147573
|
dir: displayDir,
|
|
@@ -148337,12 +147603,12 @@ ${indexSnippet(missing)}`,
|
|
|
148337
147603
|
return errors;
|
|
148338
147604
|
}
|
|
148339
147605
|
async function checkKnowledgeSections(knowledgeDir) {
|
|
148340
|
-
const projectRoot = (0,
|
|
147606
|
+
const projectRoot = (0, import_node_path17.dirname)((0, import_node_path17.dirname)(knowledgeDir));
|
|
148341
147607
|
const errors = [];
|
|
148342
147608
|
for (const filePath of await listKnowledgeFiles(knowledgeDir)) {
|
|
148343
|
-
const content3 = await (0,
|
|
147609
|
+
const content3 = await (0, import_promises13.readFile)(filePath, "utf8");
|
|
148344
147610
|
const sections = flattenSections(parseSections(filePath, content3, projectRoot));
|
|
148345
|
-
const displayPath = (0,
|
|
147611
|
+
const displayPath = (0, import_node_path17.relative)(process.cwd(), filePath);
|
|
148346
147612
|
for (const section2 of sections) {
|
|
148347
147613
|
if (!section2.firstParagraph) {
|
|
148348
147614
|
errors.push({
|
|
@@ -148397,7 +147663,7 @@ function formatKnowledgeIndexErrors(errors, styler) {
|
|
|
148397
147663
|
|
|
148398
147664
|
// src/knowledge/audit.ts
|
|
148399
147665
|
var import_node_child_process4 = require("node:child_process");
|
|
148400
|
-
var
|
|
147666
|
+
var import_node_fs10 = require("node:fs");
|
|
148401
147667
|
init_graph();
|
|
148402
147668
|
function runGit(projectRoot, args2) {
|
|
148403
147669
|
return new Promise((resolve2) => {
|
|
@@ -148532,7 +147798,7 @@ async function analyzeKnowledgeImpacts(params) {
|
|
|
148532
147798
|
const changedFiles = await getChangedFiles(params.projectRoot, params.mode);
|
|
148533
147799
|
const knowledgeChangedFiles = changedFiles.filter((filePath) => filePath.startsWith("docyrus/knowledge/"));
|
|
148534
147800
|
const diffStats = await getDiffStats(params.projectRoot, params.mode);
|
|
148535
|
-
if (!params.knowledgeDir || !(0,
|
|
147801
|
+
if (!params.knowledgeDir || !(0, import_node_fs10.existsSync)(params.knowledgeDir)) {
|
|
148536
147802
|
return {
|
|
148537
147803
|
ok: true,
|
|
148538
147804
|
mode: params.mode,
|
|
@@ -148638,7 +147904,7 @@ async function analyzeKnowledgeImpacts(params) {
|
|
|
148638
147904
|
};
|
|
148639
147905
|
}
|
|
148640
147906
|
async function analyzeKnowledgeDoctor(params) {
|
|
148641
|
-
if (!params.knowledgeDir || !(0,
|
|
147907
|
+
if (!params.knowledgeDir || !(0, import_node_fs10.existsSync)(params.knowledgeDir)) {
|
|
148642
147908
|
return {
|
|
148643
147909
|
ok: false,
|
|
148644
147910
|
warnings: [{
|
|
@@ -148725,6 +147991,786 @@ async function analyzeKnowledgeDoctor(params) {
|
|
|
148725
147991
|
};
|
|
148726
147992
|
}
|
|
148727
147993
|
|
|
147994
|
+
// src/project-plan/graph.ts
|
|
147995
|
+
var import_node_crypto5 = require("node:crypto");
|
|
147996
|
+
var import_node_fs12 = require("node:fs");
|
|
147997
|
+
var import_promises15 = __toESM(require("node:fs/promises"));
|
|
147998
|
+
var import_node_path19 = __toESM(require("node:path"));
|
|
147999
|
+
|
|
148000
|
+
// src/project-plan/localTodos.ts
|
|
148001
|
+
var import_node_crypto4 = __toESM(require("node:crypto"));
|
|
148002
|
+
var import_node_fs11 = require("node:fs");
|
|
148003
|
+
var import_promises14 = __toESM(require("node:fs/promises"));
|
|
148004
|
+
var import_node_path18 = __toESM(require("node:path"));
|
|
148005
|
+
var TODO_DIR_NAME = ".pi/todos";
|
|
148006
|
+
var TODO_PATH_ENV = "PI_TODO_PATH";
|
|
148007
|
+
function resolveTodosDirectory(root) {
|
|
148008
|
+
const overridePath = process.env[TODO_PATH_ENV]?.trim();
|
|
148009
|
+
if (overridePath) {
|
|
148010
|
+
return import_node_path18.default.resolve(root, overridePath);
|
|
148011
|
+
}
|
|
148012
|
+
return import_node_path18.default.resolve(root, TODO_DIR_NAME);
|
|
148013
|
+
}
|
|
148014
|
+
function getTodoFilePath(todosDir, id) {
|
|
148015
|
+
return import_node_path18.default.join(todosDir, `${id}.md`);
|
|
148016
|
+
}
|
|
148017
|
+
function splitFrontMatter(content3) {
|
|
148018
|
+
if (!content3.startsWith("{")) {
|
|
148019
|
+
return {
|
|
148020
|
+
frontMatter: "",
|
|
148021
|
+
body: content3
|
|
148022
|
+
};
|
|
148023
|
+
}
|
|
148024
|
+
let depth = 0;
|
|
148025
|
+
let inString = false;
|
|
148026
|
+
let escaped = false;
|
|
148027
|
+
let endIndex = -1;
|
|
148028
|
+
for (let index2 = 0; index2 < content3.length; index2 += 1) {
|
|
148029
|
+
const char = content3[index2];
|
|
148030
|
+
if (inString) {
|
|
148031
|
+
if (escaped) {
|
|
148032
|
+
escaped = false;
|
|
148033
|
+
continue;
|
|
148034
|
+
}
|
|
148035
|
+
if (char === "\\") {
|
|
148036
|
+
escaped = true;
|
|
148037
|
+
continue;
|
|
148038
|
+
}
|
|
148039
|
+
if (char === '"') {
|
|
148040
|
+
inString = false;
|
|
148041
|
+
}
|
|
148042
|
+
continue;
|
|
148043
|
+
}
|
|
148044
|
+
if (char === '"') {
|
|
148045
|
+
inString = true;
|
|
148046
|
+
continue;
|
|
148047
|
+
}
|
|
148048
|
+
if (char === "{") {
|
|
148049
|
+
depth += 1;
|
|
148050
|
+
continue;
|
|
148051
|
+
}
|
|
148052
|
+
if (char === "}") {
|
|
148053
|
+
depth -= 1;
|
|
148054
|
+
if (depth === 0) {
|
|
148055
|
+
endIndex = index2;
|
|
148056
|
+
break;
|
|
148057
|
+
}
|
|
148058
|
+
}
|
|
148059
|
+
}
|
|
148060
|
+
if (endIndex === -1) {
|
|
148061
|
+
return {
|
|
148062
|
+
frontMatter: "",
|
|
148063
|
+
body: content3
|
|
148064
|
+
};
|
|
148065
|
+
}
|
|
148066
|
+
return {
|
|
148067
|
+
frontMatter: content3.slice(0, endIndex + 1),
|
|
148068
|
+
body: content3.slice(endIndex + 1).replace(/^\r?\n+/u, "")
|
|
148069
|
+
};
|
|
148070
|
+
}
|
|
148071
|
+
function parseLocalTodoFrontMatter(frontMatter, idFallback) {
|
|
148072
|
+
const base = {
|
|
148073
|
+
id: idFallback,
|
|
148074
|
+
title: "",
|
|
148075
|
+
tags: [],
|
|
148076
|
+
status: "open",
|
|
148077
|
+
created_at: ""
|
|
148078
|
+
};
|
|
148079
|
+
if (!frontMatter.trim()) {
|
|
148080
|
+
return base;
|
|
148081
|
+
}
|
|
148082
|
+
try {
|
|
148083
|
+
const parsed = JSON.parse(frontMatter);
|
|
148084
|
+
return {
|
|
148085
|
+
id: typeof parsed.id === "string" && parsed.id.trim() ? parsed.id.trim() : idFallback,
|
|
148086
|
+
title: typeof parsed.title === "string" ? parsed.title : "",
|
|
148087
|
+
tags: Array.isArray(parsed.tags) ? parsed.tags.filter((value2) => typeof value2 === "string") : [],
|
|
148088
|
+
status: typeof parsed.status === "string" && parsed.status.trim() ? parsed.status.trim() : "open",
|
|
148089
|
+
created_at: typeof parsed.created_at === "string" ? parsed.created_at : "",
|
|
148090
|
+
assigned_to_session: typeof parsed.assigned_to_session === "string" && parsed.assigned_to_session.trim() ? parsed.assigned_to_session.trim() : void 0,
|
|
148091
|
+
parent_task_id: typeof parsed.parent_task_id === "string" && parsed.parent_task_id.trim() ? parsed.parent_task_id.trim() : void 0
|
|
148092
|
+
};
|
|
148093
|
+
} catch {
|
|
148094
|
+
return base;
|
|
148095
|
+
}
|
|
148096
|
+
}
|
|
148097
|
+
function serializeLocalTodo(record2) {
|
|
148098
|
+
const frontMatter = JSON.stringify(
|
|
148099
|
+
{
|
|
148100
|
+
id: record2.id,
|
|
148101
|
+
title: record2.title,
|
|
148102
|
+
tags: record2.tags,
|
|
148103
|
+
status: record2.status,
|
|
148104
|
+
created_at: record2.created_at,
|
|
148105
|
+
assigned_to_session: record2.assigned_to_session || void 0,
|
|
148106
|
+
parent_task_id: record2.parent_task_id || void 0
|
|
148107
|
+
},
|
|
148108
|
+
null,
|
|
148109
|
+
2
|
|
148110
|
+
);
|
|
148111
|
+
const trimmedBody = record2.body.trim();
|
|
148112
|
+
return trimmedBody ? `${frontMatter}
|
|
148113
|
+
|
|
148114
|
+
${trimmedBody}
|
|
148115
|
+
` : `${frontMatter}
|
|
148116
|
+
`;
|
|
148117
|
+
}
|
|
148118
|
+
async function generateTodoId(todosDir) {
|
|
148119
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
148120
|
+
const id = import_node_crypto4.default.randomBytes(4).toString("hex");
|
|
148121
|
+
if (!(0, import_node_fs11.existsSync)(getTodoFilePath(todosDir, id))) {
|
|
148122
|
+
return id;
|
|
148123
|
+
}
|
|
148124
|
+
}
|
|
148125
|
+
throw new Error("Failed to generate linked todo id.");
|
|
148126
|
+
}
|
|
148127
|
+
async function listLinkedTodosByTask(root) {
|
|
148128
|
+
const todosDir = resolveTodosDirectory(root);
|
|
148129
|
+
const result = /* @__PURE__ */ new Map();
|
|
148130
|
+
let entries = [];
|
|
148131
|
+
try {
|
|
148132
|
+
entries = await import_promises14.default.readdir(todosDir);
|
|
148133
|
+
} catch {
|
|
148134
|
+
return result;
|
|
148135
|
+
}
|
|
148136
|
+
for (const entry of entries) {
|
|
148137
|
+
if (!entry.endsWith(".md")) {
|
|
148138
|
+
continue;
|
|
148139
|
+
}
|
|
148140
|
+
const id = entry.slice(0, -3);
|
|
148141
|
+
const filePath = getTodoFilePath(todosDir, id);
|
|
148142
|
+
try {
|
|
148143
|
+
const raw = await import_promises14.default.readFile(filePath, "utf8");
|
|
148144
|
+
const { frontMatter } = splitFrontMatter(raw);
|
|
148145
|
+
const parsed = parseLocalTodoFrontMatter(frontMatter, id);
|
|
148146
|
+
if (!parsed.parent_task_id) {
|
|
148147
|
+
continue;
|
|
148148
|
+
}
|
|
148149
|
+
const existing = result.get(parsed.parent_task_id) || [];
|
|
148150
|
+
existing.push({
|
|
148151
|
+
id,
|
|
148152
|
+
title: parsed.title,
|
|
148153
|
+
status: parsed.status,
|
|
148154
|
+
filePath: import_node_path18.default.relative(root, filePath),
|
|
148155
|
+
parentTaskId: parsed.parent_task_id
|
|
148156
|
+
});
|
|
148157
|
+
result.set(parsed.parent_task_id, existing);
|
|
148158
|
+
} catch {
|
|
148159
|
+
}
|
|
148160
|
+
}
|
|
148161
|
+
for (const linkedTodos of result.values()) {
|
|
148162
|
+
linkedTodos.sort((left, right) => left.title.localeCompare(right.title) || left.id.localeCompare(right.id));
|
|
148163
|
+
}
|
|
148164
|
+
return result;
|
|
148165
|
+
}
|
|
148166
|
+
async function createLinkedTodo(params) {
|
|
148167
|
+
const todosDir = resolveTodosDirectory(params.root);
|
|
148168
|
+
await import_promises14.default.mkdir(todosDir, {
|
|
148169
|
+
recursive: true
|
|
148170
|
+
});
|
|
148171
|
+
const id = await generateTodoId(todosDir);
|
|
148172
|
+
const filePath = getTodoFilePath(todosDir, id);
|
|
148173
|
+
const todo = {
|
|
148174
|
+
id,
|
|
148175
|
+
title: params.title,
|
|
148176
|
+
tags: [],
|
|
148177
|
+
status: "open",
|
|
148178
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
148179
|
+
parent_task_id: params.parentTaskId,
|
|
148180
|
+
body: params.body ?? ""
|
|
148181
|
+
};
|
|
148182
|
+
await import_promises14.default.writeFile(filePath, serializeLocalTodo(todo), "utf8");
|
|
148183
|
+
return {
|
|
148184
|
+
id,
|
|
148185
|
+
title: todo.title,
|
|
148186
|
+
status: todo.status,
|
|
148187
|
+
filePath: import_node_path18.default.relative(params.root, filePath),
|
|
148188
|
+
parentTaskId: params.parentTaskId
|
|
148189
|
+
};
|
|
148190
|
+
}
|
|
148191
|
+
|
|
148192
|
+
// src/project-plan/types.ts
|
|
148193
|
+
var PROJECT_TASK_TYPES = [
|
|
148194
|
+
"bug-fix",
|
|
148195
|
+
"new-implementation",
|
|
148196
|
+
"api-test",
|
|
148197
|
+
"browser-automation-test",
|
|
148198
|
+
"work"
|
|
148199
|
+
];
|
|
148200
|
+
var PROJECT_TASK_ASSIGNEES = [
|
|
148201
|
+
"agent",
|
|
148202
|
+
"user"
|
|
148203
|
+
];
|
|
148204
|
+
var PROJECT_TASK_STATUSES = [
|
|
148205
|
+
"planned",
|
|
148206
|
+
"in_progress",
|
|
148207
|
+
"blocked",
|
|
148208
|
+
"done"
|
|
148209
|
+
];
|
|
148210
|
+
|
|
148211
|
+
// src/project-plan/graph.ts
|
|
148212
|
+
var PROJECT_PLAN_DIR_SEGMENTS = ["docyrus", "project-plan"];
|
|
148213
|
+
var PROJECT_PLAN_JSON_FILE_NAME = "project-plan.json";
|
|
148214
|
+
var PROJECT_PLAN_MARKDOWN_FILE_NAME = "PROJECT_PLAN.md";
|
|
148215
|
+
var KNOWLEDGE_FEATURES_PATH_SEGMENTS = ["docyrus", "knowledge", "features", "features.md"];
|
|
148216
|
+
var FEATURES_MARKER_BEGIN = "<!-- docyrus-project-plan:features:begin -->";
|
|
148217
|
+
var FEATURES_MARKER_END = "<!-- docyrus-project-plan:features:end -->";
|
|
148218
|
+
function isRecord3(value2) {
|
|
148219
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
148220
|
+
}
|
|
148221
|
+
function isNonEmptyString(value2) {
|
|
148222
|
+
return typeof value2 === "string" && value2.trim().length > 0;
|
|
148223
|
+
}
|
|
148224
|
+
function normalizeStringArray(value2) {
|
|
148225
|
+
if (!Array.isArray(value2)) {
|
|
148226
|
+
return [];
|
|
148227
|
+
}
|
|
148228
|
+
return value2.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
148229
|
+
}
|
|
148230
|
+
function slugify2(value2) {
|
|
148231
|
+
const slug = value2.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 80);
|
|
148232
|
+
return slug || "item";
|
|
148233
|
+
}
|
|
148234
|
+
function hashParts(parts2) {
|
|
148235
|
+
return (0, import_node_crypto5.createHash)("sha1").update(parts2.join("::")).digest("hex").slice(0, 12);
|
|
148236
|
+
}
|
|
148237
|
+
function normalizeSectionId(slug) {
|
|
148238
|
+
return `section-${hashParts([slug])}`;
|
|
148239
|
+
}
|
|
148240
|
+
function normalizeFeatureId(sectionId, slug) {
|
|
148241
|
+
return `feature-${hashParts([sectionId, slug])}`;
|
|
148242
|
+
}
|
|
148243
|
+
function normalizeTaskId(featureId, type, title) {
|
|
148244
|
+
return `task-${hashParts([featureId, type, slugify2(title)])}`;
|
|
148245
|
+
}
|
|
148246
|
+
function compareStrings(left, right) {
|
|
148247
|
+
return left.localeCompare(right);
|
|
148248
|
+
}
|
|
148249
|
+
function sortGraph(graph) {
|
|
148250
|
+
return {
|
|
148251
|
+
version: 1,
|
|
148252
|
+
sections: [...graph.sections].sort((left, right) => compareStrings(left.id, right.id)),
|
|
148253
|
+
features: [...graph.features].sort((left, right) => {
|
|
148254
|
+
return compareStrings(left.sectionId, right.sectionId) || compareStrings(left.title, right.title) || compareStrings(left.id, right.id);
|
|
148255
|
+
}),
|
|
148256
|
+
tasks: [...graph.tasks].sort((left, right) => {
|
|
148257
|
+
return compareStrings(left.sectionId, right.sectionId) || compareStrings(left.featureId, right.featureId) || compareStrings(left.title, right.title) || compareStrings(left.id, right.id);
|
|
148258
|
+
})
|
|
148259
|
+
};
|
|
148260
|
+
}
|
|
148261
|
+
function resolveProjectPlanDirectory(root) {
|
|
148262
|
+
return import_node_path19.default.join(root, ...PROJECT_PLAN_DIR_SEGMENTS);
|
|
148263
|
+
}
|
|
148264
|
+
function resolveProjectPlanGraphPath(root) {
|
|
148265
|
+
return import_node_path19.default.join(resolveProjectPlanDirectory(root), PROJECT_PLAN_JSON_FILE_NAME);
|
|
148266
|
+
}
|
|
148267
|
+
function resolveProjectPlanMarkdownPath(root) {
|
|
148268
|
+
return import_node_path19.default.join(resolveProjectPlanDirectory(root), PROJECT_PLAN_MARKDOWN_FILE_NAME);
|
|
148269
|
+
}
|
|
148270
|
+
function createEmptyProjectPlanGraph() {
|
|
148271
|
+
return {
|
|
148272
|
+
version: 1,
|
|
148273
|
+
sections: [],
|
|
148274
|
+
features: [],
|
|
148275
|
+
tasks: []
|
|
148276
|
+
};
|
|
148277
|
+
}
|
|
148278
|
+
function parseProjectPlanGraph(rawValue) {
|
|
148279
|
+
if (!isRecord3(rawValue)) {
|
|
148280
|
+
return createEmptyProjectPlanGraph();
|
|
148281
|
+
}
|
|
148282
|
+
const sections = Array.isArray(rawValue.sections) ? rawValue.sections.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
148283
|
+
id: isNonEmptyString(value2.id) ? value2.id.trim() : "",
|
|
148284
|
+
title: isNonEmptyString(value2.title) ? value2.title.trim() : "",
|
|
148285
|
+
slug: isNonEmptyString(value2.slug) ? value2.slug.trim() : "",
|
|
148286
|
+
summary: typeof value2.summary === "string" ? value2.summary.trim() : ""
|
|
148287
|
+
})).filter((value2) => value2.id.length > 0) : [];
|
|
148288
|
+
const features = Array.isArray(rawValue.features) ? rawValue.features.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
148289
|
+
id: isNonEmptyString(value2.id) ? value2.id.trim() : "",
|
|
148290
|
+
title: isNonEmptyString(value2.title) ? value2.title.trim() : "",
|
|
148291
|
+
slug: isNonEmptyString(value2.slug) ? value2.slug.trim() : "",
|
|
148292
|
+
summary: typeof value2.summary === "string" ? value2.summary.trim() : "",
|
|
148293
|
+
sectionId: isNonEmptyString(value2.sectionId) ? value2.sectionId.trim() : ""
|
|
148294
|
+
})).filter((value2) => value2.id.length > 0) : [];
|
|
148295
|
+
const tasks = Array.isArray(rawValue.tasks) ? rawValue.tasks.filter((value2) => isRecord3(value2)).map((value2) => ({
|
|
148296
|
+
id: isNonEmptyString(value2.id) ? value2.id.trim() : "",
|
|
148297
|
+
title: isNonEmptyString(value2.title) ? value2.title.trim() : "",
|
|
148298
|
+
summary: typeof value2.summary === "string" ? value2.summary.trim() : "",
|
|
148299
|
+
type: typeof value2.type === "string" ? value2.type : "work",
|
|
148300
|
+
assignee: typeof value2.assignee === "string" ? value2.assignee : "agent",
|
|
148301
|
+
status: typeof value2.status === "string" ? value2.status : "planned",
|
|
148302
|
+
acceptanceCriteria: normalizeStringArray(value2.acceptanceCriteria),
|
|
148303
|
+
featureId: isNonEmptyString(value2.featureId) ? value2.featureId.trim() : "",
|
|
148304
|
+
sectionId: isNonEmptyString(value2.sectionId) ? value2.sectionId.trim() : ""
|
|
148305
|
+
})).filter((value2) => value2.id.length > 0) : [];
|
|
148306
|
+
return sortGraph({
|
|
148307
|
+
version: 1,
|
|
148308
|
+
sections,
|
|
148309
|
+
features,
|
|
148310
|
+
tasks
|
|
148311
|
+
});
|
|
148312
|
+
}
|
|
148313
|
+
async function readProjectPlanGraph(root) {
|
|
148314
|
+
const graphPath = resolveProjectPlanGraphPath(root);
|
|
148315
|
+
if (!(0, import_node_fs12.existsSync)(graphPath)) {
|
|
148316
|
+
return createEmptyProjectPlanGraph();
|
|
148317
|
+
}
|
|
148318
|
+
const raw = await import_promises15.default.readFile(graphPath, "utf8");
|
|
148319
|
+
return parseProjectPlanGraph(JSON.parse(raw));
|
|
148320
|
+
}
|
|
148321
|
+
function deriveFeatureStatus(tasks) {
|
|
148322
|
+
if (tasks.length === 0) {
|
|
148323
|
+
return "planned";
|
|
148324
|
+
}
|
|
148325
|
+
if (tasks.every((task) => task.status === "done")) {
|
|
148326
|
+
return "done";
|
|
148327
|
+
}
|
|
148328
|
+
if (tasks.some((task) => task.status === "in_progress")) {
|
|
148329
|
+
return "in_progress";
|
|
148330
|
+
}
|
|
148331
|
+
if (tasks.some((task) => task.status === "blocked")) {
|
|
148332
|
+
return "blocked";
|
|
148333
|
+
}
|
|
148334
|
+
return "planned";
|
|
148335
|
+
}
|
|
148336
|
+
function deriveSectionStatus(features) {
|
|
148337
|
+
if (features.length === 0) {
|
|
148338
|
+
return "planned";
|
|
148339
|
+
}
|
|
148340
|
+
if (features.every((feature) => feature.status === "done")) {
|
|
148341
|
+
return "done";
|
|
148342
|
+
}
|
|
148343
|
+
if (features.some((feature) => feature.status === "in_progress")) {
|
|
148344
|
+
return "in_progress";
|
|
148345
|
+
}
|
|
148346
|
+
if (features.some((feature) => feature.status === "blocked")) {
|
|
148347
|
+
return "blocked";
|
|
148348
|
+
}
|
|
148349
|
+
return "planned";
|
|
148350
|
+
}
|
|
148351
|
+
async function buildProjectPlanHierarchy(root, graph) {
|
|
148352
|
+
const currentGraph = graph ?? await readProjectPlanGraph(root);
|
|
148353
|
+
const linkedTodos = await listLinkedTodosByTask(root);
|
|
148354
|
+
const featureMap = /* @__PURE__ */ new Map();
|
|
148355
|
+
for (const feature of currentGraph.features) {
|
|
148356
|
+
const featureTasks = currentGraph.tasks.filter((task) => task.featureId === feature.id).map((task) => {
|
|
148357
|
+
const taskLinkedTodos = linkedTodos.get(task.id) || [];
|
|
148358
|
+
return {
|
|
148359
|
+
...task,
|
|
148360
|
+
linkedTodos: taskLinkedTodos,
|
|
148361
|
+
linkedTodoCount: taskLinkedTodos.length
|
|
148362
|
+
};
|
|
148363
|
+
});
|
|
148364
|
+
featureMap.set(feature.id, {
|
|
148365
|
+
...feature,
|
|
148366
|
+
status: deriveFeatureStatus(featureTasks),
|
|
148367
|
+
taskCount: featureTasks.length,
|
|
148368
|
+
tasks: featureTasks
|
|
148369
|
+
});
|
|
148370
|
+
}
|
|
148371
|
+
const sections = currentGraph.sections.map((section2) => {
|
|
148372
|
+
const features = currentGraph.features.filter((feature) => feature.sectionId === section2.id).map((feature) => featureMap.get(feature.id)).filter((feature) => Boolean(feature));
|
|
148373
|
+
const taskCount = features.reduce((count, feature) => count + feature.taskCount, 0);
|
|
148374
|
+
return {
|
|
148375
|
+
id: section2.id,
|
|
148376
|
+
title: section2.title,
|
|
148377
|
+
slug: section2.slug,
|
|
148378
|
+
summary: section2.summary,
|
|
148379
|
+
status: deriveSectionStatus(features),
|
|
148380
|
+
featureCount: features.length,
|
|
148381
|
+
taskCount,
|
|
148382
|
+
features
|
|
148383
|
+
};
|
|
148384
|
+
});
|
|
148385
|
+
return {
|
|
148386
|
+
sections
|
|
148387
|
+
};
|
|
148388
|
+
}
|
|
148389
|
+
function formatAcceptanceCriteria(criteria) {
|
|
148390
|
+
if (criteria.length === 0) {
|
|
148391
|
+
return ["- None yet"];
|
|
148392
|
+
}
|
|
148393
|
+
return criteria.map((item) => `- ${item}`);
|
|
148394
|
+
}
|
|
148395
|
+
async function renderProjectPlanMarkdown(root, graph) {
|
|
148396
|
+
const hierarchy = await buildProjectPlanHierarchy(root, graph);
|
|
148397
|
+
const lines = [
|
|
148398
|
+
"# Project Plan",
|
|
148399
|
+
"",
|
|
148400
|
+
"This file is derived from `docyrus/project-plan/project-plan.json`.",
|
|
148401
|
+
""
|
|
148402
|
+
];
|
|
148403
|
+
const populatedSections = hierarchy.sections.filter((section2) => section2.features.length > 0);
|
|
148404
|
+
if (populatedSections.length === 0) {
|
|
148405
|
+
lines.push("No planned features or tasks yet.");
|
|
148406
|
+
lines.push("");
|
|
148407
|
+
return `${lines.join("\n")}`;
|
|
148408
|
+
}
|
|
148409
|
+
for (const section2 of populatedSections) {
|
|
148410
|
+
lines.push(`## ${section2.title}`);
|
|
148411
|
+
lines.push("");
|
|
148412
|
+
lines.push(`- Section ID: \`${section2.id}\``);
|
|
148413
|
+
lines.push(`- Status: \`${section2.status}\``);
|
|
148414
|
+
lines.push(`- Features: ${section2.featureCount}`);
|
|
148415
|
+
lines.push(`- Tasks: ${section2.taskCount}`);
|
|
148416
|
+
lines.push("");
|
|
148417
|
+
for (const feature of section2.features) {
|
|
148418
|
+
lines.push(`### ${feature.title}`);
|
|
148419
|
+
lines.push("");
|
|
148420
|
+
lines.push(`- Feature ID: \`${feature.id}\``);
|
|
148421
|
+
lines.push(`- Status: \`${feature.status}\``);
|
|
148422
|
+
lines.push(`- Slug: \`${feature.slug}\``);
|
|
148423
|
+
if (feature.summary) {
|
|
148424
|
+
lines.push(`- Summary: ${feature.summary}`);
|
|
148425
|
+
}
|
|
148426
|
+
lines.push("");
|
|
148427
|
+
for (const task of feature.tasks) {
|
|
148428
|
+
lines.push(`#### ${task.title}`);
|
|
148429
|
+
lines.push("");
|
|
148430
|
+
lines.push(`- Task ID: \`${task.id}\``);
|
|
148431
|
+
lines.push(`- Type: \`${task.type}\``);
|
|
148432
|
+
lines.push(`- Assignee: \`${task.assignee}\``);
|
|
148433
|
+
lines.push(`- Status: \`${task.status}\``);
|
|
148434
|
+
if (task.summary) {
|
|
148435
|
+
lines.push(`- Summary: ${task.summary}`);
|
|
148436
|
+
}
|
|
148437
|
+
lines.push("- Acceptance Criteria:");
|
|
148438
|
+
lines.push(...formatAcceptanceCriteria(task.acceptanceCriteria));
|
|
148439
|
+
lines.push("");
|
|
148440
|
+
}
|
|
148441
|
+
}
|
|
148442
|
+
}
|
|
148443
|
+
return `${lines.join("\n").trimEnd()}
|
|
148444
|
+
`;
|
|
148445
|
+
}
|
|
148446
|
+
function buildKnowledgeFeaturesSection(graph) {
|
|
148447
|
+
const sectionMap = new Map(graph.sections.map((section2) => [section2.id, section2]));
|
|
148448
|
+
const featuresBySection = /* @__PURE__ */ new Map();
|
|
148449
|
+
for (const feature of graph.features) {
|
|
148450
|
+
const list4 = featuresBySection.get(feature.sectionId) || [];
|
|
148451
|
+
list4.push(feature);
|
|
148452
|
+
featuresBySection.set(feature.sectionId, list4);
|
|
148453
|
+
}
|
|
148454
|
+
const lines = [
|
|
148455
|
+
"## Planned Features",
|
|
148456
|
+
"",
|
|
148457
|
+
"Features tracked in the project plan.",
|
|
148458
|
+
""
|
|
148459
|
+
];
|
|
148460
|
+
if (graph.features.length === 0) {
|
|
148461
|
+
lines.push("No planned features yet.");
|
|
148462
|
+
lines.push("");
|
|
148463
|
+
return lines.join("\n");
|
|
148464
|
+
}
|
|
148465
|
+
for (const section2 of graph.sections) {
|
|
148466
|
+
const features = featuresBySection.get(section2.id);
|
|
148467
|
+
if (!features || features.length === 0) {
|
|
148468
|
+
continue;
|
|
148469
|
+
}
|
|
148470
|
+
lines.push(`### ${section2.title}`);
|
|
148471
|
+
lines.push("");
|
|
148472
|
+
for (const feature of features) {
|
|
148473
|
+
const summary = feature.summary ? ` \u2014 ${feature.summary}` : "";
|
|
148474
|
+
lines.push(`- **${feature.title}**${summary}`);
|
|
148475
|
+
}
|
|
148476
|
+
lines.push("");
|
|
148477
|
+
}
|
|
148478
|
+
const ungrouped = graph.features.filter((feature) => !sectionMap.has(feature.sectionId));
|
|
148479
|
+
if (ungrouped.length > 0) {
|
|
148480
|
+
for (const feature of ungrouped) {
|
|
148481
|
+
const summary = feature.summary ? ` \u2014 ${feature.summary}` : "";
|
|
148482
|
+
lines.push(`- **${feature.title}**${summary}`);
|
|
148483
|
+
}
|
|
148484
|
+
lines.push("");
|
|
148485
|
+
}
|
|
148486
|
+
return lines.join("\n");
|
|
148487
|
+
}
|
|
148488
|
+
async function syncFeaturesToKnowledge(root, graph) {
|
|
148489
|
+
const featuresPath = import_node_path19.default.join(root, ...KNOWLEDGE_FEATURES_PATH_SEGMENTS);
|
|
148490
|
+
if (!(0, import_node_fs12.existsSync)(featuresPath)) {
|
|
148491
|
+
return;
|
|
148492
|
+
}
|
|
148493
|
+
const content3 = buildKnowledgeFeaturesSection(graph);
|
|
148494
|
+
const wrapped = `${FEATURES_MARKER_BEGIN}
|
|
148495
|
+
${content3.trimEnd()}
|
|
148496
|
+
|
|
148497
|
+
${FEATURES_MARKER_END}
|
|
148498
|
+
`;
|
|
148499
|
+
const current = await import_promises15.default.readFile(featuresPath, "utf8");
|
|
148500
|
+
const beginIndex = current.indexOf(FEATURES_MARKER_BEGIN);
|
|
148501
|
+
const endIndex = current.indexOf(FEATURES_MARKER_END);
|
|
148502
|
+
if (beginIndex !== -1 && endIndex !== -1 && endIndex > beginIndex) {
|
|
148503
|
+
const replaceEnd = current[endIndex + FEATURES_MARKER_END.length] === "\n" ? endIndex + FEATURES_MARKER_END.length + 1 : endIndex + FEATURES_MARKER_END.length;
|
|
148504
|
+
const next = `${current.slice(0, beginIndex)}${wrapped}${current.slice(replaceEnd)}`;
|
|
148505
|
+
if (next !== current) {
|
|
148506
|
+
await import_promises15.default.writeFile(featuresPath, next, "utf8");
|
|
148507
|
+
}
|
|
148508
|
+
return;
|
|
148509
|
+
}
|
|
148510
|
+
const separator = current.endsWith("\n") ? "\n" : "\n\n";
|
|
148511
|
+
await import_promises15.default.writeFile(featuresPath, `${current}${separator}${wrapped}`, "utf8");
|
|
148512
|
+
}
|
|
148513
|
+
async function writeProjectPlanFiles(root, graph) {
|
|
148514
|
+
const graphPath = resolveProjectPlanGraphPath(root);
|
|
148515
|
+
const markdownPath = resolveProjectPlanMarkdownPath(root);
|
|
148516
|
+
await import_promises15.default.mkdir(import_node_path19.default.dirname(graphPath), {
|
|
148517
|
+
recursive: true
|
|
148518
|
+
});
|
|
148519
|
+
const sortedGraph = sortGraph(graph);
|
|
148520
|
+
await import_promises15.default.writeFile(graphPath, `${JSON.stringify(sortedGraph, null, 2)}
|
|
148521
|
+
`, "utf8");
|
|
148522
|
+
await import_promises15.default.writeFile(markdownPath, await renderProjectPlanMarkdown(root, sortedGraph), "utf8");
|
|
148523
|
+
await syncFeaturesToKnowledge(root, sortedGraph);
|
|
148524
|
+
return {
|
|
148525
|
+
graph: sortedGraph,
|
|
148526
|
+
graphPath,
|
|
148527
|
+
markdownPath
|
|
148528
|
+
};
|
|
148529
|
+
}
|
|
148530
|
+
function buildProjectPlanCheckError(code, message, target) {
|
|
148531
|
+
return {
|
|
148532
|
+
code,
|
|
148533
|
+
message,
|
|
148534
|
+
target
|
|
148535
|
+
};
|
|
148536
|
+
}
|
|
148537
|
+
async function validateProjectPlanGraph(root, graph) {
|
|
148538
|
+
const currentGraph = graph ?? await readProjectPlanGraph(root);
|
|
148539
|
+
const errors = [];
|
|
148540
|
+
const sectionIds = /* @__PURE__ */ new Set();
|
|
148541
|
+
const featureIds = /* @__PURE__ */ new Set();
|
|
148542
|
+
const featureMap = /* @__PURE__ */ new Map();
|
|
148543
|
+
for (const section2 of currentGraph.sections) {
|
|
148544
|
+
if (!section2.id) {
|
|
148545
|
+
errors.push(buildProjectPlanCheckError("section_missing_id", "Project plan section is missing `id`."));
|
|
148546
|
+
continue;
|
|
148547
|
+
}
|
|
148548
|
+
if (sectionIds.has(section2.id)) {
|
|
148549
|
+
errors.push(buildProjectPlanCheckError("duplicate_section", `Duplicate section id "${section2.id}"`, section2.id));
|
|
148550
|
+
continue;
|
|
148551
|
+
}
|
|
148552
|
+
sectionIds.add(section2.id);
|
|
148553
|
+
if (!section2.title.trim()) {
|
|
148554
|
+
errors.push(buildProjectPlanCheckError("section_missing_title", `Section "${section2.id}" is missing a title.`, section2.id));
|
|
148555
|
+
}
|
|
148556
|
+
if (!section2.slug.trim()) {
|
|
148557
|
+
errors.push(buildProjectPlanCheckError("section_missing_slug", `Section "${section2.id}" is missing a slug.`, section2.id));
|
|
148558
|
+
}
|
|
148559
|
+
}
|
|
148560
|
+
const allowedTypes = new Set(PROJECT_TASK_TYPES);
|
|
148561
|
+
const allowedAssignees = new Set(PROJECT_TASK_ASSIGNEES);
|
|
148562
|
+
const allowedStatuses = new Set(PROJECT_TASK_STATUSES);
|
|
148563
|
+
for (const feature of currentGraph.features) {
|
|
148564
|
+
if (!feature.id) {
|
|
148565
|
+
errors.push(buildProjectPlanCheckError("feature_missing_id", "Project plan feature is missing `id`."));
|
|
148566
|
+
continue;
|
|
148567
|
+
}
|
|
148568
|
+
if (featureIds.has(feature.id)) {
|
|
148569
|
+
errors.push(buildProjectPlanCheckError("duplicate_feature", `Duplicate feature id "${feature.id}"`, feature.id));
|
|
148570
|
+
continue;
|
|
148571
|
+
}
|
|
148572
|
+
featureIds.add(feature.id);
|
|
148573
|
+
featureMap.set(feature.id, feature);
|
|
148574
|
+
if (!feature.sectionId) {
|
|
148575
|
+
errors.push(buildProjectPlanCheckError("feature_missing_section", `Feature "${feature.id}" is missing \`sectionId\`.`, feature.id));
|
|
148576
|
+
continue;
|
|
148577
|
+
}
|
|
148578
|
+
if (!sectionIds.has(feature.sectionId)) {
|
|
148579
|
+
errors.push(buildProjectPlanCheckError(
|
|
148580
|
+
"feature_unknown_section",
|
|
148581
|
+
`Feature "${feature.id}" references unknown section "${feature.sectionId}".`,
|
|
148582
|
+
feature.id
|
|
148583
|
+
));
|
|
148584
|
+
}
|
|
148585
|
+
if (!feature.title.trim()) {
|
|
148586
|
+
errors.push(buildProjectPlanCheckError("feature_missing_title", `Feature "${feature.id}" is missing a title.`, feature.id));
|
|
148587
|
+
}
|
|
148588
|
+
if (!feature.slug.trim()) {
|
|
148589
|
+
errors.push(buildProjectPlanCheckError("feature_missing_slug", `Feature "${feature.id}" is missing a slug.`, feature.id));
|
|
148590
|
+
}
|
|
148591
|
+
}
|
|
148592
|
+
const taskIds = /* @__PURE__ */ new Set();
|
|
148593
|
+
for (const task of currentGraph.tasks) {
|
|
148594
|
+
if (!task.id) {
|
|
148595
|
+
errors.push(buildProjectPlanCheckError("task_missing_id", "Project plan task is missing `id`."));
|
|
148596
|
+
continue;
|
|
148597
|
+
}
|
|
148598
|
+
if (taskIds.has(task.id)) {
|
|
148599
|
+
errors.push(buildProjectPlanCheckError("duplicate_task", `Duplicate task id "${task.id}"`, task.id));
|
|
148600
|
+
continue;
|
|
148601
|
+
}
|
|
148602
|
+
taskIds.add(task.id);
|
|
148603
|
+
const feature = featureMap.get(task.featureId);
|
|
148604
|
+
if (!feature) {
|
|
148605
|
+
errors.push(buildProjectPlanCheckError(
|
|
148606
|
+
"task_unknown_feature",
|
|
148607
|
+
`Task "${task.id}" references unknown feature "${task.featureId}".`,
|
|
148608
|
+
task.id
|
|
148609
|
+
));
|
|
148610
|
+
continue;
|
|
148611
|
+
}
|
|
148612
|
+
if (!task.title.trim()) {
|
|
148613
|
+
errors.push(buildProjectPlanCheckError("task_missing_title", `Task "${task.id}" is missing a title.`, task.id));
|
|
148614
|
+
}
|
|
148615
|
+
if (!allowedTypes.has(task.type)) {
|
|
148616
|
+
errors.push(buildProjectPlanCheckError(
|
|
148617
|
+
"task_invalid_type",
|
|
148618
|
+
`Task "${task.id}" has invalid type "${task.type}".`,
|
|
148619
|
+
task.id
|
|
148620
|
+
));
|
|
148621
|
+
}
|
|
148622
|
+
if (!allowedAssignees.has(task.assignee)) {
|
|
148623
|
+
errors.push(buildProjectPlanCheckError(
|
|
148624
|
+
"task_invalid_assignee",
|
|
148625
|
+
`Task "${task.id}" has invalid assignee "${task.assignee}".`,
|
|
148626
|
+
task.id
|
|
148627
|
+
));
|
|
148628
|
+
}
|
|
148629
|
+
if (!allowedStatuses.has(task.status)) {
|
|
148630
|
+
errors.push(buildProjectPlanCheckError(
|
|
148631
|
+
"task_invalid_status",
|
|
148632
|
+
`Task "${task.id}" has invalid status "${task.status}".`,
|
|
148633
|
+
task.id
|
|
148634
|
+
));
|
|
148635
|
+
}
|
|
148636
|
+
if (!sectionIds.has(task.sectionId)) {
|
|
148637
|
+
errors.push(buildProjectPlanCheckError(
|
|
148638
|
+
"task_unknown_section",
|
|
148639
|
+
`Task "${task.id}" references unknown section "${task.sectionId}".`,
|
|
148640
|
+
task.id
|
|
148641
|
+
));
|
|
148642
|
+
}
|
|
148643
|
+
if (task.sectionId !== feature.sectionId) {
|
|
148644
|
+
errors.push(buildProjectPlanCheckError(
|
|
148645
|
+
"task_section_mismatch",
|
|
148646
|
+
`Task "${task.id}" section "${task.sectionId}" does not match feature "${feature.id}" section "${feature.sectionId}".`,
|
|
148647
|
+
task.id
|
|
148648
|
+
));
|
|
148649
|
+
}
|
|
148650
|
+
}
|
|
148651
|
+
return {
|
|
148652
|
+
ok: errors.length === 0,
|
|
148653
|
+
errors
|
|
148654
|
+
};
|
|
148655
|
+
}
|
|
148656
|
+
async function ensureProjectPlanGraph(root) {
|
|
148657
|
+
const graphPath = resolveProjectPlanGraphPath(root);
|
|
148658
|
+
if (!(0, import_node_fs12.existsSync)(graphPath)) {
|
|
148659
|
+
return writeProjectPlanFiles(root, createEmptyProjectPlanGraph());
|
|
148660
|
+
}
|
|
148661
|
+
const graph = await readProjectPlanGraph(root);
|
|
148662
|
+
return writeProjectPlanFiles(root, graph);
|
|
148663
|
+
}
|
|
148664
|
+
async function upsertProjectPlanSection(params) {
|
|
148665
|
+
const state = await ensureProjectPlanGraph(params.root);
|
|
148666
|
+
const slug = slugify2(params.slug?.trim() || params.title);
|
|
148667
|
+
const sectionId = params.id?.trim() || normalizeSectionId(slug);
|
|
148668
|
+
const graph = state.graph;
|
|
148669
|
+
const existing = graph.sections.find((section2) => section2.id === sectionId) || graph.sections.find((section2) => section2.slug === slug);
|
|
148670
|
+
const nextSection = {
|
|
148671
|
+
id: existing?.id || sectionId,
|
|
148672
|
+
title: params.title.trim(),
|
|
148673
|
+
slug,
|
|
148674
|
+
summary: params.summary?.trim() || ""
|
|
148675
|
+
};
|
|
148676
|
+
const nextSections = existing ? graph.sections.map((section2) => section2.id === existing.id ? nextSection : section2) : [...graph.sections, nextSection];
|
|
148677
|
+
await writeProjectPlanFiles(params.root, {
|
|
148678
|
+
...graph,
|
|
148679
|
+
sections: nextSections
|
|
148680
|
+
});
|
|
148681
|
+
return nextSection;
|
|
148682
|
+
}
|
|
148683
|
+
async function ensureDefaultProjectPlanSections(root) {
|
|
148684
|
+
const features = await upsertProjectPlanSection({ root, title: "Features", slug: "features" });
|
|
148685
|
+
const testing = await upsertProjectPlanSection({ root, title: "Testing", slug: "testing" });
|
|
148686
|
+
const architecture = await upsertProjectPlanSection({ root, title: "Architecture", slug: "architecture" });
|
|
148687
|
+
const workflows = await upsertProjectPlanSection({ root, title: "Workflows", slug: "workflows" });
|
|
148688
|
+
return {
|
|
148689
|
+
featuresSectionId: features.id,
|
|
148690
|
+
testingSectionId: testing.id,
|
|
148691
|
+
architectureSectionId: architecture.id,
|
|
148692
|
+
workflowsSectionId: workflows.id
|
|
148693
|
+
};
|
|
148694
|
+
}
|
|
148695
|
+
async function upsertProjectPlanFeature(params) {
|
|
148696
|
+
const state = await ensureProjectPlanGraph(params.root);
|
|
148697
|
+
const slug = slugify2(params.slug?.trim() || params.title);
|
|
148698
|
+
const featureId = params.featureId?.trim() || normalizeFeatureId(params.sectionId, slug);
|
|
148699
|
+
const graph = state.graph;
|
|
148700
|
+
const existing = graph.features.find((feature) => feature.id === featureId) || graph.features.find((feature) => feature.sectionId === params.sectionId && feature.slug === slug);
|
|
148701
|
+
const nextFeature = {
|
|
148702
|
+
id: existing?.id || featureId,
|
|
148703
|
+
title: params.title.trim(),
|
|
148704
|
+
slug,
|
|
148705
|
+
summary: params.summary?.trim() || "",
|
|
148706
|
+
sectionId: params.sectionId
|
|
148707
|
+
};
|
|
148708
|
+
const nextFeatures = existing ? graph.features.map((feature) => feature.id === existing.id ? nextFeature : feature) : [...graph.features, nextFeature];
|
|
148709
|
+
await writeProjectPlanFiles(params.root, {
|
|
148710
|
+
...graph,
|
|
148711
|
+
features: nextFeatures
|
|
148712
|
+
});
|
|
148713
|
+
return nextFeature;
|
|
148714
|
+
}
|
|
148715
|
+
async function getProjectPlanTask(params) {
|
|
148716
|
+
const graph = await readProjectPlanGraph(params.root);
|
|
148717
|
+
const linkedTodos = await listLinkedTodosByTask(params.root);
|
|
148718
|
+
const task = graph.tasks.find((item) => item.id === params.taskId);
|
|
148719
|
+
if (!task) {
|
|
148720
|
+
return null;
|
|
148721
|
+
}
|
|
148722
|
+
const taskLinkedTodos = linkedTodos.get(task.id) || [];
|
|
148723
|
+
return {
|
|
148724
|
+
...task,
|
|
148725
|
+
linkedTodos: taskLinkedTodos,
|
|
148726
|
+
linkedTodoCount: taskLinkedTodos.length
|
|
148727
|
+
};
|
|
148728
|
+
}
|
|
148729
|
+
async function upsertProjectPlanTask(params) {
|
|
148730
|
+
const state = await ensureProjectPlanGraph(params.root);
|
|
148731
|
+
const graph = state.graph;
|
|
148732
|
+
const feature = graph.features.find((item) => item.id === params.featureId);
|
|
148733
|
+
if (!feature) {
|
|
148734
|
+
throw new Error(`Feature "${params.featureId}" not found.`);
|
|
148735
|
+
}
|
|
148736
|
+
const sectionId = params.sectionId?.trim() || feature.sectionId;
|
|
148737
|
+
const taskId = params.taskId?.trim() || normalizeTaskId(feature.id, params.type, params.title);
|
|
148738
|
+
const existing = graph.tasks.find((task) => task.id === taskId) || graph.tasks.find((task) => task.featureId === feature.id && task.type === params.type && task.title === params.title.trim());
|
|
148739
|
+
const nextTask = {
|
|
148740
|
+
id: existing?.id || taskId,
|
|
148741
|
+
title: params.title.trim(),
|
|
148742
|
+
summary: params.summary?.trim() || "",
|
|
148743
|
+
type: params.type,
|
|
148744
|
+
assignee: params.assignee,
|
|
148745
|
+
status: params.status || "planned",
|
|
148746
|
+
acceptanceCriteria: [...new Set((params.acceptanceCriteria || []).map((item) => item.trim()).filter(Boolean))],
|
|
148747
|
+
featureId: feature.id,
|
|
148748
|
+
sectionId
|
|
148749
|
+
};
|
|
148750
|
+
const nextTasks = existing ? graph.tasks.map((task) => task.id === existing.id ? nextTask : task) : [...graph.tasks, nextTask];
|
|
148751
|
+
await writeProjectPlanFiles(params.root, {
|
|
148752
|
+
...graph,
|
|
148753
|
+
tasks: nextTasks
|
|
148754
|
+
});
|
|
148755
|
+
return nextTask;
|
|
148756
|
+
}
|
|
148757
|
+
async function updateProjectPlanTaskStatus(params) {
|
|
148758
|
+
const graph = await readProjectPlanGraph(params.root);
|
|
148759
|
+
const task = graph.tasks.find((item) => item.id === params.taskId);
|
|
148760
|
+
if (!task) {
|
|
148761
|
+
throw new Error(`Task "${params.taskId}" not found.`);
|
|
148762
|
+
}
|
|
148763
|
+
const nextTask = {
|
|
148764
|
+
...task,
|
|
148765
|
+
status: params.status
|
|
148766
|
+
};
|
|
148767
|
+
await writeProjectPlanFiles(params.root, {
|
|
148768
|
+
...graph,
|
|
148769
|
+
tasks: graph.tasks.map((item) => item.id === task.id ? nextTask : item)
|
|
148770
|
+
});
|
|
148771
|
+
return nextTask;
|
|
148772
|
+
}
|
|
148773
|
+
|
|
148728
148774
|
// src/knowledge/hook.ts
|
|
148729
148775
|
function hasWikiLinks(text3) {
|
|
148730
148776
|
return /\[\[[^\]]+\]\]/u.test(text3);
|
|
@@ -148938,6 +148984,17 @@ function serializeMatches(matches) {
|
|
|
148938
148984
|
reason: match.reason
|
|
148939
148985
|
}));
|
|
148940
148986
|
}
|
|
148987
|
+
async function resolveDocyrusApiAuth(dependencies) {
|
|
148988
|
+
try {
|
|
148989
|
+
const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
|
|
148990
|
+
const profile = await dependencies.authStore.getActiveProfile(apiBaseUrl);
|
|
148991
|
+
if (profile?.accessToken) {
|
|
148992
|
+
return { apiBaseUrl, accessToken: profile.accessToken };
|
|
148993
|
+
}
|
|
148994
|
+
} catch {
|
|
148995
|
+
}
|
|
148996
|
+
return void 0;
|
|
148997
|
+
}
|
|
148941
148998
|
function createKnowledgeCli(dependencies) {
|
|
148942
148999
|
const knowledgeCli = Cli_exports.create("knowledge", {
|
|
148943
149000
|
description: "Docyrus repo knowledge graph commands",
|
|
@@ -148964,7 +149021,6 @@ function createKnowledgeCli(dependencies) {
|
|
|
148964
149021
|
maybePrintHuman(context, [
|
|
148965
149022
|
`Knowledge graph ready at ${result.knowledgeDir}`,
|
|
148966
149023
|
`knowledge.md: ${result.knowledgeFileStatus}`,
|
|
148967
|
-
`project-plan: ${result.projectPlanGraphPath}`,
|
|
148968
149024
|
`AGENTS.md: ${result.agentsStatus}`,
|
|
148969
149025
|
`CLAUDE.md: ${result.claudeStatus}`,
|
|
148970
149026
|
`.cursor/rules/docyrus-knowledge.md: ${result.cursorRulesStatus}`,
|
|
@@ -148992,10 +149048,8 @@ function createKnowledgeCli(dependencies) {
|
|
|
148992
149048
|
root: process.cwd(),
|
|
148993
149049
|
brief: context.args.brief
|
|
148994
149050
|
});
|
|
148995
|
-
const projectPlan = await syncProjectPlanSectionsFromKnowledge(process.cwd());
|
|
148996
149051
|
maybePrintHuman(context, [
|
|
148997
149052
|
`Generated starter knowledge under ${(0, import_node_path20.join)(process.cwd(), "docyrus", "knowledge")}`,
|
|
148998
|
-
`project-plan: ${projectPlan.graphPath}`,
|
|
148999
149053
|
`root: ${result.files.rootKnowledgeStatus}`,
|
|
149000
149054
|
`architecture: ${result.files.architectureStatus}`,
|
|
149001
149055
|
`features: ${result.files.featuresStatus}`,
|
|
@@ -149020,19 +149074,17 @@ function createKnowledgeCli(dependencies) {
|
|
|
149020
149074
|
const codeRefs = await checkKnowledgeCodeRefs(knowledgeContext.knowledgeDir);
|
|
149021
149075
|
const indexErrors = await checkKnowledgeIndex(knowledgeContext.knowledgeDir);
|
|
149022
149076
|
const sectionErrors = await checkKnowledgeSections(knowledgeContext.knowledgeDir);
|
|
149023
|
-
const projectPlan = await validateProjectPlanGraph(process.cwd());
|
|
149024
149077
|
const fileStats = { ...markdown.files };
|
|
149025
149078
|
for (const [extension2, count] of Object.entries(codeRefs.files)) {
|
|
149026
149079
|
fileStats[extension2] = (fileStats[extension2] || 0) + count;
|
|
149027
149080
|
}
|
|
149028
|
-
const totalErrors = markdown.errors.length + codeRefs.errors.length + indexErrors.length + sectionErrors.length
|
|
149081
|
+
const totalErrors = markdown.errors.length + codeRefs.errors.length + indexErrors.length + sectionErrors.length;
|
|
149029
149082
|
const human = [
|
|
149030
149083
|
formatKnowledgeFileStats(fileStats, knowledgeContext.styler),
|
|
149031
149084
|
...formatKnowledgeCheckErrors(markdown.errors, knowledgeContext.styler),
|
|
149032
149085
|
...formatKnowledgeCheckErrors(codeRefs.errors, knowledgeContext.styler),
|
|
149033
149086
|
...formatKnowledgeIndexErrors(indexErrors, knowledgeContext.styler),
|
|
149034
149087
|
...formatKnowledgeCheckErrors(sectionErrors, knowledgeContext.styler),
|
|
149035
|
-
...projectPlan.errors.map((error48) => `- ${knowledgeContext.styler.cyan("docyrus/project-plan/project-plan.json")}: ${knowledgeContext.styler.red(error48.message)}`),
|
|
149036
149088
|
totalErrors === 0 ? knowledgeContext.styler.green("All knowledge checks passed") : knowledgeContext.styler.red(`${totalErrors} error${totalErrors === 1 ? "" : "s"} found`)
|
|
149037
149089
|
].join("\n");
|
|
149038
149090
|
maybePrintHuman(context, human);
|
|
@@ -149045,8 +149097,7 @@ function createKnowledgeCli(dependencies) {
|
|
|
149045
149097
|
markdown: markdown.errors,
|
|
149046
149098
|
codeRefs: codeRefs.errors,
|
|
149047
149099
|
index: indexErrors,
|
|
149048
|
-
sections: sectionErrors
|
|
149049
|
-
projectPlan: projectPlan.errors
|
|
149100
|
+
sections: sectionErrors
|
|
149050
149101
|
},
|
|
149051
149102
|
files: fileStats,
|
|
149052
149103
|
ok: totalErrors === 0
|
|
@@ -149255,8 +149306,10 @@ function createKnowledgeCli(dependencies) {
|
|
|
149255
149306
|
}),
|
|
149256
149307
|
run: async (context) => {
|
|
149257
149308
|
const knowledgeContext = await resolveCliKnowledgeContext();
|
|
149309
|
+
const docyrusApi = await resolveDocyrusApiAuth(dependencies);
|
|
149258
149310
|
const provider = await getKnowledgeSearchProviderInfo({
|
|
149259
|
-
settingsRootPath: dependencies.settingsPaths.rootPath
|
|
149311
|
+
settingsRootPath: dependencies.settingsPaths.rootPath,
|
|
149312
|
+
docyrusApi
|
|
149260
149313
|
});
|
|
149261
149314
|
if (!provider.provider || !provider.info) {
|
|
149262
149315
|
throw new UserInputError(provider.error || "No embedding provider is configured.");
|
|
@@ -149371,10 +149424,9 @@ function createKnowledgeCli(dependencies) {
|
|
|
149371
149424
|
markdown: await checkKnowledgeMarkdown(knowledgeContext.knowledgeDir),
|
|
149372
149425
|
codeRefs: await checkKnowledgeCodeRefs(knowledgeContext.knowledgeDir),
|
|
149373
149426
|
index: await checkKnowledgeIndex(knowledgeContext.knowledgeDir),
|
|
149374
|
-
sections: await checkKnowledgeSections(knowledgeContext.knowledgeDir)
|
|
149375
|
-
projectPlan: await validateProjectPlanGraph(process.cwd())
|
|
149427
|
+
sections: await checkKnowledgeSections(knowledgeContext.knowledgeDir)
|
|
149376
149428
|
} : null;
|
|
149377
|
-
const blockingCheckErrors = checkResult ? checkResult.markdown.errors.length + checkResult.codeRefs.errors.length + checkResult.index.length + checkResult.sections.length
|
|
149429
|
+
const blockingCheckErrors = checkResult ? checkResult.markdown.errors.length + checkResult.codeRefs.errors.length + checkResult.index.length + checkResult.sections.length : 0;
|
|
149378
149430
|
const ok3 = blockingCheckErrors === 0 && audit.blockingErrors.length === 0;
|
|
149379
149431
|
const payload = {
|
|
149380
149432
|
ok: ok3,
|
|
@@ -149382,8 +149434,7 @@ function createKnowledgeCli(dependencies) {
|
|
|
149382
149434
|
markdown: checkResult.markdown.errors,
|
|
149383
149435
|
codeRefs: checkResult.codeRefs.errors,
|
|
149384
149436
|
index: checkResult.index,
|
|
149385
|
-
sections: checkResult.sections
|
|
149386
|
-
projectPlan: checkResult.projectPlan.errors
|
|
149437
|
+
sections: checkResult.sections
|
|
149387
149438
|
} : null,
|
|
149388
149439
|
audit
|
|
149389
149440
|
};
|
|
@@ -149457,10 +149508,8 @@ function createKnowledgeCli(dependencies) {
|
|
|
149457
149508
|
brief: context.args.brief,
|
|
149458
149509
|
targetSectionIds: sectionIds
|
|
149459
149510
|
});
|
|
149460
|
-
const projectPlan = await syncProjectPlanSectionsFromKnowledge(process.cwd());
|
|
149461
149511
|
maybePrintHuman(context, [
|
|
149462
149512
|
`Refreshed managed knowledge files.`,
|
|
149463
|
-
`project-plan: ${projectPlan.graphPath}`,
|
|
149464
149513
|
`Targets: ${sectionIds.length > 0 ? sectionIds.join(", ") : "all starter files"}`,
|
|
149465
149514
|
`root: ${result.files.rootKnowledgeStatus}`,
|
|
149466
149515
|
`architecture: ${result.files.architectureStatus}`,
|
|
@@ -149474,8 +149523,6 @@ function createKnowledgeCli(dependencies) {
|
|
|
149474
149523
|
authStore: dependencies.authStore,
|
|
149475
149524
|
payload: {
|
|
149476
149525
|
...result,
|
|
149477
|
-
projectPlanGraphPath: projectPlan.graphPath,
|
|
149478
|
-
projectPlanMarkdownPath: projectPlan.markdownPath,
|
|
149479
149526
|
targetSectionIds: sectionIds
|
|
149480
149527
|
}
|
|
149481
149528
|
});
|
|
@@ -149519,8 +149566,10 @@ function createKnowledgeCli(dependencies) {
|
|
|
149519
149566
|
run: async (context) => {
|
|
149520
149567
|
const projectRoot = findKnowledgeProjectRoot() || process.cwd();
|
|
149521
149568
|
const knowledgeDir = findKnowledgeDir();
|
|
149569
|
+
const docyrusApi = await resolveDocyrusApiAuth(dependencies);
|
|
149522
149570
|
const provider = await getKnowledgeSearchProviderInfo({
|
|
149523
|
-
settingsRootPath: dependencies.settingsPaths.rootPath
|
|
149571
|
+
settingsRootPath: dependencies.settingsPaths.rootPath,
|
|
149572
|
+
docyrusApi
|
|
149524
149573
|
});
|
|
149525
149574
|
const payload = {
|
|
149526
149575
|
id: (0, import_node_crypto6.randomUUID)(),
|
|
@@ -149568,11 +149617,6 @@ function createKnowledgeCli(dependencies) {
|
|
|
149568
149617
|
return knowledgeCli;
|
|
149569
149618
|
}
|
|
149570
149619
|
|
|
149571
|
-
// src/commands/projectPlanCommands.ts
|
|
149572
|
-
var import_node_fs14 = require("node:fs");
|
|
149573
|
-
var import_node_path22 = __toESM(require("node:path"));
|
|
149574
|
-
init_graph();
|
|
149575
|
-
|
|
149576
149620
|
// src/project-plan/artifactSync.ts
|
|
149577
149621
|
var import_node_fs13 = require("node:fs");
|
|
149578
149622
|
var import_promises16 = __toESM(require("node:fs/promises"));
|
|
@@ -149659,7 +149703,7 @@ async function readArchitectPlanJson(artifactDir) {
|
|
|
149659
149703
|
return JSON.parse(await import_promises16.default.readFile(jsonPath, "utf8"));
|
|
149660
149704
|
}
|
|
149661
149705
|
async function upsertProjectPlanFromPlanArtifact(params) {
|
|
149662
|
-
const routes = await
|
|
149706
|
+
const routes = await ensureDefaultProjectPlanSections(params.root);
|
|
149663
149707
|
if (!(0, import_node_fs13.existsSync)(params.artifactPath)) {
|
|
149664
149708
|
return {
|
|
149665
149709
|
ok: false,
|
|
@@ -149765,7 +149809,7 @@ function normalizeArchitectPhaseTitle(phase, fallbackIndex) {
|
|
|
149765
149809
|
};
|
|
149766
149810
|
}
|
|
149767
149811
|
async function upsertProjectPlanFromArchitectArtifact(params) {
|
|
149768
|
-
const routes = await
|
|
149812
|
+
const routes = await ensureDefaultProjectPlanSections(params.root);
|
|
149769
149813
|
const warnings = [];
|
|
149770
149814
|
const updatedFeatureIds = [];
|
|
149771
149815
|
const updatedTaskIds = [];
|
|
@@ -149951,7 +149995,7 @@ function createProjectPlanCli(dependencies) {
|
|
|
149951
149995
|
}
|
|
149952
149996
|
});
|
|
149953
149997
|
projectPlanCli.command("check", {
|
|
149954
|
-
description: "Validate the canonical project plan graph
|
|
149998
|
+
description: "Validate the canonical project plan graph",
|
|
149955
149999
|
env: EnvSchema,
|
|
149956
150000
|
outputPolicy: "agent-only",
|
|
149957
150001
|
run: async (context) => {
|
|
@@ -149960,18 +150004,26 @@ function createProjectPlanCli(dependencies) {
|
|
|
149960
150004
|
return await wrapPayload(dependencies, result);
|
|
149961
150005
|
}
|
|
149962
150006
|
});
|
|
149963
|
-
projectPlanCli.command("
|
|
149964
|
-
description: "
|
|
150007
|
+
projectPlanCli.command("upsert-section", {
|
|
150008
|
+
description: "Create or update a project plan section",
|
|
149965
150009
|
env: EnvSchema,
|
|
149966
150010
|
outputPolicy: "agent-only",
|
|
150011
|
+
options: external_exports.object({
|
|
150012
|
+
id: external_exports.string().optional().describe("Optional existing section id"),
|
|
150013
|
+
title: external_exports.string().min(1).describe("Section title"),
|
|
150014
|
+
slug: external_exports.string().optional().describe("Optional section slug"),
|
|
150015
|
+
summary: external_exports.string().optional().describe("Section summary")
|
|
150016
|
+
}),
|
|
149967
150017
|
run: async (context) => {
|
|
149968
|
-
const
|
|
149969
|
-
|
|
149970
|
-
|
|
149971
|
-
|
|
149972
|
-
|
|
149973
|
-
|
|
150018
|
+
const section2 = await upsertProjectPlanSection({
|
|
150019
|
+
root: process.cwd(),
|
|
150020
|
+
id: context.options.id,
|
|
150021
|
+
title: context.options.title,
|
|
150022
|
+
slug: context.options.slug,
|
|
150023
|
+
summary: context.options.summary
|
|
149974
150024
|
});
|
|
150025
|
+
maybePrintHuman2(context, `Upserted section ${section2.id}`);
|
|
150026
|
+
return await wrapPayload(dependencies, section2);
|
|
149975
150027
|
}
|
|
149976
150028
|
});
|
|
149977
150029
|
projectPlanCli.command("ensure", {
|
|
@@ -149994,7 +150046,7 @@ function createProjectPlanCli(dependencies) {
|
|
|
149994
150046
|
outputPolicy: "agent-only",
|
|
149995
150047
|
options: external_exports.object({
|
|
149996
150048
|
featureId: external_exports.string().optional().describe("Optional existing feature id"),
|
|
149997
|
-
sectionId: external_exports.string().min(1).describe("
|
|
150049
|
+
sectionId: external_exports.string().min(1).describe("Project plan section id"),
|
|
149998
150050
|
title: external_exports.string().min(1).describe("Feature title"),
|
|
149999
150051
|
slug: external_exports.string().optional().describe("Optional feature slug"),
|
|
150000
150052
|
summary: external_exports.string().optional().describe("Feature summary")
|
|
@@ -150148,27 +150200,24 @@ function createProjectPlanCli(dependencies) {
|
|
|
150148
150200
|
}
|
|
150149
150201
|
});
|
|
150150
150202
|
projectPlanCli.command("config", {
|
|
150151
|
-
description: "Show resolved project-plan
|
|
150203
|
+
description: "Show resolved project-plan paths",
|
|
150152
150204
|
env: EnvSchema,
|
|
150153
150205
|
outputPolicy: "agent-only",
|
|
150154
150206
|
run: async (context) => {
|
|
150155
150207
|
const root = process.cwd();
|
|
150156
|
-
const
|
|
150157
|
-
const knowledgeSectionCount = (0, import_node_fs14.existsSync)(knowledgeDir) ? flattenSections(await loadAllSections(knowledgeDir)).length : 0;
|
|
150208
|
+
const graph = await readProjectPlanGraph(root);
|
|
150158
150209
|
const payload = {
|
|
150159
150210
|
projectRoot: root,
|
|
150160
|
-
knowledgeDir: (0, import_node_fs14.existsSync)(knowledgeDir) ? knowledgeDir : null,
|
|
150161
150211
|
projectPlanDir: resolveProjectPlanDirectory(root),
|
|
150162
150212
|
graphPath: resolveProjectPlanGraphPath(root),
|
|
150163
150213
|
markdownPath: resolveProjectPlanMarkdownPath(root),
|
|
150164
|
-
|
|
150214
|
+
sectionCount: graph.sections.length
|
|
150165
150215
|
};
|
|
150166
150216
|
maybePrintHuman2(context, [
|
|
150167
|
-
`knowledgeDir: ${payload.knowledgeDir || "(not found)"}`,
|
|
150168
150217
|
`projectPlanDir: ${payload.projectPlanDir}`,
|
|
150169
150218
|
`graphPath: ${payload.graphPath}`,
|
|
150170
150219
|
`markdownPath: ${payload.markdownPath}`,
|
|
150171
|
-
`
|
|
150220
|
+
`sections: ${payload.sectionCount}`
|
|
150172
150221
|
].join("\n"));
|
|
150173
150222
|
return await wrapPayload(dependencies, payload);
|
|
150174
150223
|
}
|
|
@@ -150178,7 +150227,7 @@ function createProjectPlanCli(dependencies) {
|
|
|
150178
150227
|
|
|
150179
150228
|
// src/services/studioPayload.ts
|
|
150180
150229
|
var import_promises17 = require("node:fs/promises");
|
|
150181
|
-
var
|
|
150230
|
+
var import_node_path22 = require("node:path");
|
|
150182
150231
|
async function readStdinText3() {
|
|
150183
150232
|
if (process.stdin.isTTY) {
|
|
150184
150233
|
return "";
|
|
@@ -150201,7 +150250,7 @@ async function readStudioWriteInput(params) {
|
|
|
150201
150250
|
data,
|
|
150202
150251
|
fromFile,
|
|
150203
150252
|
readStdin: readStdin2 = readStdinText3,
|
|
150204
|
-
readFileFn = async (
|
|
150253
|
+
readFileFn = async (path6, encoding) => await (0, import_promises17.readFile)(path6, encoding)
|
|
150205
150254
|
} = params;
|
|
150206
150255
|
const trimmedData = data?.trim();
|
|
150207
150256
|
const trimmedFromFile = fromFile?.trim();
|
|
@@ -150209,7 +150258,7 @@ async function readStudioWriteInput(params) {
|
|
|
150209
150258
|
throw new UserInputError("Provide either --data or --from-file, not both.");
|
|
150210
150259
|
}
|
|
150211
150260
|
if (trimmedFromFile) {
|
|
150212
|
-
const extension2 = (0,
|
|
150261
|
+
const extension2 = (0, import_node_path22.extname)(trimmedFromFile).toLowerCase();
|
|
150213
150262
|
if (extension2 && extension2 !== ".json") {
|
|
150214
150263
|
throw new UserInputError("Studio commands support only JSON files in --from-file.");
|
|
150215
150264
|
}
|
|
@@ -151214,8 +151263,8 @@ function createStudioCli(dependencies) {
|
|
|
151214
151263
|
|
|
151215
151264
|
// src/commands/tuiCommand.ts
|
|
151216
151265
|
var import_node_child_process5 = require("node:child_process");
|
|
151217
|
-
var
|
|
151218
|
-
var
|
|
151266
|
+
var import_node_fs14 = require("node:fs");
|
|
151267
|
+
var import_node_path23 = require("node:path");
|
|
151219
151268
|
function summarizeFailure2(result) {
|
|
151220
151269
|
const stderr = result.stderr?.toString().trim();
|
|
151221
151270
|
if (stderr && stderr.length > 0) {
|
|
@@ -151232,23 +151281,23 @@ function summarizeFailure2(result) {
|
|
|
151232
151281
|
function resolveCliScriptPath() {
|
|
151233
151282
|
const argvScript = process.argv[1];
|
|
151234
151283
|
if (argvScript && argvScript.trim().length > 0) {
|
|
151235
|
-
return (0,
|
|
151284
|
+
return (0, import_node_path23.isAbsolute)(argvScript) ? argvScript : (0, import_node_path23.resolve)(process.cwd(), argvScript);
|
|
151236
151285
|
}
|
|
151237
151286
|
return __filename;
|
|
151238
151287
|
}
|
|
151239
151288
|
function resolveOpenTuiEntryPath(options2 = {}) {
|
|
151240
151289
|
const cwd = options2.cwd ?? process.cwd();
|
|
151241
151290
|
const dirname13 = options2.dirname ?? __dirname;
|
|
151242
|
-
const fileExists = options2.existsSyncFn ??
|
|
151291
|
+
const fileExists = options2.existsSyncFn ?? import_node_fs14.existsSync;
|
|
151243
151292
|
const candidates = [
|
|
151244
151293
|
// Source/dev mode in monorepo. Prefer this first so Bun resolves deps via
|
|
151245
151294
|
// apps/api-cli/node_modules in workspace runs (e.g. `pnpm docyrus tui`).
|
|
151246
|
-
(0,
|
|
151247
|
-
(0,
|
|
151295
|
+
(0, import_node_path23.resolve)(cwd, "apps/api-cli/src/tui/opentuiMain.tsx"),
|
|
151296
|
+
(0, import_node_path23.resolve)(dirname13, "../tui/opentuiMain.tsx"),
|
|
151248
151297
|
// Dist mode (bundled command runtime)
|
|
151249
|
-
(0,
|
|
151250
|
-
(0,
|
|
151251
|
-
(0,
|
|
151298
|
+
(0, import_node_path23.resolve)(dirname13, "tui.mjs"),
|
|
151299
|
+
(0, import_node_path23.resolve)(dirname13, "../tui.mjs"),
|
|
151300
|
+
(0, import_node_path23.resolve)(cwd, "dist/apps/api-cli/tui.mjs")
|
|
151252
151301
|
];
|
|
151253
151302
|
const resolved = candidates.find((candidate) => fileExists(candidate));
|
|
151254
151303
|
if (!resolved) {
|
|
@@ -151389,7 +151438,7 @@ async function parseResponseBody(response) {
|
|
|
151389
151438
|
}
|
|
151390
151439
|
}
|
|
151391
151440
|
function normalizeErrorResponse(params) {
|
|
151392
|
-
const { status, path:
|
|
151441
|
+
const { status, path: path6, headers, body: body2 } = params;
|
|
151393
151442
|
const bodyObject = typeof body2 === "object" && body2 !== null ? body2 : null;
|
|
151394
151443
|
const errorCodeValue = bodyObject?.error;
|
|
151395
151444
|
const errorDescriptionValue = bodyObject?.error_description ?? bodyObject?.message;
|
|
@@ -151399,7 +151448,7 @@ function normalizeErrorResponse(params) {
|
|
|
151399
151448
|
status,
|
|
151400
151449
|
error: errorCode,
|
|
151401
151450
|
error_description: errorDescription,
|
|
151402
|
-
path:
|
|
151451
|
+
path: path6,
|
|
151403
151452
|
rate_limit_limit: headers.get("ratelimit-limit") || void 0,
|
|
151404
151453
|
rate_limit_remaining: headers.get("ratelimit-remaining") || void 0,
|
|
151405
151454
|
rate_limit_reset: headers.get("ratelimit-reset") || void 0,
|
|
@@ -151407,13 +151456,13 @@ function normalizeErrorResponse(params) {
|
|
|
151407
151456
|
raw: body2
|
|
151408
151457
|
};
|
|
151409
151458
|
}
|
|
151410
|
-
function normalizePathForUrl(
|
|
151411
|
-
return normalizeApiPath(
|
|
151459
|
+
function normalizePathForUrl(path6) {
|
|
151460
|
+
return normalizeApiPath(path6);
|
|
151412
151461
|
}
|
|
151413
151462
|
async function requestDocyrusApi(options2) {
|
|
151414
151463
|
const {
|
|
151415
151464
|
baseUrl,
|
|
151416
|
-
path:
|
|
151465
|
+
path: path6,
|
|
151417
151466
|
method = "GET",
|
|
151418
151467
|
headers,
|
|
151419
151468
|
query,
|
|
@@ -151422,7 +151471,7 @@ async function requestDocyrusApi(options2) {
|
|
|
151422
151471
|
fetchFn = fetch
|
|
151423
151472
|
} = options2;
|
|
151424
151473
|
const normalizedBaseUrl = normalizeApiBaseUrl(baseUrl);
|
|
151425
|
-
const normalizedPath = normalizePathForUrl(
|
|
151474
|
+
const normalizedPath = normalizePathForUrl(path6);
|
|
151426
151475
|
const url2 = `${normalizedBaseUrl}${normalizedPath}${toQueryString(query)}`;
|
|
151427
151476
|
const requestHeaders = {
|
|
151428
151477
|
Accept: "application/json",
|
|
@@ -151482,12 +151531,12 @@ var ApiClient = class {
|
|
|
151482
151531
|
const {
|
|
151483
151532
|
authRequired = true,
|
|
151484
151533
|
method = "GET",
|
|
151485
|
-
path:
|
|
151534
|
+
path: path6,
|
|
151486
151535
|
headers,
|
|
151487
151536
|
query,
|
|
151488
151537
|
body: body2
|
|
151489
151538
|
} = options2;
|
|
151490
|
-
if (!
|
|
151539
|
+
if (!path6) {
|
|
151491
151540
|
throw new UserInputError("Request path is required.");
|
|
151492
151541
|
}
|
|
151493
151542
|
let authToken;
|
|
@@ -151497,7 +151546,7 @@ var ApiClient = class {
|
|
|
151497
151546
|
return await requestDocyrusApi({
|
|
151498
151547
|
baseUrl: this.#apiBaseUrl,
|
|
151499
151548
|
method,
|
|
151500
|
-
path:
|
|
151549
|
+
path: path6,
|
|
151501
151550
|
headers,
|
|
151502
151551
|
query,
|
|
151503
151552
|
body: body2,
|
|
@@ -152050,7 +152099,7 @@ var AuthSessionService = class {
|
|
|
152050
152099
|
|
|
152051
152100
|
// src/services/authStore.ts
|
|
152052
152101
|
var import_promises18 = require("node:fs/promises");
|
|
152053
|
-
var
|
|
152102
|
+
var import_node_path24 = require("node:path");
|
|
152054
152103
|
function createEmptyState() {
|
|
152055
152104
|
return {
|
|
152056
152105
|
version: 2,
|
|
@@ -152126,7 +152175,7 @@ var AuthStore = class {
|
|
|
152126
152175
|
});
|
|
152127
152176
|
}
|
|
152128
152177
|
const normalized = normalizeState2(validated.data);
|
|
152129
|
-
const directory = (0,
|
|
152178
|
+
const directory = (0, import_node_path24.dirname)(this.authFilePath);
|
|
152130
152179
|
await (0, import_promises18.mkdir)(directory, {
|
|
152131
152180
|
recursive: true,
|
|
152132
152181
|
mode: 448
|
|
@@ -152341,7 +152390,7 @@ var AuthStore = class {
|
|
|
152341
152390
|
|
|
152342
152391
|
// src/services/environmentConfig.ts
|
|
152343
152392
|
var import_promises19 = require("node:fs/promises");
|
|
152344
|
-
var
|
|
152393
|
+
var import_node_path25 = require("node:path");
|
|
152345
152394
|
var ENVIRONMENT_ID_ALIASES = {
|
|
152346
152395
|
"local-development": "dev",
|
|
152347
152396
|
prod: "live"
|
|
@@ -152462,7 +152511,7 @@ var EnvironmentConfigService = class {
|
|
|
152462
152511
|
});
|
|
152463
152512
|
}
|
|
152464
152513
|
const normalized = normalizeState3(validated.data);
|
|
152465
|
-
const directory = (0,
|
|
152514
|
+
const directory = (0, import_node_path25.dirname)(this.configFilePath);
|
|
152466
152515
|
await (0, import_promises19.mkdir)(directory, {
|
|
152467
152516
|
recursive: true,
|
|
152468
152517
|
mode: 448
|
|
@@ -152539,9 +152588,9 @@ var EnvironmentConfigService = class {
|
|
|
152539
152588
|
|
|
152540
152589
|
// src/services/piAgentLauncher.ts
|
|
152541
152590
|
var import_node_child_process6 = require("node:child_process");
|
|
152542
|
-
var
|
|
152591
|
+
var import_node_fs15 = require("node:fs");
|
|
152543
152592
|
var import_promises20 = require("node:fs/promises");
|
|
152544
|
-
var
|
|
152593
|
+
var import_node_path26 = require("node:path");
|
|
152545
152594
|
|
|
152546
152595
|
// src/services/spinner.ts
|
|
152547
152596
|
var import_picocolors2 = __toESM(require_picocolors());
|
|
@@ -152604,12 +152653,12 @@ function summarizeFailure3(result, commandLabel = "Command") {
|
|
|
152604
152653
|
function resolvePackagedPiResourceRoot(options2 = {}) {
|
|
152605
152654
|
const cwd = options2.cwd ?? process.cwd();
|
|
152606
152655
|
const dirname13 = options2.dirname ?? __dirname;
|
|
152607
|
-
const fileExists = options2.existsSyncFn ??
|
|
152656
|
+
const fileExists = options2.existsSyncFn ?? import_node_fs15.existsSync;
|
|
152608
152657
|
const candidates = [
|
|
152609
|
-
(0,
|
|
152610
|
-
(0,
|
|
152611
|
-
(0,
|
|
152612
|
-
(0,
|
|
152658
|
+
(0, import_node_path26.resolve)(cwd, "apps/api-cli/resources/pi-agent"),
|
|
152659
|
+
(0, import_node_path26.resolve)(dirname13, "../resources/pi-agent"),
|
|
152660
|
+
(0, import_node_path26.resolve)(dirname13, "resources/pi-agent"),
|
|
152661
|
+
(0, import_node_path26.resolve)(cwd, "dist/apps/api-cli/resources/pi-agent")
|
|
152613
152662
|
];
|
|
152614
152663
|
const resolved = candidates.find((candidate) => fileExists(candidate));
|
|
152615
152664
|
if (!resolved) {
|
|
@@ -152620,7 +152669,7 @@ function resolvePackagedPiResourceRoot(options2 = {}) {
|
|
|
152620
152669
|
function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
|
|
152621
152670
|
const cwd = options2.cwd ?? process.cwd();
|
|
152622
152671
|
const dirname13 = options2.dirname ?? __dirname;
|
|
152623
|
-
const fileExists = options2.existsSyncFn ??
|
|
152672
|
+
const fileExists = options2.existsSyncFn ?? import_node_fs15.existsSync;
|
|
152624
152673
|
const seen = /* @__PURE__ */ new Set();
|
|
152625
152674
|
const candidates = options2.candidatePaths ?? [];
|
|
152626
152675
|
const addCandidate = (candidate) => {
|
|
@@ -152630,23 +152679,23 @@ function resolveDocyrusPiLoaderEntryPath(options2 = {}) {
|
|
|
152630
152679
|
}
|
|
152631
152680
|
};
|
|
152632
152681
|
const collectAncestorCandidates = (startDir) => {
|
|
152633
|
-
let currentDir = (0,
|
|
152682
|
+
let currentDir = (0, import_node_path26.resolve)(startDir);
|
|
152634
152683
|
while (true) {
|
|
152635
|
-
addCandidate((0,
|
|
152636
|
-
addCandidate((0,
|
|
152637
|
-
if ((0,
|
|
152638
|
-
addCandidate((0,
|
|
152684
|
+
addCandidate((0, import_node_path26.join)(currentDir, "dist", "apps", "api-cli", "agent-loader.js"));
|
|
152685
|
+
addCandidate((0, import_node_path26.join)(currentDir, "agent-loader.js"));
|
|
152686
|
+
if ((0, import_node_path26.basename)(currentDir) === "dist") {
|
|
152687
|
+
addCandidate((0, import_node_path26.join)(currentDir, "apps", "api-cli", "agent-loader.js"));
|
|
152639
152688
|
}
|
|
152640
|
-
const parentDir = (0,
|
|
152689
|
+
const parentDir = (0, import_node_path26.resolve)(currentDir, "..");
|
|
152641
152690
|
if (parentDir === currentDir) {
|
|
152642
152691
|
break;
|
|
152643
152692
|
}
|
|
152644
152693
|
currentDir = parentDir;
|
|
152645
152694
|
}
|
|
152646
152695
|
};
|
|
152647
|
-
addCandidate((0,
|
|
152648
|
-
addCandidate((0,
|
|
152649
|
-
addCandidate((0,
|
|
152696
|
+
addCandidate((0, import_node_path26.resolve)(cwd, "dist/apps/api-cli/agent-loader.js"));
|
|
152697
|
+
addCandidate((0, import_node_path26.resolve)(dirname13, "../agent-loader.js"));
|
|
152698
|
+
addCandidate((0, import_node_path26.resolve)(dirname13, "agent-loader.js"));
|
|
152650
152699
|
collectAncestorCandidates(cwd);
|
|
152651
152700
|
collectAncestorCandidates(dirname13);
|
|
152652
152701
|
const resolved = candidates.find((candidate) => fileExists(candidate));
|
|
@@ -152659,27 +152708,27 @@ function resolveDocyrusCliEntryPath(options2 = {}) {
|
|
|
152659
152708
|
const cwd = options2.cwd ?? process.cwd();
|
|
152660
152709
|
const dirname13 = options2.dirname ?? __dirname;
|
|
152661
152710
|
const argv = options2.argv ?? process.argv;
|
|
152662
|
-
const fileExists = options2.existsSyncFn ??
|
|
152711
|
+
const fileExists = options2.existsSyncFn ?? import_node_fs15.existsSync;
|
|
152663
152712
|
const seen = /* @__PURE__ */ new Set();
|
|
152664
152713
|
const candidates = options2.candidatePaths ?? [];
|
|
152665
152714
|
const addCandidate = (candidate) => {
|
|
152666
152715
|
if (!candidate) {
|
|
152667
152716
|
return;
|
|
152668
152717
|
}
|
|
152669
|
-
const resolvedCandidate = (0,
|
|
152718
|
+
const resolvedCandidate = (0, import_node_path26.resolve)(candidate);
|
|
152670
152719
|
if (!seen.has(resolvedCandidate)) {
|
|
152671
152720
|
seen.add(resolvedCandidate);
|
|
152672
152721
|
candidates.push(resolvedCandidate);
|
|
152673
152722
|
}
|
|
152674
152723
|
};
|
|
152675
152724
|
const argvScript = argv[1]?.trim();
|
|
152676
|
-
const normalizedArgvScript = argvScript ? argvScript.startsWith("/") ? argvScript : (0,
|
|
152725
|
+
const normalizedArgvScript = argvScript ? argvScript.startsWith("/") ? argvScript : (0, import_node_path26.resolve)(cwd, argvScript) : void 0;
|
|
152677
152726
|
if (normalizedArgvScript && normalizedArgvScript.endsWith(".js")) {
|
|
152678
152727
|
addCandidate(normalizedArgvScript);
|
|
152679
152728
|
}
|
|
152680
|
-
addCandidate((0,
|
|
152681
|
-
addCandidate((0,
|
|
152682
|
-
addCandidate((0,
|
|
152729
|
+
addCandidate((0, import_node_path26.resolve)(cwd, "dist/apps/api-cli/main.js"));
|
|
152730
|
+
addCandidate((0, import_node_path26.resolve)(dirname13, "../main.js"));
|
|
152731
|
+
addCandidate((0, import_node_path26.resolve)(dirname13, "main.js"));
|
|
152683
152732
|
if (normalizedArgvScript) {
|
|
152684
152733
|
addCandidate(normalizedArgvScript);
|
|
152685
152734
|
}
|
|
@@ -152692,7 +152741,7 @@ function resolveDocyrusCliEntryPath(options2 = {}) {
|
|
|
152692
152741
|
function resolveInstalledPiPackageRootPath(options2 = {}) {
|
|
152693
152742
|
const cwd = options2.cwd ?? process.cwd();
|
|
152694
152743
|
const dirname13 = options2.dirname ?? __dirname;
|
|
152695
|
-
const fileExists = options2.existsSyncFn ??
|
|
152744
|
+
const fileExists = options2.existsSyncFn ?? import_node_fs15.existsSync;
|
|
152696
152745
|
const seen = /* @__PURE__ */ new Set();
|
|
152697
152746
|
const candidates = options2.candidatePaths ?? [];
|
|
152698
152747
|
const addCandidate = (candidate) => {
|
|
@@ -152702,33 +152751,33 @@ function resolveInstalledPiPackageRootPath(options2 = {}) {
|
|
|
152702
152751
|
}
|
|
152703
152752
|
};
|
|
152704
152753
|
const collectAncestorCandidates = (startDir) => {
|
|
152705
|
-
let currentDir = (0,
|
|
152754
|
+
let currentDir = (0, import_node_path26.resolve)(startDir);
|
|
152706
152755
|
while (true) {
|
|
152707
|
-
addCandidate((0,
|
|
152708
|
-
if ((0,
|
|
152709
|
-
addCandidate((0,
|
|
152756
|
+
addCandidate((0, import_node_path26.join)(currentDir, "node_modules", "@mariozechner", "pi-coding-agent", "package.json"));
|
|
152757
|
+
if ((0, import_node_path26.basename)(currentDir) === "node_modules") {
|
|
152758
|
+
addCandidate((0, import_node_path26.join)(currentDir, "@mariozechner", "pi-coding-agent", "package.json"));
|
|
152710
152759
|
}
|
|
152711
|
-
const parentDir = (0,
|
|
152760
|
+
const parentDir = (0, import_node_path26.resolve)(currentDir, "..");
|
|
152712
152761
|
if (parentDir === currentDir) {
|
|
152713
152762
|
break;
|
|
152714
152763
|
}
|
|
152715
152764
|
currentDir = parentDir;
|
|
152716
152765
|
}
|
|
152717
152766
|
};
|
|
152718
|
-
addCandidate((0,
|
|
152719
|
-
addCandidate((0,
|
|
152767
|
+
addCandidate((0, import_node_path26.resolve)(cwd, "apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
|
|
152768
|
+
addCandidate((0, import_node_path26.resolve)(dirname13, "../../../apps/api-cli/node_modules/@mariozechner/pi-coding-agent/package.json"));
|
|
152720
152769
|
collectAncestorCandidates(cwd);
|
|
152721
152770
|
collectAncestorCandidates(dirname13);
|
|
152722
152771
|
const resolvedPackageJson = candidates.find((candidate) => fileExists(candidate));
|
|
152723
152772
|
if (!resolvedPackageJson) {
|
|
152724
152773
|
throw new UserInputError(`Unable to locate the installed pi package root. Checked: ${candidates.join(", ")}`);
|
|
152725
152774
|
}
|
|
152726
|
-
return (0,
|
|
152775
|
+
return (0, import_node_path26.resolve)(resolvedPackageJson, "..");
|
|
152727
152776
|
}
|
|
152728
152777
|
function createPiAgentRuntimeSkill(params) {
|
|
152729
152778
|
const commandPrefix = params.scope === "global" ? "docyrus -g" : "docyrus";
|
|
152730
|
-
const knowledgeDir = (0,
|
|
152731
|
-
const hasKnowledgeGraph = (0,
|
|
152779
|
+
const knowledgeDir = (0, import_node_path26.join)(params.cwd, "docyrus", "knowledge");
|
|
152780
|
+
const hasKnowledgeGraph = (0, import_node_fs15.existsSync)(knowledgeDir);
|
|
152732
152781
|
const authLines = params.activeProfile ? [
|
|
152733
152782
|
`- email: \`${params.activeProfile.email}\``,
|
|
152734
152783
|
`- tenant: \`${params.activeProfile.tenantName} (${params.activeProfile.tenantNo})\``,
|
|
@@ -152781,8 +152830,8 @@ function createPiAgentRuntimeSkill(params) {
|
|
|
152781
152830
|
].join("\n");
|
|
152782
152831
|
}
|
|
152783
152832
|
async function syncPackagedSkills(params) {
|
|
152784
|
-
const sourceSkillsRoot = (0,
|
|
152785
|
-
const targetSkillsRoot = (0,
|
|
152833
|
+
const sourceSkillsRoot = (0, import_node_path26.join)(params.resourceRoot, "skills");
|
|
152834
|
+
const targetSkillsRoot = (0, import_node_path26.join)(params.agentRootPath, "skills");
|
|
152786
152835
|
await (0, import_promises20.mkdir)(targetSkillsRoot, {
|
|
152787
152836
|
recursive: true,
|
|
152788
152837
|
mode: 448
|
|
@@ -152791,25 +152840,25 @@ async function syncPackagedSkills(params) {
|
|
|
152791
152840
|
withFileTypes: true
|
|
152792
152841
|
});
|
|
152793
152842
|
await Promise.all(DOCYRUS_MIGRATED_SKILL_NAMES.map(async (skillName) => {
|
|
152794
|
-
await (0, import_promises20.rm)((0,
|
|
152843
|
+
await (0, import_promises20.rm)((0, import_node_path26.join)(targetSkillsRoot, skillName), {
|
|
152795
152844
|
recursive: true,
|
|
152796
152845
|
force: true
|
|
152797
152846
|
});
|
|
152798
152847
|
}));
|
|
152799
152848
|
await Promise.all(entries.map(async (entry) => {
|
|
152800
|
-
await (0, import_promises20.cp)((0,
|
|
152849
|
+
await (0, import_promises20.cp)((0, import_node_path26.join)(sourceSkillsRoot, entry.name), (0, import_node_path26.join)(targetSkillsRoot, entry.name), {
|
|
152801
152850
|
recursive: true,
|
|
152802
152851
|
force: true
|
|
152803
152852
|
});
|
|
152804
152853
|
}));
|
|
152805
152854
|
}
|
|
152806
152855
|
async function writeRuntimeSkill(params) {
|
|
152807
|
-
const runtimeSkillDir = (0,
|
|
152856
|
+
const runtimeSkillDir = (0, import_node_path26.join)(params.agentRootPath, "skills", "docyrus-runtime-context");
|
|
152808
152857
|
await (0, import_promises20.mkdir)(runtimeSkillDir, {
|
|
152809
152858
|
recursive: true,
|
|
152810
152859
|
mode: 448
|
|
152811
152860
|
});
|
|
152812
|
-
await (0, import_promises20.writeFile)((0,
|
|
152861
|
+
await (0, import_promises20.writeFile)((0, import_node_path26.join)(runtimeSkillDir, "SKILL.md"), `${params.content}
|
|
152813
152862
|
`, {
|
|
152814
152863
|
encoding: "utf8",
|
|
152815
152864
|
mode: 384
|
|
@@ -152822,10 +152871,10 @@ function resolveNpmCommand() {
|
|
|
152822
152871
|
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
152823
152872
|
}
|
|
152824
152873
|
function resolveManagedDiffityInstallRoot(agentRootPath) {
|
|
152825
|
-
return (0,
|
|
152874
|
+
return (0, import_node_path26.join)(agentRootPath, "tools", "diffity");
|
|
152826
152875
|
}
|
|
152827
152876
|
function resolveManagedDiffityExecutablePath(agentRootPath) {
|
|
152828
|
-
return (0,
|
|
152877
|
+
return (0, import_node_path26.join)(
|
|
152829
152878
|
resolveManagedDiffityInstallRoot(agentRootPath),
|
|
152830
152879
|
"node_modules",
|
|
152831
152880
|
".bin",
|
|
@@ -152833,10 +152882,10 @@ function resolveManagedDiffityExecutablePath(agentRootPath) {
|
|
|
152833
152882
|
);
|
|
152834
152883
|
}
|
|
152835
152884
|
function prependPathEntry(entry, existingPath) {
|
|
152836
|
-
const values = existingPath ? existingPath.split(
|
|
152885
|
+
const values = existingPath ? existingPath.split(import_node_path26.delimiter).filter((value2) => value2.trim().length > 0) : [];
|
|
152837
152886
|
const normalizedEntry = entry.trim();
|
|
152838
152887
|
const remaining = values.filter((value2) => value2 !== normalizedEntry);
|
|
152839
|
-
return [normalizedEntry, ...remaining].join(
|
|
152888
|
+
return [normalizedEntry, ...remaining].join(import_node_path26.delimiter);
|
|
152840
152889
|
}
|
|
152841
152890
|
function createDocyrusSkillsInstallArgs(scope) {
|
|
152842
152891
|
const args2 = [
|
|
@@ -152874,8 +152923,8 @@ function createPackagedDocyrusPlatformInstallArgs(params) {
|
|
|
152874
152923
|
return args2;
|
|
152875
152924
|
}
|
|
152876
152925
|
async function installExternalDocyrusSkillsOnce(params) {
|
|
152877
|
-
const markerPath = (0,
|
|
152878
|
-
if ((0,
|
|
152926
|
+
const markerPath = (0, import_node_path26.join)(params.agentRootPath, DOCYRUS_EXTERNAL_SKILL_MARKER_FILE);
|
|
152927
|
+
if ((0, import_node_fs15.existsSync)(markerPath)) {
|
|
152879
152928
|
return;
|
|
152880
152929
|
}
|
|
152881
152930
|
const result = params.spawnCommand(resolveNpxCommand(), createDocyrusSkillsInstallArgs(params.scope), {
|
|
@@ -152907,8 +152956,8 @@ async function installExternalDocyrusSkillsOnce(params) {
|
|
|
152907
152956
|
}
|
|
152908
152957
|
async function ensureManagedDiffityInstalled(params) {
|
|
152909
152958
|
const executablePath = resolveManagedDiffityExecutablePath(params.agentRootPath);
|
|
152910
|
-
const binDir = (0,
|
|
152911
|
-
if ((0,
|
|
152959
|
+
const binDir = (0, import_node_path26.dirname)(executablePath);
|
|
152960
|
+
if ((0, import_node_fs15.existsSync)(executablePath)) {
|
|
152912
152961
|
return {
|
|
152913
152962
|
available: true,
|
|
152914
152963
|
executablePath,
|
|
@@ -152946,19 +152995,19 @@ async function ensureManagedDiffityInstalled(params) {
|
|
|
152946
152995
|
};
|
|
152947
152996
|
}
|
|
152948
152997
|
function resolvePackagedDocyrusPlatformSkillPath(resourceRoot) {
|
|
152949
|
-
return (0,
|
|
152998
|
+
return (0, import_node_path26.join)(resourceRoot, "skills", DOCYRUS_PACKAGED_PLATFORM_SKILL_NAME);
|
|
152950
152999
|
}
|
|
152951
153000
|
function resolvePackagedOfficeCliRootPath(resourceRoot) {
|
|
152952
|
-
return (0,
|
|
153001
|
+
return (0, import_node_path26.join)((0, import_node_path26.resolve)(resourceRoot, ".."), "officecli");
|
|
152953
153002
|
}
|
|
152954
153003
|
function resolvePackagedOfficeCliManifestPath(resourceRoot) {
|
|
152955
|
-
return (0,
|
|
153004
|
+
return (0, import_node_path26.join)(resolvePackagedOfficeCliRootPath(resourceRoot), DOCYRUS_OFFICECLI_MANIFEST_FILE_NAME);
|
|
152956
153005
|
}
|
|
152957
153006
|
function resolveManagedOfficeCliInstallRoot(agentRootPath) {
|
|
152958
|
-
return (0,
|
|
153007
|
+
return (0, import_node_path26.join)(agentRootPath, "tools", "officecli");
|
|
152959
153008
|
}
|
|
152960
153009
|
function resolveManagedOfficeCliExecutablePath(agentRootPath) {
|
|
152961
|
-
return (0,
|
|
153010
|
+
return (0, import_node_path26.join)(
|
|
152962
153011
|
resolveManagedOfficeCliInstallRoot(agentRootPath),
|
|
152963
153012
|
process.platform === "win32" ? "officecli.exe" : "officecli"
|
|
152964
153013
|
);
|
|
@@ -152966,7 +153015,7 @@ function resolveManagedOfficeCliExecutablePath(agentRootPath) {
|
|
|
152966
153015
|
function resolveOfficeCliReleaseAssetName(options2 = {}) {
|
|
152967
153016
|
const platform2 = options2.platform ?? process.platform;
|
|
152968
153017
|
const arch = options2.arch ?? process.arch;
|
|
152969
|
-
const isAlpine = options2.isAlpine ?? (0,
|
|
153018
|
+
const isAlpine = options2.isAlpine ?? (0, import_node_fs15.existsSync)("/etc/alpine-release");
|
|
152970
153019
|
switch (platform2) {
|
|
152971
153020
|
case "darwin":
|
|
152972
153021
|
if (arch === "arm64") {
|
|
@@ -153000,7 +153049,7 @@ function resolveOfficeCliReleaseAssetName(options2 = {}) {
|
|
|
153000
153049
|
throw new UserInputError(`OfficeCLI is not supported on ${platform2}/${arch}.`);
|
|
153001
153050
|
}
|
|
153002
153051
|
function resolvePackagedOfficeCliExecutablePath(resourceRoot, options2) {
|
|
153003
|
-
return (0,
|
|
153052
|
+
return (0, import_node_path26.join)(
|
|
153004
153053
|
resolvePackagedOfficeCliRootPath(resourceRoot),
|
|
153005
153054
|
"bundled",
|
|
153006
153055
|
resolveOfficeCliReleaseAssetName(options2)
|
|
@@ -153028,11 +153077,11 @@ async function downloadOfficeCliBinary(params) {
|
|
|
153028
153077
|
});
|
|
153029
153078
|
}
|
|
153030
153079
|
function resolveManagedOfficeCliConfigMarkerPath(agentRootPath) {
|
|
153031
|
-
return (0,
|
|
153080
|
+
return (0, import_node_path26.join)(resolveManagedOfficeCliInstallRoot(agentRootPath), ".docyrus-officecli-configured.json");
|
|
153032
153081
|
}
|
|
153033
153082
|
async function disableManagedOfficeCliAutoUpdate(params) {
|
|
153034
153083
|
const markerPath = resolveManagedOfficeCliConfigMarkerPath(params.agentRootPath);
|
|
153035
|
-
if ((0,
|
|
153084
|
+
if ((0, import_node_fs15.existsSync)(markerPath)) {
|
|
153036
153085
|
return;
|
|
153037
153086
|
}
|
|
153038
153087
|
const result = params.spawnCommand(params.executablePath, ["config", "autoUpdate", "false"], {
|
|
@@ -153061,8 +153110,8 @@ async function disableManagedOfficeCliAutoUpdate(params) {
|
|
|
153061
153110
|
}
|
|
153062
153111
|
async function ensureManagedOfficeCliInstalled(params) {
|
|
153063
153112
|
const executablePath = resolveManagedOfficeCliExecutablePath(params.agentRootPath);
|
|
153064
|
-
const binDir = (0,
|
|
153065
|
-
if ((0,
|
|
153113
|
+
const binDir = (0, import_node_path26.dirname)(executablePath);
|
|
153114
|
+
if ((0, import_node_fs15.existsSync)(executablePath)) {
|
|
153066
153115
|
await disableManagedOfficeCliAutoUpdate({
|
|
153067
153116
|
agentRootPath: params.agentRootPath,
|
|
153068
153117
|
executablePath,
|
|
@@ -153082,7 +153131,7 @@ async function ensureManagedOfficeCliInstalled(params) {
|
|
|
153082
153131
|
mode: 448
|
|
153083
153132
|
});
|
|
153084
153133
|
const bundledExecutablePath = resolvePackagedOfficeCliExecutablePath(params.resourceRoot);
|
|
153085
|
-
if ((0,
|
|
153134
|
+
if ((0, import_node_fs15.existsSync)(bundledExecutablePath)) {
|
|
153086
153135
|
await (0, import_promises20.cp)(bundledExecutablePath, tempPath, {
|
|
153087
153136
|
force: true
|
|
153088
153137
|
});
|
|
@@ -153141,7 +153190,7 @@ async function ensureManagedOfficeCliInstalled(params) {
|
|
|
153141
153190
|
}
|
|
153142
153191
|
function installPackagedDocyrusPlatformSkill(params) {
|
|
153143
153192
|
const skillSourcePath = resolvePackagedDocyrusPlatformSkillPath(params.resourceRoot);
|
|
153144
|
-
if (!(0,
|
|
153193
|
+
if (!(0, import_node_fs15.existsSync)(skillSourcePath)) {
|
|
153145
153194
|
process.stderr.write("[docyrus] Packaged docyrus-platform skill is missing. Continuing without agent sync.\n");
|
|
153146
153195
|
return;
|
|
153147
153196
|
}
|
|
@@ -153270,8 +153319,8 @@ function createPiAgentLauncher(options2) {
|
|
|
153270
153319
|
|
|
153271
153320
|
// src/services/piAgentServerLauncher.ts
|
|
153272
153321
|
var import_node_child_process7 = require("node:child_process");
|
|
153273
|
-
var
|
|
153274
|
-
var
|
|
153322
|
+
var import_node_fs16 = require("node:fs");
|
|
153323
|
+
var import_node_path27 = require("node:path");
|
|
153275
153324
|
function serializePiAgentServerRequest(request) {
|
|
153276
153325
|
return JSON.stringify(request);
|
|
153277
153326
|
}
|
|
@@ -153285,26 +153334,26 @@ function resolveServerLoaderEntryPath(cwd, dirname13) {
|
|
|
153285
153334
|
}
|
|
153286
153335
|
};
|
|
153287
153336
|
const collectAncestorCandidates = (startDir) => {
|
|
153288
|
-
let currentDir = (0,
|
|
153337
|
+
let currentDir = (0, import_node_path27.resolve)(startDir);
|
|
153289
153338
|
while (true) {
|
|
153290
|
-
addCandidate((0,
|
|
153291
|
-
addCandidate((0,
|
|
153292
|
-
if ((0,
|
|
153293
|
-
addCandidate((0,
|
|
153339
|
+
addCandidate((0, import_node_path27.join)(currentDir, "dist", "apps", "api-cli", "server-loader.js"));
|
|
153340
|
+
addCandidate((0, import_node_path27.join)(currentDir, "server-loader.js"));
|
|
153341
|
+
if ((0, import_node_path27.basename)(currentDir) === "dist") {
|
|
153342
|
+
addCandidate((0, import_node_path27.join)(currentDir, "apps", "api-cli", "server-loader.js"));
|
|
153294
153343
|
}
|
|
153295
|
-
const parentDir = (0,
|
|
153344
|
+
const parentDir = (0, import_node_path27.resolve)(currentDir, "..");
|
|
153296
153345
|
if (parentDir === currentDir) {
|
|
153297
153346
|
break;
|
|
153298
153347
|
}
|
|
153299
153348
|
currentDir = parentDir;
|
|
153300
153349
|
}
|
|
153301
153350
|
};
|
|
153302
|
-
addCandidate((0,
|
|
153303
|
-
addCandidate((0,
|
|
153304
|
-
addCandidate((0,
|
|
153351
|
+
addCandidate((0, import_node_path27.resolve)(cwd, "dist/apps/api-cli/server-loader.js"));
|
|
153352
|
+
addCandidate((0, import_node_path27.resolve)(dirname13, "../server-loader.js"));
|
|
153353
|
+
addCandidate((0, import_node_path27.resolve)(dirname13, "server-loader.js"));
|
|
153305
153354
|
collectAncestorCandidates(cwd);
|
|
153306
153355
|
collectAncestorCandidates(dirname13);
|
|
153307
|
-
const resolved = candidates.find((candidate) => (0,
|
|
153356
|
+
const resolved = candidates.find((candidate) => (0, import_node_fs16.existsSync)(candidate));
|
|
153308
153357
|
if (!resolved) {
|
|
153309
153358
|
throw new UserInputError(`Unable to locate Docyrus pi server loader entry file. Checked: ${candidates.join(", ")}`);
|
|
153310
153359
|
}
|
|
@@ -153422,7 +153471,7 @@ async function runWithIncurSkillsOutOfDateWarningSuppressed(params) {
|
|
|
153422
153471
|
|
|
153423
153472
|
// src/services/tenantOpenApi.ts
|
|
153424
153473
|
var import_promises21 = require("node:fs/promises");
|
|
153425
|
-
var
|
|
153474
|
+
var import_node_path28 = require("node:path");
|
|
153426
153475
|
function resolveSourceUrl(tenantId, template) {
|
|
153427
153476
|
return template.replace("{tenantId}", encodeURIComponent(tenantId));
|
|
153428
153477
|
}
|
|
@@ -153447,7 +153496,7 @@ var TenantOpenApiService = class {
|
|
|
153447
153496
|
params;
|
|
153448
153497
|
async #writeOpenApiFile(tenantId, parsedContent) {
|
|
153449
153498
|
const filePath = this.getTenantOpenApiFilePath(tenantId);
|
|
153450
|
-
await (0, import_promises21.mkdir)((0,
|
|
153499
|
+
await (0, import_promises21.mkdir)((0, import_node_path28.dirname)(filePath), {
|
|
153451
153500
|
recursive: true,
|
|
153452
153501
|
mode: 448
|
|
153453
153502
|
});
|
|
@@ -153493,7 +153542,7 @@ var TenantOpenApiService = class {
|
|
|
153493
153542
|
throw new AuthSessionError("Tenant ID is required to resolve OpenAPI spec path.");
|
|
153494
153543
|
}
|
|
153495
153544
|
const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
|
|
153496
|
-
return (0,
|
|
153545
|
+
return (0, import_node_path28.join)(rootPath, normalizedTenantId, "openapi.json");
|
|
153497
153546
|
}
|
|
153498
153547
|
async downloadTenantOpenApi(tenantId, options2 = {}) {
|
|
153499
153548
|
const normalizedTenantId = tenantId.trim();
|