@cat-factory/integrations 0.9.0 → 0.10.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/dist/modules/tasks/TaskConnectionService.d.ts +26 -3
- package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -1
- package/dist/modules/tasks/TaskConnectionService.js +65 -3
- package/dist/modules/tasks/TaskConnectionService.js.map +1 -1
- package/dist/modules/tasks/TaskImportService.d.ts +8 -0
- package/dist/modules/tasks/TaskImportService.d.ts.map +1 -1
- package/dist/modules/tasks/TaskImportService.js +21 -5
- package/dist/modules/tasks/TaskImportService.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,19 +1,42 @@
|
|
|
1
1
|
import type { Clock } from '@cat-factory/kernel';
|
|
2
2
|
import type { TaskConnectionRecord, TaskConnectionRepository } from '@cat-factory/kernel';
|
|
3
|
+
import type { TaskSourceSettingsRepository } from '@cat-factory/kernel';
|
|
4
|
+
import type { GitHubInstallationRepository } from '@cat-factory/kernel';
|
|
3
5
|
import type { TaskSourceRegistry } from '@cat-factory/kernel';
|
|
4
|
-
import type { TaskConnection,
|
|
6
|
+
import type { TaskConnection, TaskSourceKind, TaskSourceState } from '@cat-factory/kernel';
|
|
5
7
|
import type { WorkspaceRepository } from '@cat-factory/kernel';
|
|
6
8
|
export interface TaskConnectionServiceDependencies {
|
|
7
9
|
taskConnectionRepository: TaskConnectionRepository;
|
|
10
|
+
/** Per-workspace on/off toggle for each source (absent row ⇒ enabled). */
|
|
11
|
+
taskSourceSettingsRepository: TaskSourceSettingsRepository;
|
|
8
12
|
registry: TaskSourceRegistry;
|
|
9
13
|
workspaceRepository: WorkspaceRepository;
|
|
10
14
|
clock: Clock;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the workspace's installed GitHub App, used to decide whether the
|
|
17
|
+
* credentialless GitHub Issues source is available (it rides that App). Absent
|
|
18
|
+
* when the GitHub integration isn't wired, in which case GitHub Issues — if its
|
|
19
|
+
* provider is even registered — is reported unavailable.
|
|
20
|
+
*/
|
|
21
|
+
installations?: GitHubInstallationRepository;
|
|
11
22
|
}
|
|
12
23
|
export declare class TaskConnectionService {
|
|
13
24
|
private readonly deps;
|
|
14
25
|
constructor(deps: TaskConnectionServiceDependencies);
|
|
15
|
-
/**
|
|
16
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Every configured source with the workspace's live state for it (drives the
|
|
28
|
+
* settings + import UI): each source's descriptor plus whether it is available
|
|
29
|
+
* now and whether the workspace has it enabled. Availability is connection
|
|
30
|
+
* presence for credentialed sources, and the installed GitHub App for the
|
|
31
|
+
* credentialless GitHub Issues source.
|
|
32
|
+
*/
|
|
33
|
+
listSourceStates(workspaceId: string): Promise<TaskSourceState[]>;
|
|
34
|
+
/** Whether a source can be used right now (drives the import gate + the UI toggle's enablement). */
|
|
35
|
+
private isAvailable;
|
|
36
|
+
/** The workspace's toggle for a source (defaults to enabled when no row exists). */
|
|
37
|
+
isEnabled(workspaceId: string, source: TaskSourceKind): Promise<boolean>;
|
|
38
|
+
/** Enable or disable a source for the workspace (the per-workspace toggle). */
|
|
39
|
+
setEnabled(workspaceId: string, source: TaskSourceKind, enabled: boolean): Promise<void>;
|
|
17
40
|
/** Resolve a provider for a source or throw if that source isn't configured. */
|
|
18
41
|
private requireProvider;
|
|
19
42
|
/** Connect (or re-connect) a workspace to a task source. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskConnectionService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"TaskConnectionService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,KAAK,EAAsB,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAQ9D,MAAM,WAAW,iCAAiC;IAChD,wBAAwB,EAAE,wBAAwB,CAAA;IAClD,0EAA0E;IAC1E,4BAA4B,EAAE,4BAA4B,CAAA;IAC1D,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;IACZ;;;;;OAKG;IACH,aAAa,CAAC,EAAE,4BAA4B,CAAA;CAC7C;AA+BD,qBAAa,qBAAqB;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,iCAAiC,EAAI;IAExE;;;;;;OAMG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAatE;IAED,oGAAoG;YACtF,WAAW;IAWzB,oFAAoF;IAC9E,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;IAED,+EAA+E;IACzE,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7F;IAED,gFAAgF;IAChF,OAAO,CAAC,eAAe;IAMvB,4DAA4D;IACtD,OAAO,CACX,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,cAAc,CAAC,CAsBzB;IAED,iFAAiF;IAC3E,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAG/F;IAED,iEAAiE;IAC3D,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGpE;IAED,gFAAgF;IAC1E,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,oBAAoB,CAAC,CAM/B;IAED,qEAAqE;IAC/D,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;CACF"}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import { ConflictError, ValidationError } from '@cat-factory/kernel';
|
|
2
2
|
import { requireWorkspace } from '@cat-factory/kernel';
|
|
3
|
+
/**
|
|
4
|
+
* A credentialless provider carries no connection to make: there are no credential
|
|
5
|
+
* fields to fill in. Today the only such provider is GitHub Issues, which rides the
|
|
6
|
+
* workspace's installed GitHub App. `connect()` and the import credential resolver
|
|
7
|
+
* use this to skip the connection lookup; it does NOT by itself decide availability
|
|
8
|
+
* (see `isAvailable`, where the App-presence check is keyed on the GitHub source).
|
|
9
|
+
*/
|
|
10
|
+
function isCredentialless(provider) {
|
|
11
|
+
return provider.descriptor.credentialFields.length === 0;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The credentialless source whose availability is the installed GitHub App's
|
|
15
|
+
* presence. Keyed on the source kind (not just "is credentialless") so a future
|
|
16
|
+
* credentialless source with a different out-of-band auth path is forced to add its
|
|
17
|
+
* own availability branch rather than silently inheriting the App check.
|
|
18
|
+
*/
|
|
19
|
+
function ridesGitHubApp(provider) {
|
|
20
|
+
return provider.kind === 'github' && isCredentialless(provider);
|
|
21
|
+
}
|
|
3
22
|
function toConnection(record) {
|
|
4
23
|
return {
|
|
5
24
|
source: record.source,
|
|
@@ -12,9 +31,47 @@ export class TaskConnectionService {
|
|
|
12
31
|
constructor(deps) {
|
|
13
32
|
this.deps = deps;
|
|
14
33
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Every configured source with the workspace's live state for it (drives the
|
|
36
|
+
* settings + import UI): each source's descriptor plus whether it is available
|
|
37
|
+
* now and whether the workspace has it enabled. Availability is connection
|
|
38
|
+
* presence for credentialed sources, and the installed GitHub App for the
|
|
39
|
+
* credentialless GitHub Issues source.
|
|
40
|
+
*/
|
|
41
|
+
async listSourceStates(workspaceId) {
|
|
42
|
+
const settings = await this.deps.taskSourceSettingsRepository.getByWorkspace(workspaceId);
|
|
43
|
+
const enabledBySource = new Map(settings.map((s) => [s.source, s.enabled]));
|
|
44
|
+
const states = [];
|
|
45
|
+
for (const provider of this.deps.registry.list()) {
|
|
46
|
+
states.push({
|
|
47
|
+
...provider.descriptor,
|
|
48
|
+
available: await this.isAvailable(workspaceId, provider),
|
|
49
|
+
// No row ⇒ default enabled, so a source is offered as soon as it's available.
|
|
50
|
+
enabled: enabledBySource.get(provider.kind) ?? true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return states;
|
|
54
|
+
}
|
|
55
|
+
/** Whether a source can be used right now (drives the import gate + the UI toggle's enablement). */
|
|
56
|
+
async isAvailable(workspaceId, provider) {
|
|
57
|
+
if (ridesGitHubApp(provider)) {
|
|
58
|
+
// GitHub Issues rides the workspace's installed GitHub App: available once installed.
|
|
59
|
+
if (!this.deps.installations)
|
|
60
|
+
return false;
|
|
61
|
+
return (await this.deps.installations.getByWorkspace(workspaceId)) !== null;
|
|
62
|
+
}
|
|
63
|
+
return ((await this.deps.taskConnectionRepository.getByWorkspace(workspaceId, provider.kind)) !== null);
|
|
64
|
+
}
|
|
65
|
+
/** The workspace's toggle for a source (defaults to enabled when no row exists). */
|
|
66
|
+
async isEnabled(workspaceId, source) {
|
|
67
|
+
const row = await this.deps.taskSourceSettingsRepository.get(workspaceId, source);
|
|
68
|
+
return row?.enabled ?? true;
|
|
69
|
+
}
|
|
70
|
+
/** Enable or disable a source for the workspace (the per-workspace toggle). */
|
|
71
|
+
async setEnabled(workspaceId, source, enabled) {
|
|
72
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
73
|
+
this.requireProvider(source);
|
|
74
|
+
await this.deps.taskSourceSettingsRepository.upsert({ workspaceId, source, enabled });
|
|
18
75
|
}
|
|
19
76
|
/** Resolve a provider for a source or throw if that source isn't configured. */
|
|
20
77
|
requireProvider(source) {
|
|
@@ -27,6 +84,11 @@ export class TaskConnectionService {
|
|
|
27
84
|
async connect(workspaceId, source, credentials) {
|
|
28
85
|
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
29
86
|
const provider = this.requireProvider(source);
|
|
87
|
+
if (isCredentialless(provider)) {
|
|
88
|
+
// A credentialless source has no connection to make: it rides the workspace's
|
|
89
|
+
// installed GitHub App and is toggled via setEnabled, not connected.
|
|
90
|
+
throw new ValidationError(`The ${source} source has no connection to configure; it uses the workspace's installed GitHub App. Enable or disable it instead.`);
|
|
91
|
+
}
|
|
30
92
|
const normalized = provider.normalizeConnection(credentials);
|
|
31
93
|
const existing = await this.deps.taskConnectionRepository.getByWorkspace(workspaceId, source);
|
|
32
94
|
const record = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskConnectionService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TaskConnectionService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,14 @@ export declare class TaskImportService {
|
|
|
17
17
|
private readonly deps;
|
|
18
18
|
constructor(deps: TaskImportServiceDependencies);
|
|
19
19
|
private requireProvider;
|
|
20
|
+
/**
|
|
21
|
+
* Enforce the workspace's toggle and resolve the credentials to authenticate
|
|
22
|
+
* with. A disabled source is refused (it isn't offered, so neither import nor
|
|
23
|
+
* search may run against it). A credentialless source (GitHub Issues) needs no
|
|
24
|
+
* stored connection — it rides the workspace's installed GitHub App — so it
|
|
25
|
+
* authenticates with an empty bag; a credentialed source requires a connection.
|
|
26
|
+
*/
|
|
27
|
+
private resolveCredentials;
|
|
20
28
|
/** Fetch an issue (by key or URL) and upsert its projection; returns the issue. */
|
|
21
29
|
import(workspaceId: string, source: TaskSourceKind, ref: string): Promise<SourceTask>;
|
|
22
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskImportService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskImportService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"TaskImportService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskImportService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAuC,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAClG,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AASvE,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,cAAc,EAAE,cAAc,CAAA;IAC9B,iBAAiB,EAAE,qBAAqB,CAAA;IACxC,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;CACb;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAiB3D;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,6BAA6B,EAAI;IAEpE,OAAO,CAAC,eAAe;IAMvB;;;;;;OAMG;YACW,kBAAkB;IAahC,mFAAmF;IAC7E,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgC1F;IAED;;;;;OAKG;IACG,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAQ7B;IAED,+EAA+E;IACzE,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAG1D;IAED,6DAA6D;IACvD,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CAMrB;CACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ValidationError } from '@cat-factory/kernel';
|
|
1
|
+
import { ConflictError, ValidationError } from '@cat-factory/kernel';
|
|
2
2
|
import { requireWorkspace } from '@cat-factory/kernel';
|
|
3
3
|
import { buildTaskExcerpt } from './tasks.logic.js';
|
|
4
4
|
/** Project a stored task record onto the wire shape (drops the tombstone). */
|
|
@@ -31,6 +31,22 @@ export class TaskImportService {
|
|
|
31
31
|
throw new ValidationError(`Unknown or unconfigured task source '${source}'`);
|
|
32
32
|
return provider;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Enforce the workspace's toggle and resolve the credentials to authenticate
|
|
36
|
+
* with. A disabled source is refused (it isn't offered, so neither import nor
|
|
37
|
+
* search may run against it). A credentialless source (GitHub Issues) needs no
|
|
38
|
+
* stored connection — it rides the workspace's installed GitHub App — so it
|
|
39
|
+
* authenticates with an empty bag; a credentialed source requires a connection.
|
|
40
|
+
*/
|
|
41
|
+
async resolveCredentials(workspaceId, source, provider) {
|
|
42
|
+
if (!(await this.deps.connectionService.isEnabled(workspaceId, source))) {
|
|
43
|
+
throw new ConflictError(`The ${source} task source is disabled for this workspace`);
|
|
44
|
+
}
|
|
45
|
+
if (provider.descriptor.credentialFields.length === 0)
|
|
46
|
+
return {};
|
|
47
|
+
const connection = await this.deps.connectionService.requireConnection(workspaceId, source);
|
|
48
|
+
return connection.credentials;
|
|
49
|
+
}
|
|
34
50
|
/** Fetch an issue (by key or URL) and upsert its projection; returns the issue. */
|
|
35
51
|
async import(workspaceId, source, ref) {
|
|
36
52
|
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
@@ -39,8 +55,8 @@ export class TaskImportService {
|
|
|
39
55
|
if (!externalId) {
|
|
40
56
|
throw new ValidationError(`Could not resolve a ${source} issue key from '${ref}'`);
|
|
41
57
|
}
|
|
42
|
-
const
|
|
43
|
-
const content = await provider.fetchTask(
|
|
58
|
+
const credentials = await this.resolveCredentials(workspaceId, source, provider);
|
|
59
|
+
const content = await provider.fetchTask(credentials, externalId);
|
|
44
60
|
// Preserve any existing block link across a re-import.
|
|
45
61
|
const existing = await this.deps.taskRepository.get(workspaceId, source, content.externalId);
|
|
46
62
|
const record = {
|
|
@@ -76,8 +92,8 @@ export class TaskImportService {
|
|
|
76
92
|
if (!provider.search) {
|
|
77
93
|
throw new ValidationError(`The ${source} source does not support search`);
|
|
78
94
|
}
|
|
79
|
-
const
|
|
80
|
-
return provider.search(
|
|
95
|
+
const credentials = await this.resolveCredentials(workspaceId, source, provider);
|
|
96
|
+
return provider.search(credentials, query, workspaceId);
|
|
81
97
|
}
|
|
82
98
|
/** Every issue imported into the workspace, across sources, as wire shapes. */
|
|
83
99
|
async listTasks(workspaceId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskImportService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskImportService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"TaskImportService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskImportService.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/integrations",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "External-system integration domain logic for the Agent Architecture Board (GitHub, documents, tasks, environments, runners).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"ai": "^6.0.209",
|
|
28
|
-
"@cat-factory/contracts": "0.
|
|
29
|
-
"@cat-factory/kernel": "0.
|
|
28
|
+
"@cat-factory/contracts": "0.13.0",
|
|
29
|
+
"@cat-factory/kernel": "0.13.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"typescript": "7.0.1-rc",
|