@bradygaster/squad-sdk 0.8.23 → 0.8.25
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/config/init.d.ts +3 -3
- package/dist/config/init.d.ts.map +1 -1
- package/dist/config/init.js +72 -16
- package/dist/config/init.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/platform/azure-devops.d.ts +68 -0
- package/dist/platform/azure-devops.d.ts.map +1 -0
- package/dist/platform/azure-devops.js +271 -0
- package/dist/platform/azure-devops.js.map +1 -0
- package/dist/platform/comms-ado-discussions.d.ts +31 -0
- package/dist/platform/comms-ado-discussions.d.ts.map +1 -0
- package/dist/platform/comms-ado-discussions.js +82 -0
- package/dist/platform/comms-ado-discussions.js.map +1 -0
- package/dist/platform/comms-file-log.d.ts +31 -0
- package/dist/platform/comms-file-log.d.ts.map +1 -0
- package/dist/platform/comms-file-log.js +71 -0
- package/dist/platform/comms-file-log.js.map +1 -0
- package/dist/platform/comms-github-discussions.d.ts +30 -0
- package/dist/platform/comms-github-discussions.d.ts.map +1 -0
- package/dist/platform/comms-github-discussions.js +68 -0
- package/dist/platform/comms-github-discussions.js.map +1 -0
- package/dist/platform/comms.d.ts +19 -0
- package/dist/platform/comms.d.ts.map +1 -0
- package/dist/platform/comms.js +109 -0
- package/dist/platform/comms.js.map +1 -0
- package/dist/platform/detect.d.ts +56 -0
- package/dist/platform/detect.d.ts.map +1 -0
- package/dist/platform/detect.js +109 -0
- package/dist/platform/detect.js.map +1 -0
- package/dist/platform/github.d.ts +43 -0
- package/dist/platform/github.d.ts.map +1 -0
- package/dist/platform/github.js +192 -0
- package/dist/platform/github.js.map +1 -0
- package/dist/platform/index.d.ts +25 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +61 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/planner.d.ts +57 -0
- package/dist/platform/planner.d.ts.map +1 -0
- package/dist/platform/planner.js +185 -0
- package/dist/platform/planner.js.map +1 -0
- package/dist/platform/ralph-commands.d.ts +25 -0
- package/dist/platform/ralph-commands.d.ts.map +1 -0
- package/dist/platform/ralph-commands.js +60 -0
- package/dist/platform/ralph-commands.js.map +1 -0
- package/dist/platform/types.d.ts +125 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +8 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/streams/filter.d.ts +18 -14
- package/dist/streams/filter.d.ts.map +1 -1
- package/dist/streams/filter.js +13 -11
- package/dist/streams/filter.js.map +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/streams/resolver.d.ts +27 -21
- package/dist/streams/resolver.d.ts.map +1 -1
- package/dist/streams/resolver.js +41 -35
- package/dist/streams/resolver.js.map +1 -1
- package/dist/streams/types.d.ts +29 -23
- package/dist/streams/types.d.ts.map +1 -1
- package/dist/streams/types.js +2 -2
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communication adapter factory — creates the right adapter based on config.
|
|
3
|
+
*
|
|
4
|
+
* Reads `.squad/config.json` for the `communications` section.
|
|
5
|
+
* Falls back to FileLog (always available) if nothing is configured.
|
|
6
|
+
*
|
|
7
|
+
* @module platform/comms
|
|
8
|
+
*/
|
|
9
|
+
import type { CommunicationAdapter } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Create a communication adapter based on config or auto-detection.
|
|
12
|
+
*
|
|
13
|
+
* Priority:
|
|
14
|
+
* 1. Explicit config in `.squad/config.json` → `communications.channel`
|
|
15
|
+
* 2. Auto-detect from platform: GitHub → GitHubDiscussions, ADO → ADOWorkItemDiscussions
|
|
16
|
+
* 3. Fallback: FileLog (always works)
|
|
17
|
+
*/
|
|
18
|
+
export declare function createCommunicationAdapter(repoRoot: string): CommunicationAdapter;
|
|
19
|
+
//# sourceMappingURL=comms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comms.d.ts","sourceRoot":"","sources":["../../src/platform/comms.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAA6C,MAAM,YAAY,CAAC;AAsBlG;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAyCjF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Communication adapter factory — creates the right adapter based on config.
|
|
3
|
+
*
|
|
4
|
+
* Reads `.squad/config.json` for the `communications` section.
|
|
5
|
+
* Falls back to FileLog (always available) if nothing is configured.
|
|
6
|
+
*
|
|
7
|
+
* @module platform/comms
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { FileLogCommunicationAdapter } from './comms-file-log.js';
|
|
12
|
+
import { GitHubDiscussionsCommunicationAdapter } from './comms-github-discussions.js';
|
|
13
|
+
import { ADODiscussionCommunicationAdapter } from './comms-ado-discussions.js';
|
|
14
|
+
import { detectPlatform, getRemoteUrl, parseGitHubRemote, parseAzureDevOpsRemote } from './detect.js';
|
|
15
|
+
/**
|
|
16
|
+
* Read communication config from `.squad/config.json`.
|
|
17
|
+
*/
|
|
18
|
+
function readCommsConfig(repoRoot) {
|
|
19
|
+
const configPath = join(repoRoot, '.squad', 'config.json');
|
|
20
|
+
if (!existsSync(configPath))
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
24
|
+
const parsed = JSON.parse(raw);
|
|
25
|
+
if (parsed.communications && typeof parsed.communications === 'object') {
|
|
26
|
+
return parsed.communications;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch { /* ignore */ }
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a communication adapter based on config or auto-detection.
|
|
34
|
+
*
|
|
35
|
+
* Priority:
|
|
36
|
+
* 1. Explicit config in `.squad/config.json` → `communications.channel`
|
|
37
|
+
* 2. Auto-detect from platform: GitHub → GitHubDiscussions, ADO → ADOWorkItemDiscussions
|
|
38
|
+
* 3. Fallback: FileLog (always works)
|
|
39
|
+
*/
|
|
40
|
+
export function createCommunicationAdapter(repoRoot) {
|
|
41
|
+
const config = readCommsConfig(repoRoot);
|
|
42
|
+
// Explicit config wins
|
|
43
|
+
if (config?.channel) {
|
|
44
|
+
return createAdapterByChannel(config.channel, repoRoot);
|
|
45
|
+
}
|
|
46
|
+
// Auto-detect from platform
|
|
47
|
+
const platform = detectPlatform(repoRoot);
|
|
48
|
+
const remoteUrl = getRemoteUrl(repoRoot);
|
|
49
|
+
if (platform === 'github' && remoteUrl) {
|
|
50
|
+
const info = parseGitHubRemote(remoteUrl);
|
|
51
|
+
if (info) {
|
|
52
|
+
return new GitHubDiscussionsCommunicationAdapter(info.owner, info.repo);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (platform === 'azure-devops' && remoteUrl) {
|
|
56
|
+
const info = parseAzureDevOpsRemote(remoteUrl);
|
|
57
|
+
if (info) {
|
|
58
|
+
// Read ADO config for org/project override
|
|
59
|
+
const configPath = join(repoRoot, '.squad', 'config.json');
|
|
60
|
+
let adoOrg = info.org;
|
|
61
|
+
let adoProject = info.project;
|
|
62
|
+
if (existsSync(configPath)) {
|
|
63
|
+
try {
|
|
64
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
65
|
+
const parsed = JSON.parse(raw);
|
|
66
|
+
const ado = parsed.ado;
|
|
67
|
+
if (ado?.org && typeof ado.org === 'string')
|
|
68
|
+
adoOrg = ado.org;
|
|
69
|
+
if (ado?.project && typeof ado.project === 'string')
|
|
70
|
+
adoProject = ado.project;
|
|
71
|
+
}
|
|
72
|
+
catch { /* ignore */ }
|
|
73
|
+
}
|
|
74
|
+
return new ADODiscussionCommunicationAdapter(adoOrg, adoProject);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Fallback: file-based logging (always available)
|
|
78
|
+
return new FileLogCommunicationAdapter(repoRoot);
|
|
79
|
+
}
|
|
80
|
+
function createAdapterByChannel(channel, repoRoot) {
|
|
81
|
+
const remoteUrl = getRemoteUrl(repoRoot);
|
|
82
|
+
switch (channel) {
|
|
83
|
+
case 'github-discussions': {
|
|
84
|
+
if (!remoteUrl)
|
|
85
|
+
throw new Error('No git remote — cannot create GitHub Discussions adapter');
|
|
86
|
+
const info = parseGitHubRemote(remoteUrl);
|
|
87
|
+
if (!info)
|
|
88
|
+
throw new Error(`Cannot parse GitHub remote: ${remoteUrl}`);
|
|
89
|
+
return new GitHubDiscussionsCommunicationAdapter(info.owner, info.repo);
|
|
90
|
+
}
|
|
91
|
+
case 'ado-work-items': {
|
|
92
|
+
if (!remoteUrl)
|
|
93
|
+
throw new Error('No git remote — cannot create ADO Discussions adapter');
|
|
94
|
+
const info = parseAzureDevOpsRemote(remoteUrl);
|
|
95
|
+
if (!info)
|
|
96
|
+
throw new Error(`Cannot parse ADO remote: ${remoteUrl}`);
|
|
97
|
+
return new ADODiscussionCommunicationAdapter(info.org, info.project);
|
|
98
|
+
}
|
|
99
|
+
case 'teams-webhook':
|
|
100
|
+
// Teams webhook adapter would go here — for now fall back to file log
|
|
101
|
+
console.warn('Teams webhook adapter not yet implemented — using file log fallback');
|
|
102
|
+
return new FileLogCommunicationAdapter(repoRoot);
|
|
103
|
+
case 'file-log':
|
|
104
|
+
return new FileLogCommunicationAdapter(repoRoot);
|
|
105
|
+
default:
|
|
106
|
+
return new FileLogCommunicationAdapter(repoRoot);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=comms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comms.js","sourceRoot":"","sources":["../../src/platform/comms.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detect platform from git remote URL.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/detect
|
|
5
|
+
*/
|
|
6
|
+
import type { PlatformType, WorkItemSource } from './types.js';
|
|
7
|
+
/** Parsed GitHub remote info */
|
|
8
|
+
export interface GitHubRemoteInfo {
|
|
9
|
+
owner: string;
|
|
10
|
+
repo: string;
|
|
11
|
+
}
|
|
12
|
+
/** Parsed Azure DevOps remote info */
|
|
13
|
+
export interface AzureDevOpsRemoteInfo {
|
|
14
|
+
org: string;
|
|
15
|
+
project: string;
|
|
16
|
+
repo: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a GitHub remote URL into owner/repo.
|
|
20
|
+
* Supports HTTPS and SSH formats:
|
|
21
|
+
* https://github.com/owner/repo.git
|
|
22
|
+
* git@github.com:owner/repo.git
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseGitHubRemote(url: string): GitHubRemoteInfo | null;
|
|
25
|
+
/**
|
|
26
|
+
* Parse an Azure DevOps remote URL into org/project/repo.
|
|
27
|
+
* Supports multiple formats:
|
|
28
|
+
* https://dev.azure.com/org/project/_git/repo
|
|
29
|
+
* https://org@dev.azure.com/org/project/_git/repo
|
|
30
|
+
* git@ssh.dev.azure.com:v3/org/project/repo
|
|
31
|
+
* https://org.visualstudio.com/project/_git/repo
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseAzureDevOpsRemote(url: string): AzureDevOpsRemoteInfo | null;
|
|
34
|
+
/**
|
|
35
|
+
* Detect platform type from git remote URL string.
|
|
36
|
+
* Returns 'github' for github.com remotes, 'azure-devops' for ADO remotes.
|
|
37
|
+
* Defaults to 'github' if unrecognized.
|
|
38
|
+
*/
|
|
39
|
+
export declare function detectPlatformFromUrl(url: string): PlatformType;
|
|
40
|
+
/**
|
|
41
|
+
* Detect platform from a repository root by reading the git remote.
|
|
42
|
+
* Reads 'origin' remote URL and determines whether it's GitHub or Azure DevOps.
|
|
43
|
+
* Defaults to 'github' if detection fails.
|
|
44
|
+
*/
|
|
45
|
+
export declare function detectPlatform(repoRoot: string): PlatformType;
|
|
46
|
+
/**
|
|
47
|
+
* Detect work-item source for hybrid setups.
|
|
48
|
+
* When a squad config specifies `workItems: 'planner'`, work items come from
|
|
49
|
+
* Planner even though the repo is on GitHub or Azure DevOps.
|
|
50
|
+
*/
|
|
51
|
+
export declare function detectWorkItemSource(repoRoot: string, configWorkItems?: string): WorkItemSource;
|
|
52
|
+
/**
|
|
53
|
+
* Get the origin remote URL for a repo, or null if unavailable.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getRemoteUrl(repoRoot: string): string | null;
|
|
56
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,sCAAsC;AACtC,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CActE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CA2BhF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAY7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB,cAAc,CAGhB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU5D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detect platform from git remote URL.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/detect
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'node:child_process';
|
|
7
|
+
/**
|
|
8
|
+
* Parse a GitHub remote URL into owner/repo.
|
|
9
|
+
* Supports HTTPS and SSH formats:
|
|
10
|
+
* https://github.com/owner/repo.git
|
|
11
|
+
* git@github.com:owner/repo.git
|
|
12
|
+
*/
|
|
13
|
+
export function parseGitHubRemote(url) {
|
|
14
|
+
// HTTPS: https://github.com/owner/repo.git
|
|
15
|
+
const httpsMatch = url.match(/github\.com\/([^/]+)\/([^/.]+?)(?:\.git)?$/i);
|
|
16
|
+
if (httpsMatch) {
|
|
17
|
+
return { owner: httpsMatch[1], repo: httpsMatch[2] };
|
|
18
|
+
}
|
|
19
|
+
// SSH: git@github.com:owner/repo.git
|
|
20
|
+
const sshMatch = url.match(/github\.com:([^/]+)\/([^/.]+?)(?:\.git)?$/i);
|
|
21
|
+
if (sshMatch) {
|
|
22
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse an Azure DevOps remote URL into org/project/repo.
|
|
28
|
+
* Supports multiple formats:
|
|
29
|
+
* https://dev.azure.com/org/project/_git/repo
|
|
30
|
+
* https://org@dev.azure.com/org/project/_git/repo
|
|
31
|
+
* git@ssh.dev.azure.com:v3/org/project/repo
|
|
32
|
+
* https://org.visualstudio.com/project/_git/repo
|
|
33
|
+
*/
|
|
34
|
+
export function parseAzureDevOpsRemote(url) {
|
|
35
|
+
// HTTPS dev.azure.com: https://dev.azure.com/org/project/_git/repo
|
|
36
|
+
// Also handles: https://org@dev.azure.com/org/project/_git/repo
|
|
37
|
+
const devAzureHttps = url.match(/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/.]+?)(?:\.git)?$/i);
|
|
38
|
+
if (devAzureHttps) {
|
|
39
|
+
return { org: devAzureHttps[1], project: devAzureHttps[2], repo: devAzureHttps[3] };
|
|
40
|
+
}
|
|
41
|
+
// SSH dev.azure.com: git@ssh.dev.azure.com:v3/org/project/repo
|
|
42
|
+
const devAzureSsh = url.match(/ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\/([^/.]+?)(?:\.git)?$/i);
|
|
43
|
+
if (devAzureSsh) {
|
|
44
|
+
return { org: devAzureSsh[1], project: devAzureSsh[2], repo: devAzureSsh[3] };
|
|
45
|
+
}
|
|
46
|
+
// Legacy visualstudio.com: https://org.visualstudio.com/project/_git/repo
|
|
47
|
+
const vsMatch = url.match(/([^/.]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/.]+?)(?:\.git)?$/i);
|
|
48
|
+
if (vsMatch) {
|
|
49
|
+
return { org: vsMatch[1], project: vsMatch[2], repo: vsMatch[3] };
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Detect platform type from git remote URL string.
|
|
55
|
+
* Returns 'github' for github.com remotes, 'azure-devops' for ADO remotes.
|
|
56
|
+
* Defaults to 'github' if unrecognized.
|
|
57
|
+
*/
|
|
58
|
+
export function detectPlatformFromUrl(url) {
|
|
59
|
+
if (/github\.com/i.test(url))
|
|
60
|
+
return 'github';
|
|
61
|
+
if (/dev\.azure\.com/i.test(url) || /\.visualstudio\.com/i.test(url) || /ssh\.dev\.azure\.com/i.test(url)) {
|
|
62
|
+
return 'azure-devops';
|
|
63
|
+
}
|
|
64
|
+
return 'github';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Detect platform from a repository root by reading the git remote.
|
|
68
|
+
* Reads 'origin' remote URL and determines whether it's GitHub or Azure DevOps.
|
|
69
|
+
* Defaults to 'github' if detection fails.
|
|
70
|
+
*/
|
|
71
|
+
export function detectPlatform(repoRoot) {
|
|
72
|
+
try {
|
|
73
|
+
const remoteUrl = execSync('git remote get-url origin', {
|
|
74
|
+
cwd: repoRoot,
|
|
75
|
+
encoding: 'utf-8',
|
|
76
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
77
|
+
}).trim();
|
|
78
|
+
return detectPlatformFromUrl(remoteUrl);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return 'github';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Detect work-item source for hybrid setups.
|
|
86
|
+
* When a squad config specifies `workItems: 'planner'`, work items come from
|
|
87
|
+
* Planner even though the repo is on GitHub or Azure DevOps.
|
|
88
|
+
*/
|
|
89
|
+
export function detectWorkItemSource(repoRoot, configWorkItems) {
|
|
90
|
+
if (configWorkItems === 'planner')
|
|
91
|
+
return 'planner';
|
|
92
|
+
return detectPlatform(repoRoot);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the origin remote URL for a repo, or null if unavailable.
|
|
96
|
+
*/
|
|
97
|
+
export function getRemoteUrl(repoRoot) {
|
|
98
|
+
try {
|
|
99
|
+
return execSync('git remote get-url origin', {
|
|
100
|
+
cwd: repoRoot,
|
|
101
|
+
encoding: 'utf-8',
|
|
102
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
103
|
+
}).trim();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub platform adapter — wraps gh CLI for issue/PR/branch operations.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/github
|
|
5
|
+
*/
|
|
6
|
+
import type { PlatformAdapter, PlatformType, WorkItem, PullRequest } from './types.js';
|
|
7
|
+
export declare class GitHubAdapter implements PlatformAdapter {
|
|
8
|
+
private readonly owner;
|
|
9
|
+
private readonly repo;
|
|
10
|
+
readonly type: PlatformType;
|
|
11
|
+
constructor(owner: string, repo: string);
|
|
12
|
+
private get repoFlag();
|
|
13
|
+
private gh;
|
|
14
|
+
listWorkItems(options: {
|
|
15
|
+
tags?: string[];
|
|
16
|
+
state?: string;
|
|
17
|
+
limit?: number;
|
|
18
|
+
}): Promise<WorkItem[]>;
|
|
19
|
+
getWorkItem(id: number): Promise<WorkItem>;
|
|
20
|
+
createWorkItem(options: {
|
|
21
|
+
title: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
tags?: string[];
|
|
24
|
+
assignedTo?: string;
|
|
25
|
+
type?: string;
|
|
26
|
+
}): Promise<WorkItem>;
|
|
27
|
+
addTag(workItemId: number, tag: string): Promise<void>;
|
|
28
|
+
removeTag(workItemId: number, tag: string): Promise<void>;
|
|
29
|
+
addComment(workItemId: number, comment: string): Promise<void>;
|
|
30
|
+
listPullRequests(options: {
|
|
31
|
+
status?: string;
|
|
32
|
+
limit?: number;
|
|
33
|
+
}): Promise<PullRequest[]>;
|
|
34
|
+
createPullRequest(options: {
|
|
35
|
+
title: string;
|
|
36
|
+
sourceBranch: string;
|
|
37
|
+
targetBranch: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
}): Promise<PullRequest>;
|
|
40
|
+
mergePullRequest(id: number): Promise<void>;
|
|
41
|
+
createBranch(name: string, fromBranch?: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/platform/github.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAavF,qBAAa,aAAc,YAAW,eAAe;IAIjD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAY;gBAGpB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM;IAG/B,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,EAAE;IAIJ,aAAa,CAAC,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA8BhG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAwB1C,cAAc,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAoCxI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,gBAAgB,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA8BtF,iBAAiB,CAAC,OAAO,EAAE;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsClB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMrE"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub platform adapter — wraps gh CLI for issue/PR/branch operations.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/github
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
const EXEC_OPTS = { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] };
|
|
8
|
+
/** Safely parse JSON output, including raw text in error messages */
|
|
9
|
+
function parseJson(raw) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(raw);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
throw new Error(`Failed to parse JSON from CLI output: ${err.message}\nRaw output: ${raw}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class GitHubAdapter {
|
|
18
|
+
owner;
|
|
19
|
+
repo;
|
|
20
|
+
type = 'github';
|
|
21
|
+
constructor(owner, repo) {
|
|
22
|
+
this.owner = owner;
|
|
23
|
+
this.repo = repo;
|
|
24
|
+
}
|
|
25
|
+
get repoFlag() {
|
|
26
|
+
return `${this.owner}/${this.repo}`;
|
|
27
|
+
}
|
|
28
|
+
gh(args) {
|
|
29
|
+
return execFileSync('gh', args, EXEC_OPTS).trim();
|
|
30
|
+
}
|
|
31
|
+
async listWorkItems(options) {
|
|
32
|
+
const args = ['issue', 'list', '--repo', this.repoFlag, '--json', 'number,title,state,labels,assignees,url'];
|
|
33
|
+
if (options.state)
|
|
34
|
+
args.push('--state', options.state);
|
|
35
|
+
if (options.limit)
|
|
36
|
+
args.push('--limit', String(options.limit));
|
|
37
|
+
if (options.tags?.length) {
|
|
38
|
+
for (const tag of options.tags) {
|
|
39
|
+
args.push('--label', tag);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const output = this.gh(args);
|
|
43
|
+
const issues = parseJson(output);
|
|
44
|
+
return issues.map((issue) => ({
|
|
45
|
+
id: issue.number,
|
|
46
|
+
title: issue.title,
|
|
47
|
+
state: issue.state.toLowerCase(),
|
|
48
|
+
tags: issue.labels.map((l) => l.name),
|
|
49
|
+
assignedTo: issue.assignees[0]?.login,
|
|
50
|
+
url: issue.url,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
async getWorkItem(id) {
|
|
54
|
+
const output = this.gh([
|
|
55
|
+
'issue', 'view', String(id), '--repo', this.repoFlag,
|
|
56
|
+
'--json', 'number,title,state,labels,assignees,url',
|
|
57
|
+
]);
|
|
58
|
+
const issue = parseJson(output);
|
|
59
|
+
return {
|
|
60
|
+
id: issue.number,
|
|
61
|
+
title: issue.title,
|
|
62
|
+
state: issue.state.toLowerCase(),
|
|
63
|
+
tags: issue.labels.map((l) => l.name),
|
|
64
|
+
assignedTo: issue.assignees[0]?.login,
|
|
65
|
+
url: issue.url,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async createWorkItem(options) {
|
|
69
|
+
const args = [
|
|
70
|
+
'issue', 'create',
|
|
71
|
+
'--repo', this.repoFlag,
|
|
72
|
+
'--title', options.title,
|
|
73
|
+
];
|
|
74
|
+
if (options.description) {
|
|
75
|
+
args.push('--body', options.description);
|
|
76
|
+
}
|
|
77
|
+
if (options.tags?.length) {
|
|
78
|
+
for (const tag of options.tags) {
|
|
79
|
+
args.push('--label', tag);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (options.assignedTo) {
|
|
83
|
+
args.push('--assignee', options.assignedTo);
|
|
84
|
+
}
|
|
85
|
+
// gh issue create doesn't support --json; it prints the issue URL to stdout
|
|
86
|
+
const url = this.gh(args);
|
|
87
|
+
const match = url.match(/\/issues\/(\d+)\s*$/);
|
|
88
|
+
if (!match) {
|
|
89
|
+
throw new Error(`Could not parse issue number from gh output: ${url}`);
|
|
90
|
+
}
|
|
91
|
+
const issueNumber = parseInt(match[1], 10);
|
|
92
|
+
return {
|
|
93
|
+
id: issueNumber,
|
|
94
|
+
title: options.title,
|
|
95
|
+
state: 'open',
|
|
96
|
+
tags: options.tags ?? [],
|
|
97
|
+
assignedTo: options.assignedTo,
|
|
98
|
+
url: url.trim(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async addTag(workItemId, tag) {
|
|
102
|
+
this.gh(['issue', 'edit', String(workItemId), '--repo', this.repoFlag, '--add-label', tag]);
|
|
103
|
+
}
|
|
104
|
+
async removeTag(workItemId, tag) {
|
|
105
|
+
this.gh(['issue', 'edit', String(workItemId), '--repo', this.repoFlag, '--remove-label', tag]);
|
|
106
|
+
}
|
|
107
|
+
async addComment(workItemId, comment) {
|
|
108
|
+
this.gh(['issue', 'comment', String(workItemId), '--repo', this.repoFlag, '--body', comment]);
|
|
109
|
+
}
|
|
110
|
+
async listPullRequests(options) {
|
|
111
|
+
const args = ['pr', 'list', '--repo', this.repoFlag, '--json', 'number,title,headRefName,baseRefName,state,isDraft,reviewDecision,author,url'];
|
|
112
|
+
if (options.status)
|
|
113
|
+
args.push('--state', mapStatusToGhState(options.status));
|
|
114
|
+
if (options.limit)
|
|
115
|
+
args.push('--limit', String(options.limit));
|
|
116
|
+
const output = this.gh(args);
|
|
117
|
+
const prs = parseJson(output);
|
|
118
|
+
return prs.map((pr) => ({
|
|
119
|
+
id: pr.number,
|
|
120
|
+
title: pr.title,
|
|
121
|
+
sourceBranch: pr.headRefName,
|
|
122
|
+
targetBranch: pr.baseRefName,
|
|
123
|
+
status: mapGitHubPrStatus(pr.state, pr.isDraft),
|
|
124
|
+
reviewStatus: mapGitHubReviewStatus(pr.reviewDecision),
|
|
125
|
+
author: pr.author.login,
|
|
126
|
+
url: pr.url,
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
async createPullRequest(options) {
|
|
130
|
+
const args = [
|
|
131
|
+
'pr', 'create',
|
|
132
|
+
'--repo', this.repoFlag,
|
|
133
|
+
'--head', options.sourceBranch,
|
|
134
|
+
'--base', options.targetBranch,
|
|
135
|
+
'--title', options.title,
|
|
136
|
+
'--json', 'number,title,headRefName,baseRefName,state,isDraft,reviewDecision,author,url',
|
|
137
|
+
];
|
|
138
|
+
if (options.description) {
|
|
139
|
+
args.push('--body', options.description);
|
|
140
|
+
}
|
|
141
|
+
const output = this.gh(args);
|
|
142
|
+
const pr = parseJson(output);
|
|
143
|
+
return {
|
|
144
|
+
id: pr.number,
|
|
145
|
+
title: pr.title,
|
|
146
|
+
sourceBranch: pr.headRefName,
|
|
147
|
+
targetBranch: pr.baseRefName,
|
|
148
|
+
status: mapGitHubPrStatus(pr.state, pr.isDraft),
|
|
149
|
+
reviewStatus: mapGitHubReviewStatus(pr.reviewDecision),
|
|
150
|
+
author: pr.author.login,
|
|
151
|
+
url: pr.url,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async mergePullRequest(id) {
|
|
155
|
+
this.gh(['pr', 'merge', String(id), '--repo', this.repoFlag, '--merge']);
|
|
156
|
+
}
|
|
157
|
+
async createBranch(name, fromBranch) {
|
|
158
|
+
const base = fromBranch ?? 'main';
|
|
159
|
+
execFileSync('git', ['checkout', base], EXEC_OPTS);
|
|
160
|
+
execFileSync('git', ['pull'], EXEC_OPTS);
|
|
161
|
+
execFileSync('git', ['checkout', '-b', name], EXEC_OPTS);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Map normalized status (active/completed/abandoned/draft) to gh CLI --state values */
|
|
165
|
+
function mapStatusToGhState(status) {
|
|
166
|
+
switch (status.toLowerCase()) {
|
|
167
|
+
case 'active': return 'open';
|
|
168
|
+
case 'completed': return 'merged';
|
|
169
|
+
case 'abandoned': return 'closed';
|
|
170
|
+
case 'draft': return 'open';
|
|
171
|
+
default: return status;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function mapGitHubPrStatus(state, isDraft) {
|
|
175
|
+
if (isDraft)
|
|
176
|
+
return 'draft';
|
|
177
|
+
switch (state.toUpperCase()) {
|
|
178
|
+
case 'OPEN': return 'active';
|
|
179
|
+
case 'CLOSED': return 'abandoned';
|
|
180
|
+
case 'MERGED': return 'completed';
|
|
181
|
+
default: return 'active';
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function mapGitHubReviewStatus(decision) {
|
|
185
|
+
switch (decision?.toUpperCase()) {
|
|
186
|
+
case 'APPROVED': return 'approved';
|
|
187
|
+
case 'CHANGES_REQUESTED': return 'changes-requested';
|
|
188
|
+
case 'REVIEW_REQUIRED': return 'pending';
|
|
189
|
+
default: return undefined;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/platform/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform module — factory + barrel exports.
|
|
3
|
+
*
|
|
4
|
+
* @module platform
|
|
5
|
+
*/
|
|
6
|
+
export type { PlatformType, WorkItem, PullRequest, PlatformAdapter, WorkItemSource, HybridPlatformConfig, CommunicationChannel, CommunicationReply, CommunicationConfig, CommunicationAdapter } from './types.js';
|
|
7
|
+
export type { GitHubRemoteInfo, AzureDevOpsRemoteInfo } from './detect.js';
|
|
8
|
+
export { detectPlatform, detectPlatformFromUrl, detectWorkItemSource, parseGitHubRemote, parseAzureDevOpsRemote, getRemoteUrl } from './detect.js';
|
|
9
|
+
export { GitHubAdapter } from './github.js';
|
|
10
|
+
export { AzureDevOpsAdapter } from './azure-devops.js';
|
|
11
|
+
export type { AdoWorkItemConfig } from './azure-devops.js';
|
|
12
|
+
export { PlannerAdapter, mapPlannerTaskToWorkItem } from './planner.js';
|
|
13
|
+
export { getRalphScanCommands } from './ralph-commands.js';
|
|
14
|
+
export type { RalphCommands } from './ralph-commands.js';
|
|
15
|
+
export { FileLogCommunicationAdapter } from './comms-file-log.js';
|
|
16
|
+
export { GitHubDiscussionsCommunicationAdapter } from './comms-github-discussions.js';
|
|
17
|
+
export { ADODiscussionCommunicationAdapter } from './comms-ado-discussions.js';
|
|
18
|
+
export { createCommunicationAdapter } from './comms.js';
|
|
19
|
+
import type { PlatformAdapter } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Create a platform adapter by auto-detecting the platform from the repo's git remote.
|
|
22
|
+
* Throws if required remote info cannot be parsed.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createPlatformAdapter(repoRoot: string): PlatformAdapter;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClN,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnJ,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,qCAAqC,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAIxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsBlD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAsBvE"}
|