@bpmsoftwaresolutions/ai-engine-client 1.0.0-beta.5 → 1.0.0-beta.6

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 CHANGED
@@ -174,6 +174,9 @@ const client = AIEngineClient.fromEnv();
174
174
  | `listProjects({ limit, includeInactive, processStatus, charterStatus })` | List projects. |
175
175
  | `getProject(projectId)` | Get project detail. |
176
176
  | `getProjectCharterReport(projectId)` | Get the SQL-backed charter report payload for a project. |
177
+ | `createProjectMarkdownDownload(projectId, { reportType, includeMarkdown })` | Create a markdown download descriptor for `charter` or `implementation_roadmap`. |
178
+ | `downloadProjectMarkdownReport(projectId, reportType)` | Download a rendered markdown report as text plus filename metadata. |
179
+ | `downloadProjectCharterReportMarkdown(projectId)` | Download the charter markdown report. |
177
180
  | `getProjectBundle(projectId)` | Get current status, charter report, and roadmap report in one payload. |
178
181
 
179
182
  ### Roadmaps
@@ -184,6 +187,7 @@ const client = AIEngineClient.fromEnv();
184
187
  | `getProjectRoadmapSummary(projectId)` | Roadmap summary. |
185
188
  | `getProjectRoadmapActiveItem(projectId)` | Current active roadmap item. |
186
189
  | `getProjectImplementationRoadmapReport(projectId)` | Get the SQL-backed implementation roadmap report payload. |
190
+ | `downloadProjectImplementationRoadmapReportMarkdown(projectId)` | Download the implementation roadmap markdown report. |
187
191
  | `ensureProjectRoadmapTaskSurface(projectId, { requestedBy, assignedTo, createAcceptanceSubtasks })` | Materialize the active roadmap item's parent task and acceptance subtasks. |
188
192
  | `listProjectOpenTasks(projectId)` | Open tasks for a project. |
189
193
  | `getProjectPerformanceMetrics(projectId, { workflowId, workflowRunId, sinceUtc })` | Performance metrics. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmsoftwaresolutions/ai-engine-client",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.6",
4
4
  "description": "Thin npm client for the AI Engine operator and retrieval APIs",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -20,6 +20,14 @@ async function readJson(response) {
20
20
  return { message: text };
21
21
  }
22
22
 
23
+ function parseContentDispositionFilename(headerValue) {
24
+ const value = String(headerValue || '');
25
+ const quotedMatch = value.match(/filename="([^"]+)"/i);
26
+ if (quotedMatch) return quotedMatch[1];
27
+ const plainMatch = value.match(/filename=([^;]+)/i);
28
+ return plainMatch ? plainMatch[1].trim() : null;
29
+ }
30
+
23
31
  export class AIEngineClient {
24
32
  constructor({ baseUrl, apiKey, actorId, fetchImpl, timeoutMs } = {}) {
25
33
  if (!baseUrl) throw new Error('baseUrl is required.');
@@ -482,6 +490,21 @@ export class AIEngineClient {
482
490
  return this._request(`/api/operator/projects/${projectId}/charter/report`);
483
491
  }
484
492
 
493
+ async createProjectMarkdownDownload(projectId, { reportType, includeMarkdown = false } = {}) {
494
+ return this._request(`/api/operator/projects/${projectId}/markdown-report-downloads`, {
495
+ method: 'POST',
496
+ body: { report_type: reportType, include_markdown: includeMarkdown },
497
+ });
498
+ }
499
+
500
+ async downloadProjectMarkdownReport(projectId, reportType) {
501
+ return this._requestText(`/api/operator/projects/${projectId}/markdown-reports/${reportType}/download`);
502
+ }
503
+
504
+ async downloadProjectCharterReportMarkdown(projectId) {
505
+ return this.downloadProjectMarkdownReport(projectId, 'charter');
506
+ }
507
+
485
508
  async getProjectBundle(projectId) {
486
509
  return this._request(`/api/operator/projects/${projectId}/bundle`);
487
510
  }
@@ -510,6 +533,10 @@ export class AIEngineClient {
510
533
  return this._request(`/api/operator/projects/${projectId}/implementation-roadmap/report`);
511
534
  }
512
535
 
536
+ async downloadProjectImplementationRoadmapReportMarkdown(projectId) {
537
+ return this.downloadProjectMarkdownReport(projectId, 'implementation_roadmap');
538
+ }
539
+
513
540
  async ensureProjectRoadmapTaskSurface(projectId, {
514
541
  requestedBy,
515
542
  assignedTo,
@@ -1110,6 +1137,44 @@ export class AIEngineClient {
1110
1137
  clearTimeout(timeoutHandle);
1111
1138
  }
1112
1139
  }
1140
+
1141
+ async _requestText(path, { method = 'GET', query, headers, body } = {}) {
1142
+ const url = appendQuery(`${this.baseUrl}${path}`, query);
1143
+ const controller = new AbortController();
1144
+ const timeoutHandle = setTimeout(() => controller.abort(), this.timeoutMs);
1145
+ try {
1146
+ const response = await this.fetchImpl(url, {
1147
+ method,
1148
+ headers: {
1149
+ accept: 'text/markdown, text/plain;q=0.9, application/json;q=0.8',
1150
+ 'content-type': body ? 'application/json' : undefined,
1151
+ 'x-actor-id': this.actorId,
1152
+ authorization: this.apiKey ? `Bearer ${this.apiKey}` : undefined,
1153
+ ...headers,
1154
+ },
1155
+ body: body ? JSON.stringify(body) : undefined,
1156
+ signal: controller.signal,
1157
+ });
1158
+ const contentType = response.headers.get('content-type') || '';
1159
+ const contentDisposition = response.headers.get('content-disposition') || '';
1160
+ if (!response.ok) {
1161
+ const payload = contentType.includes('application/json')
1162
+ ? await response.json()
1163
+ : { message: await response.text() };
1164
+ const error = new Error(payload?.message || payload?.error || `Request failed with status ${response.status}.`);
1165
+ error.status = response.status;
1166
+ error.payload = payload;
1167
+ throw error;
1168
+ }
1169
+ return {
1170
+ text: await response.text(),
1171
+ contentType,
1172
+ fileName: parseContentDispositionFilename(contentDisposition),
1173
+ };
1174
+ } finally {
1175
+ clearTimeout(timeoutHandle);
1176
+ }
1177
+ }
1113
1178
  }
1114
1179
 
1115
1180
  export function createAIEngineClient(options) {