@mc1global/opencode-jarvis 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/dist/application/azure-sync/task-push-use-cases.d.ts.map +1 -1
- package/dist/application/azure-sync/task-push-use-cases.js +21 -3
- package/dist/application/azure-sync/task-push-use-cases.js.map +1 -1
- package/dist/application/bootstrap/use-cases.d.ts.map +1 -1
- package/dist/application/bootstrap/use-cases.js +4 -4
- package/dist/application/bootstrap/use-cases.js.map +1 -1
- package/dist/application/config/config-service.d.ts +3 -1
- package/dist/application/config/config-service.d.ts.map +1 -1
- package/dist/application/config/config-service.js +4 -0
- package/dist/application/config/config-service.js.map +1 -1
- package/dist/application/wiki-feedback/poll-service.d.ts +56 -0
- package/dist/application/wiki-feedback/poll-service.d.ts.map +1 -0
- package/dist/application/wiki-feedback/poll-service.js +87 -0
- package/dist/application/wiki-feedback/poll-service.js.map +1 -0
- package/dist/application/wiki-feedback/use-cases.d.ts +115 -0
- package/dist/application/wiki-feedback/use-cases.d.ts.map +1 -0
- package/dist/application/wiki-feedback/use-cases.js +271 -0
- package/dist/application/wiki-feedback/use-cases.js.map +1 -0
- package/dist/domain/config/value-objects.d.ts +28 -1
- package/dist/domain/config/value-objects.d.ts.map +1 -1
- package/dist/domain/config/value-objects.js +10 -0
- package/dist/domain/config/value-objects.js.map +1 -1
- package/dist/domain/governance/policies.d.ts.map +1 -1
- package/dist/domain/governance/policies.js +41 -0
- package/dist/domain/governance/policies.js.map +1 -1
- package/dist/domain/wiki-feedback/entities.d.ts +101 -0
- package/dist/domain/wiki-feedback/entities.d.ts.map +1 -0
- package/dist/domain/wiki-feedback/entities.js +154 -0
- package/dist/domain/wiki-feedback/entities.js.map +1 -0
- package/dist/domain/wiki-feedback/index.d.ts +13 -0
- package/dist/domain/wiki-feedback/index.d.ts.map +1 -0
- package/dist/domain/wiki-feedback/index.js +11 -0
- package/dist/domain/wiki-feedback/index.js.map +1 -0
- package/dist/domain/wiki-feedback/ports.d.ts +47 -0
- package/dist/domain/wiki-feedback/ports.d.ts.map +1 -0
- package/dist/domain/wiki-feedback/ports.js +13 -0
- package/dist/domain/wiki-feedback/ports.js.map +1 -0
- package/dist/domain/wiki-feedback/repositories.d.ts +33 -0
- package/dist/domain/wiki-feedback/repositories.d.ts.map +1 -0
- package/dist/domain/wiki-feedback/repositories.js +12 -0
- package/dist/domain/wiki-feedback/repositories.js.map +1 -0
- package/dist/domain/wiki-feedback/value-objects.d.ts +74 -0
- package/dist/domain/wiki-feedback/value-objects.d.ts.map +1 -0
- package/dist/domain/wiki-feedback/value-objects.js +144 -0
- package/dist/domain/wiki-feedback/value-objects.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/wiki-feedback/azure-wiki-client.d.ts +36 -0
- package/dist/infrastructure/wiki-feedback/azure-wiki-client.d.ts.map +1 -0
- package/dist/infrastructure/wiki-feedback/azure-wiki-client.js +106 -0
- package/dist/infrastructure/wiki-feedback/azure-wiki-client.js.map +1 -0
- package/dist/infrastructure/wiki-feedback/sqlite-feedback-repository.d.ts +31 -0
- package/dist/infrastructure/wiki-feedback/sqlite-feedback-repository.d.ts.map +1 -0
- package/dist/infrastructure/wiki-feedback/sqlite-feedback-repository.js +149 -0
- package/dist/infrastructure/wiki-feedback/sqlite-feedback-repository.js.map +1 -0
- package/dist/tools/wiki-feedback-tools.d.ts +9 -0
- package/dist/tools/wiki-feedback-tools.d.ts.map +1 -0
- package/dist/tools/wiki-feedback-tools.js +189 -0
- package/dist/tools/wiki-feedback-tools.js.map +1 -0
- package/package.json +1 -1
- package/templates/agents-md.template.md +7 -2
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Entities
|
|
3
|
+
*
|
|
4
|
+
* WikiFeedbackItem tracks a wiki comment through the feedback lifecycle:
|
|
5
|
+
* pending → triaged → card_created / dismissed.
|
|
6
|
+
*
|
|
7
|
+
* SOLID: SRP — entity manages its own state and invariants
|
|
8
|
+
* DDD: Entity with identity and lifecycle, mutable state with guards
|
|
9
|
+
*/
|
|
10
|
+
import { Timestamp } from "../shared/value-objects.js";
|
|
11
|
+
import { WikiFeedbackId, CommentAuthor, PageSource } from "./value-objects.js";
|
|
12
|
+
// ─── WikiFeedbackItem Entity ──────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Represents a wiki comment captured from Azure DevOps Wiki.
|
|
15
|
+
* Tracks the comment through a feedback lifecycle from detection
|
|
16
|
+
* to either card creation or dismissal.
|
|
17
|
+
*
|
|
18
|
+
* Lifecycle: pending → triaged → card_created / dismissed
|
|
19
|
+
* (dismiss can also happen directly from pending)
|
|
20
|
+
*/
|
|
21
|
+
export class WikiFeedbackItem {
|
|
22
|
+
_id;
|
|
23
|
+
_azureCommentId;
|
|
24
|
+
_commentText;
|
|
25
|
+
_author;
|
|
26
|
+
_pageSource;
|
|
27
|
+
_detectedAt;
|
|
28
|
+
_commentCreatedDate;
|
|
29
|
+
_status;
|
|
30
|
+
_feedbackType;
|
|
31
|
+
_priority;
|
|
32
|
+
_cardId;
|
|
33
|
+
_dismissReason;
|
|
34
|
+
_triagedAt;
|
|
35
|
+
_resolvedAt;
|
|
36
|
+
constructor(_id, _azureCommentId, _commentText, _author, _pageSource, status, feedbackType, priority, cardId, dismissReason, _detectedAt, triagedAt, resolvedAt, _commentCreatedDate) {
|
|
37
|
+
this._id = _id;
|
|
38
|
+
this._azureCommentId = _azureCommentId;
|
|
39
|
+
this._commentText = _commentText;
|
|
40
|
+
this._author = _author;
|
|
41
|
+
this._pageSource = _pageSource;
|
|
42
|
+
this._detectedAt = _detectedAt;
|
|
43
|
+
this._commentCreatedDate = _commentCreatedDate;
|
|
44
|
+
this._status = status;
|
|
45
|
+
this._feedbackType = feedbackType;
|
|
46
|
+
this._priority = priority;
|
|
47
|
+
this._cardId = cardId;
|
|
48
|
+
this._dismissReason = dismissReason;
|
|
49
|
+
this._triagedAt = triagedAt;
|
|
50
|
+
this._resolvedAt = resolvedAt;
|
|
51
|
+
}
|
|
52
|
+
// ── Factory Methods ───────────────────────────────────────────────
|
|
53
|
+
/** Create a new feedback item from a detected wiki comment. */
|
|
54
|
+
static create(params) {
|
|
55
|
+
if (!Number.isInteger(params.azureCommentId) || params.azureCommentId < 1) {
|
|
56
|
+
throw new Error("WikiFeedbackItem: azureCommentId must be a positive integer");
|
|
57
|
+
}
|
|
58
|
+
if (!params.commentText.trim()) {
|
|
59
|
+
throw new Error("WikiFeedbackItem: commentText cannot be empty");
|
|
60
|
+
}
|
|
61
|
+
return new WikiFeedbackItem(params.id, params.azureCommentId, params.commentText.trim(), params.author, params.pageSource, "pending", null, null, null, null, Timestamp.now(), null, null, params.commentCreatedDate);
|
|
62
|
+
}
|
|
63
|
+
/** Reconstitute from persistence (trusted data, no validation). */
|
|
64
|
+
static reconstitute(props) {
|
|
65
|
+
return new WikiFeedbackItem(WikiFeedbackId.from(props.id), props.azureCommentId, props.commentText, CommentAuthor.from(props.authorDisplayName, props.authorUniqueName), PageSource.from(props.pageId, props.pagePath, props.pageDefaultType), props.status, props.feedbackType, props.priority, props.cardId, props.dismissReason, Timestamp.fromISO(props.detectedAt), props.triagedAt ? Timestamp.fromISO(props.triagedAt) : null, props.resolvedAt ? Timestamp.fromISO(props.resolvedAt) : null, Timestamp.fromISO(props.commentCreatedDate));
|
|
66
|
+
}
|
|
67
|
+
// ── Getters ───────────────────────────────────────────────────────
|
|
68
|
+
get id() { return this._id; }
|
|
69
|
+
get azureCommentId() { return this._azureCommentId; }
|
|
70
|
+
get commentText() { return this._commentText; }
|
|
71
|
+
get author() { return this._author; }
|
|
72
|
+
get pageSource() { return this._pageSource; }
|
|
73
|
+
get status() { return this._status; }
|
|
74
|
+
get feedbackType() { return this._feedbackType; }
|
|
75
|
+
get priority() { return this._priority; }
|
|
76
|
+
get cardId() { return this._cardId; }
|
|
77
|
+
get dismissReason() { return this._dismissReason; }
|
|
78
|
+
get detectedAt() { return this._detectedAt; }
|
|
79
|
+
get triagedAt() { return this._triagedAt; }
|
|
80
|
+
get resolvedAt() { return this._resolvedAt; }
|
|
81
|
+
get commentCreatedDate() { return this._commentCreatedDate; }
|
|
82
|
+
// ── State Mutations ───────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Triage this feedback item: assign type and priority.
|
|
85
|
+
* Transition: pending → triaged
|
|
86
|
+
*/
|
|
87
|
+
triage(feedbackType, priority) {
|
|
88
|
+
if (this._status !== "pending") {
|
|
89
|
+
throw new Error(`WikiFeedbackItem: cannot triage from status "${this._status}" — must be "pending"`);
|
|
90
|
+
}
|
|
91
|
+
this._feedbackType = feedbackType;
|
|
92
|
+
this._priority = priority;
|
|
93
|
+
this._status = "triaged";
|
|
94
|
+
this._triagedAt = Timestamp.now();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Mark this feedback as having a kanban card created from it.
|
|
98
|
+
* Transition: triaged → card_created
|
|
99
|
+
*/
|
|
100
|
+
markCardCreated(cardId) {
|
|
101
|
+
if (this._status !== "triaged") {
|
|
102
|
+
throw new Error(`WikiFeedbackItem: cannot mark card_created from status "${this._status}" — must be "triaged"`);
|
|
103
|
+
}
|
|
104
|
+
if (!cardId.trim()) {
|
|
105
|
+
throw new Error("WikiFeedbackItem: cardId cannot be empty");
|
|
106
|
+
}
|
|
107
|
+
this._cardId = cardId.trim();
|
|
108
|
+
this._status = "card_created";
|
|
109
|
+
this._resolvedAt = Timestamp.now();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Dismiss this feedback item with a reason.
|
|
113
|
+
* Transition: pending → dismissed OR triaged → dismissed
|
|
114
|
+
*/
|
|
115
|
+
dismiss(reason) {
|
|
116
|
+
if (this._status !== "pending" && this._status !== "triaged") {
|
|
117
|
+
throw new Error(`WikiFeedbackItem: cannot dismiss from status "${this._status}" — must be "pending" or "triaged"`);
|
|
118
|
+
}
|
|
119
|
+
if (!reason.trim()) {
|
|
120
|
+
throw new Error("WikiFeedbackItem: dismiss reason cannot be empty");
|
|
121
|
+
}
|
|
122
|
+
this._dismissReason = reason.trim();
|
|
123
|
+
this._status = "dismissed";
|
|
124
|
+
this._resolvedAt = Timestamp.now();
|
|
125
|
+
}
|
|
126
|
+
// ── Query ─────────────────────────────────────────────────────────
|
|
127
|
+
/** Whether this feedback item has been resolved (card created or dismissed). */
|
|
128
|
+
get isResolved() {
|
|
129
|
+
return this._status === "card_created" || this._status === "dismissed";
|
|
130
|
+
}
|
|
131
|
+
// ── Serialization ─────────────────────────────────────────────────
|
|
132
|
+
toProps() {
|
|
133
|
+
return {
|
|
134
|
+
id: this._id.value,
|
|
135
|
+
azureCommentId: this._azureCommentId,
|
|
136
|
+
commentText: this._commentText,
|
|
137
|
+
authorDisplayName: this._author.displayName,
|
|
138
|
+
authorUniqueName: this._author.uniqueName,
|
|
139
|
+
pageId: this._pageSource.pageId,
|
|
140
|
+
pagePath: this._pageSource.pagePath,
|
|
141
|
+
pageDefaultType: this._pageSource.defaultType,
|
|
142
|
+
status: this._status,
|
|
143
|
+
feedbackType: this._feedbackType,
|
|
144
|
+
priority: this._priority,
|
|
145
|
+
cardId: this._cardId,
|
|
146
|
+
dismissReason: this._dismissReason,
|
|
147
|
+
detectedAt: this._detectedAt.toISO(),
|
|
148
|
+
triagedAt: this._triagedAt?.toISO() ?? null,
|
|
149
|
+
resolvedAt: this._resolvedAt?.toISO() ?? null,
|
|
150
|
+
commentCreatedDate: this._commentCreatedDate.toISO(),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/entities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Barrel Export
|
|
3
|
+
*
|
|
4
|
+
* Public API for the wiki-feedback bounded context domain layer.
|
|
5
|
+
* Groups exports by category for clean import paths.
|
|
6
|
+
*/
|
|
7
|
+
export { WikiFeedbackId, CommentAuthor, PageSource, FEEDBACK_STATUSES, FEEDBACK_TYPES, FEEDBACK_PRIORITIES, isValidFeedbackStatus, isValidFeedbackType, isValidFeedbackPriority, } from "./value-objects.js";
|
|
8
|
+
export type { FeedbackStatus, FeedbackType, FeedbackPriority, } from "./value-objects.js";
|
|
9
|
+
export { WikiFeedbackItem } from "./entities.js";
|
|
10
|
+
export type { WikiFeedbackItemProps } from "./entities.js";
|
|
11
|
+
export type { WikiFeedbackRepository } from "./repositories.js";
|
|
12
|
+
export type { WikiClientPort, WikiComment } from "./ports.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,cAAc,EACd,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAI3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAIhE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Barrel Export
|
|
3
|
+
*
|
|
4
|
+
* Public API for the wiki-feedback bounded context domain layer.
|
|
5
|
+
* Groups exports by category for clean import paths.
|
|
6
|
+
*/
|
|
7
|
+
// ── Value Objects ────────────────────────────────────────────────────────────
|
|
8
|
+
export { WikiFeedbackId, CommentAuthor, PageSource, FEEDBACK_STATUSES, FEEDBACK_TYPES, FEEDBACK_PRIORITIES, isValidFeedbackStatus, isValidFeedbackType, isValidFeedbackPriority, } from "./value-objects.js";
|
|
9
|
+
// ── Entities ─────────────────────────────────────────────────────────────────
|
|
10
|
+
export { WikiFeedbackItem } from "./entities.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gFAAgF;AAEhF,OAAO,EACL,cAAc,EACd,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAQ5B,gFAAgF;AAEhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Port Interfaces
|
|
3
|
+
*
|
|
4
|
+
* Hexagonal ports defining contracts for external systems.
|
|
5
|
+
* The Azure Wiki client is an infrastructure concern;
|
|
6
|
+
* domain only defines what operations it needs.
|
|
7
|
+
*
|
|
8
|
+
* SOLID: DIP — domain defines contracts, infra implements
|
|
9
|
+
* SOLID: ISP — focused interface per capability
|
|
10
|
+
* DDD: Ports & Adapters pattern
|
|
11
|
+
*/
|
|
12
|
+
import type { Result } from "../shared/value-objects.js";
|
|
13
|
+
/** Represents a comment on a wiki page as returned by the API. */
|
|
14
|
+
export interface WikiComment {
|
|
15
|
+
readonly id: number;
|
|
16
|
+
readonly text: string;
|
|
17
|
+
readonly createdBy: {
|
|
18
|
+
readonly displayName: string;
|
|
19
|
+
readonly uniqueName: string;
|
|
20
|
+
};
|
|
21
|
+
readonly createdDate: string;
|
|
22
|
+
readonly modifiedDate: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Port interface for interacting with Azure DevOps Wiki comments.
|
|
26
|
+
* Infrastructure layer provides the concrete HTTP implementation.
|
|
27
|
+
*/
|
|
28
|
+
export interface WikiClientPort {
|
|
29
|
+
/**
|
|
30
|
+
* Fetch all comments from a wiki page.
|
|
31
|
+
* Returns comments ordered by creation date (newest first).
|
|
32
|
+
*/
|
|
33
|
+
getPageComments(params: {
|
|
34
|
+
wikiIdentifier: string;
|
|
35
|
+
pageId: number;
|
|
36
|
+
}): Promise<Result<readonly WikiComment[]>>;
|
|
37
|
+
/**
|
|
38
|
+
* Post a comment on a wiki page.
|
|
39
|
+
* Used for auto-reply when a feedback item is converted to a card.
|
|
40
|
+
*/
|
|
41
|
+
postPageComment(params: {
|
|
42
|
+
wikiIdentifier: string;
|
|
43
|
+
pageId: number;
|
|
44
|
+
text: string;
|
|
45
|
+
}): Promise<Result<WikiComment>>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAIzD,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAID;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC,CAAC;IAE5C;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Port Interfaces
|
|
3
|
+
*
|
|
4
|
+
* Hexagonal ports defining contracts for external systems.
|
|
5
|
+
* The Azure Wiki client is an infrastructure concern;
|
|
6
|
+
* domain only defines what operations it needs.
|
|
7
|
+
*
|
|
8
|
+
* SOLID: DIP — domain defines contracts, infra implements
|
|
9
|
+
* SOLID: ISP — focused interface per capability
|
|
10
|
+
* DDD: Ports & Adapters pattern
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Repository Interfaces (Ports)
|
|
3
|
+
*
|
|
4
|
+
* Pure interfaces defining persistence contracts for wiki feedback items.
|
|
5
|
+
* Implementations provided by infrastructure layer (DIP).
|
|
6
|
+
*
|
|
7
|
+
* SOLID: ISP — focused interface for feedback aggregate
|
|
8
|
+
* SOLID: DIP — domain defines contracts, infra implements
|
|
9
|
+
* DDD: Repository pattern — abstracts persistence behind domain-driven interface
|
|
10
|
+
*/
|
|
11
|
+
import type { WikiFeedbackItem } from "./entities.js";
|
|
12
|
+
import type { WikiFeedbackId, FeedbackStatus } from "./value-objects.js";
|
|
13
|
+
/**
|
|
14
|
+
* Repository for WikiFeedbackItem persistence.
|
|
15
|
+
* Each item represents a wiki comment captured from Azure DevOps Wiki.
|
|
16
|
+
*/
|
|
17
|
+
export interface WikiFeedbackRepository {
|
|
18
|
+
/** Persist a feedback item (create or update). */
|
|
19
|
+
save(item: WikiFeedbackItem): Promise<void>;
|
|
20
|
+
/** Find a feedback item by its ID. Returns undefined if not found. */
|
|
21
|
+
findById(id: WikiFeedbackId): Promise<WikiFeedbackItem | undefined>;
|
|
22
|
+
/** Find a feedback item by its Azure comment ID (deduplication). */
|
|
23
|
+
findByAzureCommentId(azureCommentId: number): Promise<WikiFeedbackItem | undefined>;
|
|
24
|
+
/** Find all feedback items with a specific status. */
|
|
25
|
+
findByStatus(status: FeedbackStatus, limit?: number): Promise<readonly WikiFeedbackItem[]>;
|
|
26
|
+
/** Find all pending (unprocessed) feedback items. */
|
|
27
|
+
findPending(limit?: number): Promise<readonly WikiFeedbackItem[]>;
|
|
28
|
+
/** Find recent feedback items across all statuses. */
|
|
29
|
+
findRecent(limit: number): Promise<readonly WikiFeedbackItem[]>;
|
|
30
|
+
/** Get the next available sequence number for WikiFeedbackId generation. */
|
|
31
|
+
nextFeedbackSequence(): Promise<number>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=repositories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repositories.d.ts","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/repositories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,kDAAkD;IAClD,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAEpE,oEAAoE;IACpE,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAEpF,sDAAsD;IACtD,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;IAE3F,qDAAqD;IACrD,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;IAElE,sDAAsD;IACtD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;IAEhE,4EAA4E;IAC5E,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Repository Interfaces (Ports)
|
|
3
|
+
*
|
|
4
|
+
* Pure interfaces defining persistence contracts for wiki feedback items.
|
|
5
|
+
* Implementations provided by infrastructure layer (DIP).
|
|
6
|
+
*
|
|
7
|
+
* SOLID: ISP — focused interface for feedback aggregate
|
|
8
|
+
* SOLID: DIP — domain defines contracts, infra implements
|
|
9
|
+
* DDD: Repository pattern — abstracts persistence behind domain-driven interface
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=repositories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repositories.js","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/repositories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Value Objects
|
|
3
|
+
*
|
|
4
|
+
* Identifiers, enums, and constrained types for the wiki-feedback bounded context.
|
|
5
|
+
* Models wiki comment metadata, feedback lifecycle statuses, and type classification.
|
|
6
|
+
* Zero external dependencies (pure domain).
|
|
7
|
+
*
|
|
8
|
+
* SOLID: SRP — each type models a single domain concept
|
|
9
|
+
* DDD: Value Objects compared by value, no identity of their own
|
|
10
|
+
*/
|
|
11
|
+
import { EntityId } from "../shared/value-objects.js";
|
|
12
|
+
/** Wiki feedback item identifier (format: WF-NNN). */
|
|
13
|
+
export declare class WikiFeedbackId extends EntityId {
|
|
14
|
+
private constructor();
|
|
15
|
+
static create(sequence: number): WikiFeedbackId;
|
|
16
|
+
static from(value: string): WikiFeedbackId;
|
|
17
|
+
get sequence(): number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Lifecycle status for a WikiFeedbackItem.
|
|
21
|
+
* - pending: detected but not yet triaged
|
|
22
|
+
* - triaged: agent assigned type/priority, card proposal ready
|
|
23
|
+
* - card_created: kanban card was created from this feedback
|
|
24
|
+
* - dismissed: agent decided not to act on this feedback
|
|
25
|
+
*/
|
|
26
|
+
export declare const FEEDBACK_STATUSES: readonly ["pending", "triaged", "card_created", "dismissed"];
|
|
27
|
+
export type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];
|
|
28
|
+
export declare function isValidFeedbackStatus(value: string): value is FeedbackStatus;
|
|
29
|
+
/**
|
|
30
|
+
* Classification of the feedback item.
|
|
31
|
+
* Assigned during triage based on content analysis.
|
|
32
|
+
*/
|
|
33
|
+
export declare const FEEDBACK_TYPES: readonly ["feature", "bug", "improvement", "question", "documentation"];
|
|
34
|
+
export type FeedbackType = (typeof FEEDBACK_TYPES)[number];
|
|
35
|
+
export declare function isValidFeedbackType(value: string): value is FeedbackType;
|
|
36
|
+
/**
|
|
37
|
+
* Suggested priority for the feedback item.
|
|
38
|
+
* Assigned during triage; maps to kanban card priority.
|
|
39
|
+
*/
|
|
40
|
+
export declare const FEEDBACK_PRIORITIES: readonly ["high", "medium", "low"];
|
|
41
|
+
export type FeedbackPriority = (typeof FEEDBACK_PRIORITIES)[number];
|
|
42
|
+
export declare function isValidFeedbackPriority(value: string): value is FeedbackPriority;
|
|
43
|
+
/**
|
|
44
|
+
* Value object representing the author of a wiki comment.
|
|
45
|
+
* Extracted from Azure DevOps IdentityRef.
|
|
46
|
+
*/
|
|
47
|
+
export declare class CommentAuthor {
|
|
48
|
+
readonly displayName: string;
|
|
49
|
+
readonly uniqueName: string;
|
|
50
|
+
private constructor();
|
|
51
|
+
/** Create from Azure DevOps identity fields. */
|
|
52
|
+
static create(displayName: string, uniqueName: string): CommentAuthor;
|
|
53
|
+
/** Reconstitute from persistence (trusted data). */
|
|
54
|
+
static from(displayName: string, uniqueName: string): CommentAuthor;
|
|
55
|
+
equals(other: CommentAuthor): boolean;
|
|
56
|
+
toString(): string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Value object representing the wiki page where the comment was posted.
|
|
60
|
+
* Links feedback back to its source page for context.
|
|
61
|
+
*/
|
|
62
|
+
export declare class PageSource {
|
|
63
|
+
readonly pageId: number;
|
|
64
|
+
readonly pagePath: string;
|
|
65
|
+
readonly defaultType: FeedbackType;
|
|
66
|
+
private constructor();
|
|
67
|
+
/** Create with validation. */
|
|
68
|
+
static create(pageId: number, pagePath: string, defaultType: FeedbackType): PageSource;
|
|
69
|
+
/** Reconstitute from persistence (trusted data). */
|
|
70
|
+
static from(pageId: number, pagePath: string, defaultType: FeedbackType): PageSource;
|
|
71
|
+
equals(other: PageSource): boolean;
|
|
72
|
+
toString(): string;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=value-objects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-objects.d.ts","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/value-objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAItD,sDAAsD;AACtD,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO;IAIP,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAO/C,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAI1C,IAAI,QAAQ,IAAI,MAAM,CAGrB;CACF;AAID;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,8DAKpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAE5E;AAID;;;GAGG;AACH,eAAO,MAAM,cAAc,yEAMjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,YAAY,CAExE;AAID;;;GAGG;AACH,eAAO,MAAM,mBAAmB,oCAAqC,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAEhF;AAID;;;GAGG;AACH,qBAAa,aAAa;aAEN,WAAW,EAAE,MAAM;aACnB,UAAU,EAAE,MAAM;IAFpC,OAAO;IAKP,gDAAgD;IAChD,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa;IAUrE,oDAAoD;IACpD,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa;IAInE,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAIrC,QAAQ,IAAI,MAAM;CAGnB;AAID;;;GAGG;AACH,qBAAa,UAAU;aAEH,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAChB,WAAW,EAAE,YAAY;IAH3C,OAAO;IAMP,8BAA8B;IAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,UAAU;IAatF,oDAAoD;IACpD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,UAAU;IAIpF,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAIlC,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Feedback Domain — Value Objects
|
|
3
|
+
*
|
|
4
|
+
* Identifiers, enums, and constrained types for the wiki-feedback bounded context.
|
|
5
|
+
* Models wiki comment metadata, feedback lifecycle statuses, and type classification.
|
|
6
|
+
* Zero external dependencies (pure domain).
|
|
7
|
+
*
|
|
8
|
+
* SOLID: SRP — each type models a single domain concept
|
|
9
|
+
* DDD: Value Objects compared by value, no identity of their own
|
|
10
|
+
*/
|
|
11
|
+
import { EntityId } from "../shared/value-objects.js";
|
|
12
|
+
// ─── Identifiers ──────────────────────────────────────────────────────────────
|
|
13
|
+
/** Wiki feedback item identifier (format: WF-NNN). */
|
|
14
|
+
export class WikiFeedbackId extends EntityId {
|
|
15
|
+
constructor(value) {
|
|
16
|
+
super(value);
|
|
17
|
+
}
|
|
18
|
+
static create(sequence) {
|
|
19
|
+
if (!Number.isInteger(sequence) || sequence < 1) {
|
|
20
|
+
throw new Error("WikiFeedbackId: sequence must be a positive integer");
|
|
21
|
+
}
|
|
22
|
+
return new WikiFeedbackId(`WF-${String(sequence).padStart(3, "0")}`);
|
|
23
|
+
}
|
|
24
|
+
static from(value) {
|
|
25
|
+
return new WikiFeedbackId(value);
|
|
26
|
+
}
|
|
27
|
+
get sequence() {
|
|
28
|
+
const parts = this.value.split("-");
|
|
29
|
+
return parseInt(parts[1] ?? "0", 10);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ─── Feedback Status ──────────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Lifecycle status for a WikiFeedbackItem.
|
|
35
|
+
* - pending: detected but not yet triaged
|
|
36
|
+
* - triaged: agent assigned type/priority, card proposal ready
|
|
37
|
+
* - card_created: kanban card was created from this feedback
|
|
38
|
+
* - dismissed: agent decided not to act on this feedback
|
|
39
|
+
*/
|
|
40
|
+
export const FEEDBACK_STATUSES = [
|
|
41
|
+
"pending",
|
|
42
|
+
"triaged",
|
|
43
|
+
"card_created",
|
|
44
|
+
"dismissed",
|
|
45
|
+
];
|
|
46
|
+
export function isValidFeedbackStatus(value) {
|
|
47
|
+
return FEEDBACK_STATUSES.includes(value);
|
|
48
|
+
}
|
|
49
|
+
// ─── Feedback Type ────────────────────────────────────────────────────────────
|
|
50
|
+
/**
|
|
51
|
+
* Classification of the feedback item.
|
|
52
|
+
* Assigned during triage based on content analysis.
|
|
53
|
+
*/
|
|
54
|
+
export const FEEDBACK_TYPES = [
|
|
55
|
+
"feature",
|
|
56
|
+
"bug",
|
|
57
|
+
"improvement",
|
|
58
|
+
"question",
|
|
59
|
+
"documentation",
|
|
60
|
+
];
|
|
61
|
+
export function isValidFeedbackType(value) {
|
|
62
|
+
return FEEDBACK_TYPES.includes(value);
|
|
63
|
+
}
|
|
64
|
+
// ─── Priority Suggestion ──────────────────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* Suggested priority for the feedback item.
|
|
67
|
+
* Assigned during triage; maps to kanban card priority.
|
|
68
|
+
*/
|
|
69
|
+
export const FEEDBACK_PRIORITIES = ["high", "medium", "low"];
|
|
70
|
+
export function isValidFeedbackPriority(value) {
|
|
71
|
+
return FEEDBACK_PRIORITIES.includes(value);
|
|
72
|
+
}
|
|
73
|
+
// ─── Comment Author ───────────────────────────────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Value object representing the author of a wiki comment.
|
|
76
|
+
* Extracted from Azure DevOps IdentityRef.
|
|
77
|
+
*/
|
|
78
|
+
export class CommentAuthor {
|
|
79
|
+
displayName;
|
|
80
|
+
uniqueName;
|
|
81
|
+
constructor(displayName, uniqueName) {
|
|
82
|
+
this.displayName = displayName;
|
|
83
|
+
this.uniqueName = uniqueName;
|
|
84
|
+
}
|
|
85
|
+
/** Create from Azure DevOps identity fields. */
|
|
86
|
+
static create(displayName, uniqueName) {
|
|
87
|
+
if (!displayName.trim()) {
|
|
88
|
+
throw new Error("CommentAuthor: displayName cannot be empty");
|
|
89
|
+
}
|
|
90
|
+
if (!uniqueName.trim()) {
|
|
91
|
+
throw new Error("CommentAuthor: uniqueName cannot be empty");
|
|
92
|
+
}
|
|
93
|
+
return new CommentAuthor(displayName.trim(), uniqueName.trim());
|
|
94
|
+
}
|
|
95
|
+
/** Reconstitute from persistence (trusted data). */
|
|
96
|
+
static from(displayName, uniqueName) {
|
|
97
|
+
return new CommentAuthor(displayName, uniqueName);
|
|
98
|
+
}
|
|
99
|
+
equals(other) {
|
|
100
|
+
return this.uniqueName === other.uniqueName;
|
|
101
|
+
}
|
|
102
|
+
toString() {
|
|
103
|
+
return `${this.displayName} <${this.uniqueName}>`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ─── Page Source ──────────────────────────────────────────────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* Value object representing the wiki page where the comment was posted.
|
|
109
|
+
* Links feedback back to its source page for context.
|
|
110
|
+
*/
|
|
111
|
+
export class PageSource {
|
|
112
|
+
pageId;
|
|
113
|
+
pagePath;
|
|
114
|
+
defaultType;
|
|
115
|
+
constructor(pageId, pagePath, defaultType) {
|
|
116
|
+
this.pageId = pageId;
|
|
117
|
+
this.pagePath = pagePath;
|
|
118
|
+
this.defaultType = defaultType;
|
|
119
|
+
}
|
|
120
|
+
/** Create with validation. */
|
|
121
|
+
static create(pageId, pagePath, defaultType) {
|
|
122
|
+
if (!Number.isInteger(pageId) || pageId < 1) {
|
|
123
|
+
throw new Error("PageSource: pageId must be a positive integer");
|
|
124
|
+
}
|
|
125
|
+
if (!pagePath.trim()) {
|
|
126
|
+
throw new Error("PageSource: pagePath cannot be empty");
|
|
127
|
+
}
|
|
128
|
+
if (!isValidFeedbackType(defaultType)) {
|
|
129
|
+
throw new Error(`PageSource: invalid defaultType "${defaultType}"`);
|
|
130
|
+
}
|
|
131
|
+
return new PageSource(pageId, pagePath.trim(), defaultType);
|
|
132
|
+
}
|
|
133
|
+
/** Reconstitute from persistence (trusted data). */
|
|
134
|
+
static from(pageId, pagePath, defaultType) {
|
|
135
|
+
return new PageSource(pageId, pagePath, defaultType);
|
|
136
|
+
}
|
|
137
|
+
equals(other) {
|
|
138
|
+
return this.pageId === other.pageId;
|
|
139
|
+
}
|
|
140
|
+
toString() {
|
|
141
|
+
return `${this.pagePath} (id=${this.pageId})`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=value-objects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-objects.js","sourceRoot":"","sources":["../../../src/domain/wiki-feedback/value-objects.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA6HlD,eAAO,MAAM,YAAY,EAAE,MAmmB1B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -89,7 +89,12 @@ import { createAzureSyncTools } from "./tools/azure-sync-tools.js";
|
|
|
89
89
|
import { createAzureSyncEventTools } from "./tools/azure-sync-event-tools.js";
|
|
90
90
|
import { createBootstrapTools } from "./tools/bootstrap-tools.js";
|
|
91
91
|
import { createConfigTools } from "./tools/config-tools.js";
|
|
92
|
+
import { createWikiFeedbackTools } from "./tools/wiki-feedback-tools.js";
|
|
92
93
|
import { BootstrapUseCases, HealthcheckUseCases, TerminalCommandsUseCases } from "./application/bootstrap/index.js";
|
|
94
|
+
import { SqliteWikiFeedbackRepository } from "./infrastructure/wiki-feedback/sqlite-feedback-repository.js";
|
|
95
|
+
import { AzureWikiClient } from "./infrastructure/wiki-feedback/azure-wiki-client.js";
|
|
96
|
+
import { WikiFeedbackUseCases } from "./application/wiki-feedback/use-cases.js";
|
|
97
|
+
import { WikiFeedbackPollService } from "./application/wiki-feedback/poll-service.js";
|
|
93
98
|
// Hooks
|
|
94
99
|
import { createCompactingHook } from "./hooks/context-compacting.js";
|
|
95
100
|
import { createShellEnvHook } from "./hooks/shell-env.js";
|
|
@@ -393,6 +398,46 @@ export const JarvisPlugin = async (input) => {
|
|
|
393
398
|
pollService.start();
|
|
394
399
|
}
|
|
395
400
|
const azureSyncEventTools = createAzureSyncEventTools({ syncEventUseCases, pollService });
|
|
401
|
+
// Wiki Feedback
|
|
402
|
+
const wikiFeedbackConfig = configService.getWikiFeedbackConfig();
|
|
403
|
+
const wikiFeedbackRepo = new SqliteWikiFeedbackRepository(db);
|
|
404
|
+
const wikiClient = new AzureWikiClient(azureSyncConfig.organization, azureSyncConfig.project, azureSyncConfig.authMethod);
|
|
405
|
+
const wikiFeedbackUseCases = new WikiFeedbackUseCases({
|
|
406
|
+
feedbackRepo: wikiFeedbackRepo,
|
|
407
|
+
wikiClient,
|
|
408
|
+
createCard: async (params) => {
|
|
409
|
+
const result = await cardUseCases.createCard({
|
|
410
|
+
title: params.title,
|
|
411
|
+
workspace: params.workspace,
|
|
412
|
+
...(params.priority !== undefined ? { priority: params.priority } : {}),
|
|
413
|
+
...(params.description !== undefined ? { description: params.description } : {}),
|
|
414
|
+
...(params.epicId !== undefined ? { epicId: params.epicId } : {}),
|
|
415
|
+
});
|
|
416
|
+
if (!result.success)
|
|
417
|
+
return { success: false, error: result.error };
|
|
418
|
+
return { success: true, data: { id: result.data.id } };
|
|
419
|
+
},
|
|
420
|
+
workspace: wsName,
|
|
421
|
+
wikiIdentifier: wikiFeedbackConfig.wikiIdentifier,
|
|
422
|
+
monitoredPages: wikiFeedbackConfig.monitoredPages,
|
|
423
|
+
autoReply: wikiFeedbackConfig.autoReply,
|
|
424
|
+
autoReplyPrefix: wikiFeedbackConfig.autoReplyPrefix,
|
|
425
|
+
});
|
|
426
|
+
let wikiPollService;
|
|
427
|
+
if (wikiFeedbackConfig.pollEnabled &&
|
|
428
|
+
wikiFeedbackConfig.wikiIdentifier &&
|
|
429
|
+
wikiFeedbackConfig.monitoredPages.length > 0) {
|
|
430
|
+
wikiPollService = new WikiFeedbackPollService({
|
|
431
|
+
useCases: wikiFeedbackUseCases,
|
|
432
|
+
onNewComments: (n) => { log.info(`[WikiPoll] ${n.summary}`, { newComments: n.newCommentsFound }); },
|
|
433
|
+
onError: (e) => { log.error(`[WikiPoll] ${e}`); },
|
|
434
|
+
}, wikiFeedbackConfig.pollIntervalSecs);
|
|
435
|
+
wikiPollService.start();
|
|
436
|
+
}
|
|
437
|
+
const wikiFeedbackTools = createWikiFeedbackTools({
|
|
438
|
+
useCases: wikiFeedbackUseCases,
|
|
439
|
+
...(wikiPollService !== undefined ? { pollService: wikiPollService } : {}),
|
|
440
|
+
});
|
|
396
441
|
// Bootstrap Tools (project initialization + healthcheck)
|
|
397
442
|
const bootstrapUseCases = new BootstrapUseCases();
|
|
398
443
|
const healthcheckUseCases = new HealthcheckUseCases({
|
|
@@ -570,6 +615,7 @@ export const JarvisPlugin = async (input) => {
|
|
|
570
615
|
...azureSyncEventTools,
|
|
571
616
|
...bootstrapTools,
|
|
572
617
|
...configTools,
|
|
618
|
+
...wikiFeedbackTools,
|
|
573
619
|
};
|
|
574
620
|
log.info("Plugin initialized", {
|
|
575
621
|
workspace: wsName,
|