@cat-factory/worker 0.6.0 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/dist/infrastructure/config/agents.d.ts.map +1 -1
- package/dist/infrastructure/config/agents.js +10 -0
- package/dist/infrastructure/config/agents.js.map +1 -1
- package/dist/infrastructure/container.d.ts.map +1 -1
- package/dist/infrastructure/container.js +36 -2
- package/dist/infrastructure/container.js.map +1 -1
- package/dist/infrastructure/repositories/D1BootstrapJobRepository.js +4 -4
- package/dist/infrastructure/repositories/D1ModelDefaultsRepository.js +1 -1
- package/dist/infrastructure/repositories/D1PipelineScheduleRepository.js +25 -25
- package/dist/infrastructure/repositories/D1RepoProjectionRepository.js +6 -6
- package/dist/infrastructure/repositories/D1ServiceRepository.js +1 -1
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.js +12 -6
- package/dist/infrastructure/repositories/D1TrackerSettingsRepository.js.map +1 -1
- package/dist/infrastructure/repositories/D1WorkspaceMountRepository.js +8 -8
- package/migrations/0005_issue_tracker_writeback.sql +11 -0
- package/package.json +18 -13
- package/dist/infrastructure/ai/CloudflareModelProvider.d.ts +0 -23
- package/dist/infrastructure/ai/CloudflareModelProvider.d.ts.map +0 -1
- package/dist/infrastructure/ai/CloudflareModelProvider.js +0 -62
- package/dist/infrastructure/ai/CloudflareModelProvider.js.map +0 -1
- package/dist/infrastructure/ai/ContainerRepoScanner.d.ts +0 -39
- package/dist/infrastructure/ai/ContainerRepoScanner.d.ts.map +0 -1
- package/dist/infrastructure/ai/ContainerRepoScanner.js +0 -115
- package/dist/infrastructure/ai/ContainerRepoScanner.js.map +0 -1
- package/dist/infrastructure/documents/ConfluenceProvider.d.ts +0 -29
- package/dist/infrastructure/documents/ConfluenceProvider.d.ts.map +0 -1
- package/dist/infrastructure/documents/ConfluenceProvider.js +0 -179
- package/dist/infrastructure/documents/ConfluenceProvider.js.map +0 -1
- package/dist/infrastructure/documents/GitHubDocsProvider.d.ts +0 -42
- package/dist/infrastructure/documents/GitHubDocsProvider.d.ts.map +0 -1
- package/dist/infrastructure/documents/GitHubDocsProvider.js +0 -85
- package/dist/infrastructure/documents/GitHubDocsProvider.js.map +0 -1
- package/dist/infrastructure/documents/NotionProvider.d.ts +0 -32
- package/dist/infrastructure/documents/NotionProvider.d.ts.map +0 -1
- package/dist/infrastructure/documents/NotionProvider.js +0 -220
- package/dist/infrastructure/documents/NotionProvider.js.map +0 -1
- package/dist/infrastructure/environments/HttpEnvironmentProvider.d.ts +0 -27
- package/dist/infrastructure/environments/HttpEnvironmentProvider.d.ts.map +0 -1
- package/dist/infrastructure/environments/HttpEnvironmentProvider.js +0 -314
- package/dist/infrastructure/environments/HttpEnvironmentProvider.js.map +0 -1
- package/dist/infrastructure/events/InAppNotificationChannel.d.ts +0 -19
- package/dist/infrastructure/events/InAppNotificationChannel.d.ts.map +0 -1
- package/dist/infrastructure/events/InAppNotificationChannel.js +0 -22
- package/dist/infrastructure/events/InAppNotificationChannel.js.map +0 -1
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.d.ts +0 -20
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.d.ts.map +0 -1
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.js +0 -64
- package/dist/infrastructure/repositories/D1RepoBlueprintRepository.js.map +0 -1
- package/dist/infrastructure/tasks/GitHubIssuesProvider.d.ts +0 -50
- package/dist/infrastructure/tasks/GitHubIssuesProvider.d.ts.map +0 -1
- package/dist/infrastructure/tasks/GitHubIssuesProvider.js +0 -91
- package/dist/infrastructure/tasks/GitHubIssuesProvider.js.map +0 -1
- package/dist/infrastructure/tasks/JiraProvider.d.ts +0 -29
- package/dist/infrastructure/tasks/JiraProvider.d.ts.map +0 -1
- package/dist/infrastructure/tasks/JiraProvider.js +0 -109
- package/dist/infrastructure/tasks/JiraProvider.js.map +0 -1
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { type TaskContent, type TaskCredentials, type TaskSearchResult, type TaskSourceProvider, type NormalizedTaskConnection } from '@cat-factory/kernel';
|
|
2
|
-
/** Carries the HTTP status so callers can surface a meaningful error. */
|
|
3
|
-
export declare class JiraApiError extends Error {
|
|
4
|
-
readonly status: number;
|
|
5
|
-
constructor(status: number, message: string);
|
|
6
|
-
}
|
|
7
|
-
export declare class JiraProvider implements TaskSourceProvider {
|
|
8
|
-
readonly kind: 'jira';
|
|
9
|
-
readonly descriptor: {
|
|
10
|
-
source: "github" | "jira";
|
|
11
|
-
label: string;
|
|
12
|
-
icon: string;
|
|
13
|
-
credentialFields: {
|
|
14
|
-
key: string;
|
|
15
|
-
label: string;
|
|
16
|
-
help?: string | undefined;
|
|
17
|
-
placeholder?: string | undefined;
|
|
18
|
-
secret?: boolean | undefined;
|
|
19
|
-
}[];
|
|
20
|
-
refLabel: string;
|
|
21
|
-
refPlaceholder: string;
|
|
22
|
-
searchable?: boolean | undefined;
|
|
23
|
-
};
|
|
24
|
-
normalizeConnection(input: TaskCredentials): NormalizedTaskConnection;
|
|
25
|
-
parseRef(input: string): string | null;
|
|
26
|
-
fetchTask(credentials: TaskCredentials, externalId: string): Promise<TaskContent>;
|
|
27
|
-
search(credentials: TaskCredentials, query: string): Promise<TaskSearchResult[]>;
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=JiraProvider.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"JiraProvider.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/tasks/JiraProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAA;AAa5B,yEAAyE;AACzE,qBAAa,YAAa,SAAQ,KAAK;IAEnC,QAAQ,CAAC,MAAM,EAAE,MAAM;IADzB,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAIhB;CACF;AAsBD,qBAAa,YAAa,YAAW,kBAAkB;IACrD,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAS;IAC/B,QAAQ,CAAC,UAAU;;;;;;;;;;;;;;MAAkB;IAErC,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,wBAAwB,CAepE;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAErC;IAEK,SAAS,CAAC,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA4CtF;IAEK,MAAM,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA6BrF;CACF"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { ValidationError, atlassianLogic, } from '@cat-factory/kernel';
|
|
2
|
-
import { JIRA_DESCRIPTOR, jiraLogic } from '@cat-factory/integrations';
|
|
3
|
-
// JiraProvider: the task-source provider for Jira Cloud. It authenticates with
|
|
4
|
-
// HTTP Basic (account email + API token, the same scheme as Confluence), fetches
|
|
5
|
-
// an issue via the REST v3 API, and maps it onto the structured TaskContent —
|
|
6
|
-
// converting the ADF description and comment bodies to the Markdown the generic
|
|
7
|
-
// excerpt/prompt logic consumes. All Jira-specific *pure* logic (ref parsing, ADF
|
|
8
|
-
// conversion) lives in `@cat-factory/integrations` so it is unit-testable; this class is
|
|
9
|
-
// the thin `fetch` shell around it. No SDK — fetch + `btoa` suffice.
|
|
10
|
-
const USER_AGENT = 'cat-factory';
|
|
11
|
-
/** Carries the HTTP status so callers can surface a meaningful error. */
|
|
12
|
-
export class JiraApiError extends Error {
|
|
13
|
-
status;
|
|
14
|
-
constructor(status, message) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.status = status;
|
|
17
|
-
this.name = 'JiraApiError';
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export class JiraProvider {
|
|
21
|
-
kind = 'jira';
|
|
22
|
-
descriptor = JIRA_DESCRIPTOR;
|
|
23
|
-
normalizeConnection(input) {
|
|
24
|
-
const baseUrlRaw = input.baseUrl?.trim();
|
|
25
|
-
const accountEmail = input.accountEmail?.trim();
|
|
26
|
-
const apiToken = input.apiToken?.trim();
|
|
27
|
-
if (!baseUrlRaw || !accountEmail || !apiToken) {
|
|
28
|
-
throw new ValidationError('Jira requires a site URL, account email and API token');
|
|
29
|
-
}
|
|
30
|
-
const baseUrl = atlassianLogic.normalizeAtlassianBaseUrl(baseUrlRaw);
|
|
31
|
-
// Guard against SSRF: the stored base URL is later fetched with the
|
|
32
|
-
// workspace's credentials, so it must be a public https host.
|
|
33
|
-
atlassianLogic.assertSafeAtlassianBaseUrl(baseUrl);
|
|
34
|
-
return {
|
|
35
|
-
credentials: { baseUrl, accountEmail, apiToken },
|
|
36
|
-
label: baseUrl,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
parseRef(input) {
|
|
40
|
-
return jiraLogic.parseJiraRef(input);
|
|
41
|
-
}
|
|
42
|
-
async fetchTask(credentials, externalId) {
|
|
43
|
-
const base = credentials.baseUrl.replace(/\/+$/, '');
|
|
44
|
-
const fields = 'summary,description,status,issuetype,assignee,priority,labels,comment';
|
|
45
|
-
const url = `${base}/rest/api/3/issue/${encodeURIComponent(externalId)}?fields=${fields}`;
|
|
46
|
-
const auth = btoa(`${credentials.accountEmail}:${credentials.apiToken}`);
|
|
47
|
-
const res = await fetch(url, {
|
|
48
|
-
method: 'GET',
|
|
49
|
-
headers: {
|
|
50
|
-
authorization: `Basic ${auth}`,
|
|
51
|
-
accept: 'application/json',
|
|
52
|
-
'user-agent': USER_AGENT,
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
if (!res.ok) {
|
|
56
|
-
const text = await res.text().catch(() => '');
|
|
57
|
-
throw new JiraApiError(res.status, `Jira GET ${url} → ${res.status}: ${text.slice(0, 300)}`);
|
|
58
|
-
}
|
|
59
|
-
const json = (await res.json().catch(() => null));
|
|
60
|
-
if (!json || !json.key || !json.fields) {
|
|
61
|
-
throw new JiraApiError(502, `Jira returned an unexpected body for issue ${externalId}`);
|
|
62
|
-
}
|
|
63
|
-
const f = json.fields;
|
|
64
|
-
const comments = (f.comment?.comments ?? []).map((c) => ({
|
|
65
|
-
author: c.author?.displayName ?? '',
|
|
66
|
-
createdAt: c.created ?? '',
|
|
67
|
-
body: jiraLogic.adfToMarkdown(c.body),
|
|
68
|
-
}));
|
|
69
|
-
return {
|
|
70
|
-
externalId: json.key,
|
|
71
|
-
url: `${base}/browse/${json.key}`,
|
|
72
|
-
title: f.summary ?? '(untitled)',
|
|
73
|
-
status: f.status?.name ?? '',
|
|
74
|
-
type: f.issuetype?.name ?? '',
|
|
75
|
-
assignee: f.assignee?.displayName ?? null,
|
|
76
|
-
priority: f.priority?.name ?? null,
|
|
77
|
-
labels: Array.isArray(f.labels) ? f.labels : [],
|
|
78
|
-
description: jiraLogic.adfToMarkdown(f.description),
|
|
79
|
-
comments,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
async search(credentials, query) {
|
|
83
|
-
const base = credentials.baseUrl.replace(/\/+$/, '');
|
|
84
|
-
// Re-validate the stored base before fetching with the workspace's credentials
|
|
85
|
-
// (defense-in-depth against a base that became unsafe since connect time).
|
|
86
|
-
atlassianLogic.assertSafeAtlassianBaseUrl(base);
|
|
87
|
-
const jql = encodeURIComponent(jiraLogic.buildJiraSearchJql(query));
|
|
88
|
-
// `/rest/api/3/search/jql` is the current enhanced-search endpoint; the legacy
|
|
89
|
-
// GET `/rest/api/3/search` was removed by Atlassian (May 2025). The `issues[]`
|
|
90
|
-
// response shape is unchanged, so `parseJiraSearchResults` still applies.
|
|
91
|
-
const url = `${base}/rest/api/3/search/jql?jql=${jql}&fields=summary,status&maxResults=20`;
|
|
92
|
-
const auth = btoa(`${credentials.accountEmail}:${credentials.apiToken}`);
|
|
93
|
-
const res = await fetch(url, {
|
|
94
|
-
method: 'GET',
|
|
95
|
-
headers: {
|
|
96
|
-
authorization: `Basic ${auth}`,
|
|
97
|
-
accept: 'application/json',
|
|
98
|
-
'user-agent': USER_AGENT,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
if (!res.ok) {
|
|
102
|
-
const text = await res.text().catch(() => '');
|
|
103
|
-
throw new JiraApiError(res.status, `Jira search ${url} → ${res.status}: ${text.slice(0, 300)}`);
|
|
104
|
-
}
|
|
105
|
-
const json = await res.json().catch(() => null);
|
|
106
|
-
return jiraLogic.parseJiraSearchResults(json, base);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=JiraProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"JiraProvider.js","sourceRoot":"","sources":["../../../src/infrastructure/tasks/JiraProvider.ts"],"names":[],"mappings":"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"}
|