@bradygaster/squad-sdk 0.8.22 → 0.8.24
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,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform module — factory + barrel exports.
|
|
3
|
+
*
|
|
4
|
+
* @module platform
|
|
5
|
+
*/
|
|
6
|
+
export { detectPlatform, detectPlatformFromUrl, detectWorkItemSource, parseGitHubRemote, parseAzureDevOpsRemote, getRemoteUrl } from './detect.js';
|
|
7
|
+
export { GitHubAdapter } from './github.js';
|
|
8
|
+
export { AzureDevOpsAdapter } from './azure-devops.js';
|
|
9
|
+
export { PlannerAdapter, mapPlannerTaskToWorkItem } from './planner.js';
|
|
10
|
+
export { getRalphScanCommands } from './ralph-commands.js';
|
|
11
|
+
export { FileLogCommunicationAdapter } from './comms-file-log.js';
|
|
12
|
+
export { GitHubDiscussionsCommunicationAdapter } from './comms-github-discussions.js';
|
|
13
|
+
export { ADODiscussionCommunicationAdapter } from './comms-ado-discussions.js';
|
|
14
|
+
export { createCommunicationAdapter } from './comms.js';
|
|
15
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { detectPlatform, getRemoteUrl, parseGitHubRemote, parseAzureDevOpsRemote } from './detect.js';
|
|
18
|
+
import { GitHubAdapter } from './github.js';
|
|
19
|
+
import { AzureDevOpsAdapter } from './azure-devops.js';
|
|
20
|
+
/**
|
|
21
|
+
* Read ADO work item config from .squad/config.json if present.
|
|
22
|
+
*/
|
|
23
|
+
function readAdoConfig(repoRoot) {
|
|
24
|
+
const configPath = join(repoRoot, '.squad', 'config.json');
|
|
25
|
+
if (!existsSync(configPath))
|
|
26
|
+
return undefined;
|
|
27
|
+
try {
|
|
28
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
29
|
+
const parsed = JSON.parse(raw);
|
|
30
|
+
if (parsed.ado && typeof parsed.ado === 'object') {
|
|
31
|
+
return parsed.ado;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch { /* ignore parse errors */ }
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a platform adapter by auto-detecting the platform from the repo's git remote.
|
|
39
|
+
* Throws if required remote info cannot be parsed.
|
|
40
|
+
*/
|
|
41
|
+
export function createPlatformAdapter(repoRoot) {
|
|
42
|
+
const platform = detectPlatform(repoRoot);
|
|
43
|
+
const remoteUrl = getRemoteUrl(repoRoot);
|
|
44
|
+
if (!remoteUrl) {
|
|
45
|
+
throw new Error('No git remote "origin" found. Cannot create platform adapter.');
|
|
46
|
+
}
|
|
47
|
+
if (platform === 'azure-devops') {
|
|
48
|
+
const info = parseAzureDevOpsRemote(remoteUrl);
|
|
49
|
+
if (!info) {
|
|
50
|
+
throw new Error(`Could not parse Azure DevOps remote URL: ${remoteUrl}`);
|
|
51
|
+
}
|
|
52
|
+
const adoConfig = readAdoConfig(repoRoot);
|
|
53
|
+
return new AzureDevOpsAdapter(info.org, info.project, info.repo, adoConfig);
|
|
54
|
+
}
|
|
55
|
+
const info = parseGitHubRemote(remoteUrl);
|
|
56
|
+
if (!info) {
|
|
57
|
+
throw new Error(`Could not parse GitHub remote URL: ${remoteUrl}`);
|
|
58
|
+
}
|
|
59
|
+
return new GitHubAdapter(info.owner, info.repo);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,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;AAEvD,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,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;AAExD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD;;GAEG;AACH,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAC1D,IAAI,MAAM,CAAC,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YACjD,OAAO,MAAM,CAAC,GAAwB,CAAC;QACzC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;IACrC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,4CAA4C,SAAS,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,sCAAsC,SAAS,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft Planner adapter — uses Graph API via az CLI token for task management.
|
|
3
|
+
* Planner buckets map to squad assignments (squad:untriaged, squad:riker, etc.)
|
|
4
|
+
*
|
|
5
|
+
* @module platform/planner
|
|
6
|
+
*/
|
|
7
|
+
import type { PlatformType, WorkItem } from './types.js';
|
|
8
|
+
/** Planner task shape from Graph API */
|
|
9
|
+
interface PlannerTask {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
percentComplete: number;
|
|
13
|
+
bucketId: string;
|
|
14
|
+
assignments: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/** Planner bucket shape from Graph API */
|
|
17
|
+
interface PlannerBucket {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Map a Planner task + bucket name to a normalized WorkItem.
|
|
23
|
+
* The original Planner task ID is stored in the url field so it can be recovered.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mapPlannerTaskToWorkItem(task: PlannerTask, bucketName: string): WorkItem;
|
|
26
|
+
/**
|
|
27
|
+
* Planner adapter — partial PlatformAdapter for work-item operations only.
|
|
28
|
+
* Planner has no concept of PRs or branches, so those methods are not implemented.
|
|
29
|
+
* Use alongside a repo adapter (GitHub/ADO) in a hybrid config.
|
|
30
|
+
*/
|
|
31
|
+
export declare class PlannerAdapter {
|
|
32
|
+
private readonly planId;
|
|
33
|
+
readonly type: PlatformType;
|
|
34
|
+
private bucketCache;
|
|
35
|
+
constructor(planId: string);
|
|
36
|
+
private graphFetch;
|
|
37
|
+
/** Fetch and cache buckets for this plan */
|
|
38
|
+
getBuckets(): Promise<PlannerBucket[]>;
|
|
39
|
+
/** Resolve a bucket name to its ID */
|
|
40
|
+
getBucketId(bucketName: string): Promise<string | undefined>;
|
|
41
|
+
/** Resolve a bucket ID to its name */
|
|
42
|
+
getBucketName(bucketId: string): Promise<string>;
|
|
43
|
+
listWorkItems(options: {
|
|
44
|
+
tags?: string[];
|
|
45
|
+
state?: string;
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): Promise<WorkItem[]>;
|
|
48
|
+
createWorkItem(options: {
|
|
49
|
+
title: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
tags?: string[];
|
|
52
|
+
}): Promise<WorkItem>;
|
|
53
|
+
addTag(taskId: string, bucketName: string): Promise<void>;
|
|
54
|
+
addComment(taskId: string, comment: string): Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/platform/planner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAIzD,wCAAwC;AACxC,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,0CAA0C;AAC1C,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAgCD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,GACjB,QAAQ,CAQV;AAcD;;;;GAIG;AACH,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAa;IACxC,OAAO,CAAC,WAAW,CAAgC;gBAEtB,MAAM,EAAE,MAAM;IAE3C,OAAO,CAAC,UAAU;IAuBlB,4CAA4C;IACtC,UAAU,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAS5C,sCAAsC;IAChC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAKlE,sCAAsC;IAChC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKhD,aAAa,CAAC,OAAO,EAAE;QAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAkCjB,cAAc,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyCpG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWjE"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft Planner adapter — uses Graph API via az CLI token for task management.
|
|
3
|
+
* Planner buckets map to squad assignments (squad:untriaged, squad:riker, etc.)
|
|
4
|
+
*
|
|
5
|
+
* @module platform/planner
|
|
6
|
+
*/
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
const EXEC_OPTS = { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] };
|
|
9
|
+
/**
|
|
10
|
+
* Get a Microsoft Graph access token via the az CLI.
|
|
11
|
+
* Requires: `az login` completed beforehand.
|
|
12
|
+
*/
|
|
13
|
+
function getGraphToken() {
|
|
14
|
+
try {
|
|
15
|
+
const output = execFileSync('az', ['account', 'get-access-token', '--resource-type', 'ms-graph', '--query', 'accessToken', '-o', 'tsv'], EXEC_OPTS).trim();
|
|
16
|
+
return output;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error('Could not obtain Microsoft Graph token. Ensure you are logged in:\n' +
|
|
20
|
+
' az login\n' +
|
|
21
|
+
' az account get-access-token --resource-type ms-graph');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Safely parse JSON output, including raw text in error messages */
|
|
25
|
+
function parseJson(raw) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(raw);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
throw new Error(`Failed to parse JSON from CLI output: ${err.message}\nRaw output: ${raw}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Map a Planner task + bucket name to a normalized WorkItem.
|
|
35
|
+
* The original Planner task ID is stored in the url field so it can be recovered.
|
|
36
|
+
*/
|
|
37
|
+
export function mapPlannerTaskToWorkItem(task, bucketName) {
|
|
38
|
+
return {
|
|
39
|
+
id: hashTaskId(task.id),
|
|
40
|
+
title: task.title,
|
|
41
|
+
state: task.percentComplete === 100 ? 'done' : 'active',
|
|
42
|
+
tags: [bucketName],
|
|
43
|
+
url: `https://tasks.office.com/task/${task.id}`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert a Planner string ID to a stable numeric hash.
|
|
48
|
+
* WorkItem.id is a number, but Planner IDs are strings.
|
|
49
|
+
*/
|
|
50
|
+
function hashTaskId(id) {
|
|
51
|
+
let hash = 0;
|
|
52
|
+
for (let i = 0; i < id.length; i++) {
|
|
53
|
+
hash = ((hash << 5) - hash + id.charCodeAt(i)) | 0;
|
|
54
|
+
}
|
|
55
|
+
return Math.abs(hash);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Planner adapter — partial PlatformAdapter for work-item operations only.
|
|
59
|
+
* Planner has no concept of PRs or branches, so those methods are not implemented.
|
|
60
|
+
* Use alongside a repo adapter (GitHub/ADO) in a hybrid config.
|
|
61
|
+
*/
|
|
62
|
+
export class PlannerAdapter {
|
|
63
|
+
planId;
|
|
64
|
+
type = 'planner';
|
|
65
|
+
bucketCache = null;
|
|
66
|
+
constructor(planId) {
|
|
67
|
+
this.planId = planId;
|
|
68
|
+
}
|
|
69
|
+
graphFetch(path, method = 'GET', body) {
|
|
70
|
+
const token = getGraphToken();
|
|
71
|
+
const url = `https://graph.microsoft.com/v1.0${path}`;
|
|
72
|
+
const curlArgs = [
|
|
73
|
+
'-s',
|
|
74
|
+
'-X', method,
|
|
75
|
+
'-H', 'Content-Type: application/json',
|
|
76
|
+
'--config', '-',
|
|
77
|
+
];
|
|
78
|
+
if (body) {
|
|
79
|
+
curlArgs.push('-d', body);
|
|
80
|
+
}
|
|
81
|
+
curlArgs.push(url);
|
|
82
|
+
// Pass the Authorization header via stdin so the token is not visible in process args.
|
|
83
|
+
const config = `header "Authorization: Bearer ${token}"`;
|
|
84
|
+
return execFileSync('curl', curlArgs, {
|
|
85
|
+
encoding: 'utf-8',
|
|
86
|
+
input: config,
|
|
87
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
88
|
+
}).trim();
|
|
89
|
+
}
|
|
90
|
+
/** Fetch and cache buckets for this plan */
|
|
91
|
+
async getBuckets() {
|
|
92
|
+
if (this.bucketCache)
|
|
93
|
+
return this.bucketCache;
|
|
94
|
+
const output = this.graphFetch(`/planner/plans/${this.planId}/buckets`);
|
|
95
|
+
const data = parseJson(output);
|
|
96
|
+
this.bucketCache = data.value;
|
|
97
|
+
return this.bucketCache;
|
|
98
|
+
}
|
|
99
|
+
/** Resolve a bucket name to its ID */
|
|
100
|
+
async getBucketId(bucketName) {
|
|
101
|
+
const buckets = await this.getBuckets();
|
|
102
|
+
return buckets.find((b) => b.name === bucketName)?.id;
|
|
103
|
+
}
|
|
104
|
+
/** Resolve a bucket ID to its name */
|
|
105
|
+
async getBucketName(bucketId) {
|
|
106
|
+
const buckets = await this.getBuckets();
|
|
107
|
+
return buckets.find((b) => b.id === bucketId)?.name ?? 'unknown';
|
|
108
|
+
}
|
|
109
|
+
async listWorkItems(options) {
|
|
110
|
+
const output = this.graphFetch(`/planner/plans/${this.planId}/tasks`);
|
|
111
|
+
const data = parseJson(output);
|
|
112
|
+
const buckets = await this.getBuckets();
|
|
113
|
+
const bucketMap = new Map(buckets.map((b) => [b.id, b.name]));
|
|
114
|
+
let tasks = data.value;
|
|
115
|
+
// Filter by bucket name (tag)
|
|
116
|
+
if (options.tags?.length) {
|
|
117
|
+
const targetBucketIds = new Set();
|
|
118
|
+
for (const tag of options.tags) {
|
|
119
|
+
const bucket = buckets.find((b) => b.name === tag);
|
|
120
|
+
if (bucket)
|
|
121
|
+
targetBucketIds.add(bucket.id);
|
|
122
|
+
}
|
|
123
|
+
tasks = tasks.filter((t) => targetBucketIds.has(t.bucketId));
|
|
124
|
+
}
|
|
125
|
+
// Filter by state
|
|
126
|
+
if (options.state === 'done') {
|
|
127
|
+
tasks = tasks.filter((t) => t.percentComplete === 100);
|
|
128
|
+
}
|
|
129
|
+
else if (options.state === 'active') {
|
|
130
|
+
tasks = tasks.filter((t) => t.percentComplete < 100);
|
|
131
|
+
}
|
|
132
|
+
if (options.limit) {
|
|
133
|
+
tasks = tasks.slice(0, options.limit);
|
|
134
|
+
}
|
|
135
|
+
return tasks.map((task) => mapPlannerTaskToWorkItem(task, bucketMap.get(task.bucketId) ?? 'unknown'));
|
|
136
|
+
}
|
|
137
|
+
async createWorkItem(options) {
|
|
138
|
+
// Resolve target bucket from tags (first squad: tag), default to untriaged
|
|
139
|
+
let bucketId;
|
|
140
|
+
let bucketName = 'squad:untriaged';
|
|
141
|
+
if (options.tags?.length) {
|
|
142
|
+
for (const tag of options.tags) {
|
|
143
|
+
const bid = await this.getBucketId(tag);
|
|
144
|
+
if (bid) {
|
|
145
|
+
bucketId = bid;
|
|
146
|
+
bucketName = tag;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!bucketId) {
|
|
152
|
+
bucketId = await this.getBucketId('squad:untriaged');
|
|
153
|
+
}
|
|
154
|
+
const taskBody = {
|
|
155
|
+
planId: this.planId,
|
|
156
|
+
title: options.title,
|
|
157
|
+
};
|
|
158
|
+
if (bucketId) {
|
|
159
|
+
taskBody.bucketId = bucketId;
|
|
160
|
+
}
|
|
161
|
+
const output = this.graphFetch('/planner/tasks', 'POST', JSON.stringify(taskBody));
|
|
162
|
+
const task = parseJson(output);
|
|
163
|
+
// Add description if provided
|
|
164
|
+
if (options.description) {
|
|
165
|
+
this.graphFetch(`/planner/tasks/${task.id}/details`, 'PATCH', JSON.stringify({ description: options.description, previewType: 'description' }));
|
|
166
|
+
}
|
|
167
|
+
return mapPlannerTaskToWorkItem(task, bucketName);
|
|
168
|
+
}
|
|
169
|
+
async addTag(taskId, bucketName) {
|
|
170
|
+
const bucketId = await this.getBucketId(bucketName);
|
|
171
|
+
if (!bucketId) {
|
|
172
|
+
throw new Error(`Bucket "${bucketName}" not found in plan ${this.planId}`);
|
|
173
|
+
}
|
|
174
|
+
// Moving a task to a different bucket = reassigning
|
|
175
|
+
this.graphFetch(`/planner/tasks/${taskId}`, 'PATCH', JSON.stringify({ bucketId }));
|
|
176
|
+
}
|
|
177
|
+
async addComment(taskId, comment) {
|
|
178
|
+
// Planner task comments go through the group conversation thread
|
|
179
|
+
this.graphFetch(`/planner/tasks/${taskId}/details`, 'PATCH', JSON.stringify({
|
|
180
|
+
description: comment,
|
|
181
|
+
previewType: 'description',
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/platform/planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific Ralph commands for triage and work management.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/ralph-commands
|
|
5
|
+
*/
|
|
6
|
+
import type { PlatformType } from './types.js';
|
|
7
|
+
export interface RalphCommands {
|
|
8
|
+
listUntriaged: string;
|
|
9
|
+
listAssigned: string;
|
|
10
|
+
listOpenPRs: string;
|
|
11
|
+
listDraftPRs: string;
|
|
12
|
+
createBranch: string;
|
|
13
|
+
createPR: string;
|
|
14
|
+
mergePR: string;
|
|
15
|
+
createWorkItem: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get Ralph scan/triage commands for a given platform.
|
|
19
|
+
* GitHub → gh CLI commands
|
|
20
|
+
* Azure DevOps → az CLI commands
|
|
21
|
+
*/
|
|
22
|
+
export declare function getRalphScanCommands(platform: PlatformType): RalphCommands;
|
|
23
|
+
/** Ralph commands for Planner via Graph API (az CLI token) */
|
|
24
|
+
export declare function getPlannerRalphCommands(): RalphCommands;
|
|
25
|
+
//# sourceMappingURL=ralph-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ralph-commands.d.ts","sourceRoot":"","sources":["../../src/platform/ralph-commands.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAW1E;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,IAAI,aAAa,CAmBvD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific Ralph commands for triage and work management.
|
|
3
|
+
*
|
|
4
|
+
* @module platform/ralph-commands
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get Ralph scan/triage commands for a given platform.
|
|
8
|
+
* GitHub → gh CLI commands
|
|
9
|
+
* Azure DevOps → az CLI commands
|
|
10
|
+
*/
|
|
11
|
+
export function getRalphScanCommands(platform) {
|
|
12
|
+
switch (platform) {
|
|
13
|
+
case 'github':
|
|
14
|
+
return getGitHubRalphCommands();
|
|
15
|
+
case 'azure-devops':
|
|
16
|
+
return getAzureDevOpsRalphCommands();
|
|
17
|
+
case 'planner':
|
|
18
|
+
return getPlannerRalphCommands();
|
|
19
|
+
default:
|
|
20
|
+
return getGitHubRalphCommands();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Ralph commands for Planner via Graph API (az CLI token) */
|
|
24
|
+
export function getPlannerRalphCommands() {
|
|
25
|
+
return {
|
|
26
|
+
listUntriaged: `curl -s -H "Authorization: Bearer $(az account get-access-token --resource-type ms-graph --query accessToken -o tsv)" "https://graph.microsoft.com/v1.0/planner/plans/{planId}/tasks?$filter=bucketId eq '{untriagedBucketId}'"`,
|
|
27
|
+
listAssigned: `curl -s -H "Authorization: Bearer $(az account get-access-token --resource-type ms-graph --query accessToken -o tsv)" "https://graph.microsoft.com/v1.0/planner/plans/{planId}/tasks?$filter=bucketId eq '{memberBucketId}'"`,
|
|
28
|
+
listOpenPRs: 'echo "Planner does not manage PRs — use the repo adapter (GitHub or Azure DevOps)"',
|
|
29
|
+
listDraftPRs: 'echo "Planner does not manage PRs — use the repo adapter (GitHub or Azure DevOps)"',
|
|
30
|
+
createBranch: 'git checkout main && git pull && git checkout -b {branchName}',
|
|
31
|
+
createPR: 'echo "Planner does not manage PRs — use the repo adapter (GitHub or Azure DevOps)"',
|
|
32
|
+
mergePR: 'echo "Planner does not manage PRs — use the repo adapter (GitHub or Azure DevOps)"',
|
|
33
|
+
createWorkItem: `curl -s -X POST -H "Authorization: Bearer $(az account get-access-token --resource-type ms-graph --query accessToken -o tsv)" -H "Content-Type: application/json" -d '{"planId":"{planId}","title":"{title}","bucketId":"{bucketId}"}' "https://graph.microsoft.com/v1.0/planner/tasks"`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function getGitHubRalphCommands() {
|
|
37
|
+
return {
|
|
38
|
+
listUntriaged: 'gh issue list --label "squad:untriaged" --json number,title,labels,assignees --limit 20',
|
|
39
|
+
listAssigned: 'gh issue list --label "squad:{member}" --state open --json number,title,labels,assignees --limit 20',
|
|
40
|
+
listOpenPRs: 'gh pr list --state open --json number,title,headRefName,baseRefName,state,isDraft,reviewDecision,author --limit 20',
|
|
41
|
+
listDraftPRs: 'gh pr list --state open --draft --json number,title,headRefName,baseRefName,state,isDraft,reviewDecision,author --limit 20',
|
|
42
|
+
createBranch: 'git checkout main && git pull && git checkout -b {branchName}',
|
|
43
|
+
createPR: 'gh pr create --title "{title}" --body "{description}" --head {sourceBranch} --base {targetBranch}',
|
|
44
|
+
mergePR: 'gh pr merge {id} --merge',
|
|
45
|
+
createWorkItem: 'gh issue create --title "{title}" --body "{description}" --label "{tags}"',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function getAzureDevOpsRalphCommands() {
|
|
49
|
+
return {
|
|
50
|
+
listUntriaged: `az boards query --wiql "SELECT [System.Id],[System.Title],[System.State],[System.Tags] FROM WorkItems WHERE [System.Tags] Contains 'squad:untriaged' ORDER BY [System.CreatedDate] DESC" --output table`,
|
|
51
|
+
listAssigned: `az boards query --wiql "SELECT [System.Id],[System.Title],[System.State],[System.Tags] FROM WorkItems WHERE [System.Tags] Contains 'squad:{member}' AND [System.State] <> 'Closed' ORDER BY [System.CreatedDate] DESC" --output table`,
|
|
52
|
+
listOpenPRs: 'az repos pr list --status active --output table',
|
|
53
|
+
listDraftPRs: 'az repos pr list --status active --query "[?isDraft==`true`]" --output table',
|
|
54
|
+
createBranch: 'git checkout main && git pull && git checkout -b {branchName}',
|
|
55
|
+
createPR: 'az repos pr create --title "{title}" --description "{description}" --source-branch {sourceBranch} --target-branch {targetBranch}',
|
|
56
|
+
mergePR: 'az repos pr update --id {id} --status completed',
|
|
57
|
+
createWorkItem: 'az boards work-item create --type "{workItemType}" --title "{title}" --description "{description}" --fields "System.Tags={tags}"',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=ralph-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ralph-commands.js","sourceRoot":"","sources":["../../src/platform/ralph-commands.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAsB;IACzD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,sBAAsB,EAAE,CAAC;QAClC,KAAK,cAAc;YACjB,OAAO,2BAA2B,EAAE,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,uBAAuB,EAAE,CAAC;QACnC;YACE,OAAO,sBAAsB,EAAE,CAAC;IACpC,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,aAAa,EACX,iOAAiO;QACnO,YAAY,EACV,8NAA8N;QAChO,WAAW,EACT,oFAAoF;QACtF,YAAY,EACV,oFAAoF;QACtF,YAAY,EACV,+DAA+D;QACjE,QAAQ,EACN,oFAAoF;QACtF,OAAO,EACL,oFAAoF;QACtF,cAAc,EACZ,yRAAyR;KAC5R,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB;IAC7B,OAAO;QACL,aAAa,EACX,yFAAyF;QAC3F,YAAY,EACV,qGAAqG;QACvG,WAAW,EACT,oHAAoH;QACtH,YAAY,EACV,4HAA4H;QAC9H,YAAY,EACV,+DAA+D;QACjE,QAAQ,EACN,mGAAmG;QACrG,OAAO,EACL,0BAA0B;QAC5B,cAAc,EACZ,2EAA2E;KAC9E,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;QACL,aAAa,EACX,yMAAyM;QAC3M,YAAY,EACV,uOAAuO;QACzO,WAAW,EACT,iDAAiD;QACnD,YAAY,EACV,8EAA8E;QAChF,YAAY,EACV,+DAA+D;QACjE,QAAQ,EACN,kIAAkI;QACpI,OAAO,EACL,iDAAiD;QACnD,cAAc,EACZ,kIAAkI;KACrI,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic interfaces for multi-platform support.
|
|
3
|
+
* Allows Squad to work with GitHub and Azure DevOps interchangeably.
|
|
4
|
+
*
|
|
5
|
+
* @module platform/types
|
|
6
|
+
*/
|
|
7
|
+
export type PlatformType = 'github' | 'azure-devops' | 'planner';
|
|
8
|
+
/** Where work items are tracked — may differ from where code lives */
|
|
9
|
+
export type WorkItemSource = 'github' | 'azure-devops' | 'planner';
|
|
10
|
+
/** Hybrid config: repo on one platform, work items on another */
|
|
11
|
+
export interface HybridPlatformConfig {
|
|
12
|
+
repo: PlatformType;
|
|
13
|
+
workItems: WorkItemSource;
|
|
14
|
+
}
|
|
15
|
+
/** Normalized work item — maps to GitHub Issues or ADO Work Items */
|
|
16
|
+
export interface WorkItem {
|
|
17
|
+
id: number;
|
|
18
|
+
title: string;
|
|
19
|
+
state: string;
|
|
20
|
+
tags: string[];
|
|
21
|
+
assignedTo?: string;
|
|
22
|
+
url: string;
|
|
23
|
+
}
|
|
24
|
+
/** Normalized pull request — maps to GitHub PRs or ADO PRs */
|
|
25
|
+
export interface PullRequest {
|
|
26
|
+
id: number;
|
|
27
|
+
title: string;
|
|
28
|
+
sourceBranch: string;
|
|
29
|
+
targetBranch: string;
|
|
30
|
+
status: 'active' | 'completed' | 'abandoned' | 'draft';
|
|
31
|
+
reviewStatus?: 'approved' | 'changes-requested' | 'pending';
|
|
32
|
+
author: string;
|
|
33
|
+
url: string;
|
|
34
|
+
}
|
|
35
|
+
/** Platform adapter interface — implemented by GitHub and ADO adapters */
|
|
36
|
+
export interface PlatformAdapter {
|
|
37
|
+
readonly type: PlatformType;
|
|
38
|
+
listWorkItems(options: {
|
|
39
|
+
tags?: string[];
|
|
40
|
+
state?: string;
|
|
41
|
+
limit?: number;
|
|
42
|
+
}): Promise<WorkItem[]>;
|
|
43
|
+
getWorkItem(id: number): Promise<WorkItem>;
|
|
44
|
+
createWorkItem(options: {
|
|
45
|
+
title: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
tags?: string[];
|
|
48
|
+
assignedTo?: string;
|
|
49
|
+
type?: string;
|
|
50
|
+
}): Promise<WorkItem>;
|
|
51
|
+
addTag(workItemId: number, tag: string): Promise<void>;
|
|
52
|
+
removeTag(workItemId: number, tag: string): Promise<void>;
|
|
53
|
+
addComment(workItemId: number, comment: string): Promise<void>;
|
|
54
|
+
listPullRequests(options: {
|
|
55
|
+
status?: string;
|
|
56
|
+
limit?: number;
|
|
57
|
+
}): Promise<PullRequest[]>;
|
|
58
|
+
createPullRequest(options: {
|
|
59
|
+
title: string;
|
|
60
|
+
sourceBranch: string;
|
|
61
|
+
targetBranch: string;
|
|
62
|
+
description?: string;
|
|
63
|
+
}): Promise<PullRequest>;
|
|
64
|
+
mergePullRequest(id: number): Promise<void>;
|
|
65
|
+
createBranch(name: string, fromBranch?: string): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
/** Where communication happens — which channel/service */
|
|
68
|
+
export type CommunicationChannel = 'github-discussions' | 'ado-work-items' | 'teams-webhook' | 'file-log';
|
|
69
|
+
/** A reply from a human on a communication channel */
|
|
70
|
+
export interface CommunicationReply {
|
|
71
|
+
author: string;
|
|
72
|
+
body: string;
|
|
73
|
+
timestamp: Date;
|
|
74
|
+
/** Platform-specific identifier for the reply */
|
|
75
|
+
id: string;
|
|
76
|
+
}
|
|
77
|
+
/** Configuration for a communication channel */
|
|
78
|
+
export interface CommunicationConfig {
|
|
79
|
+
channel: CommunicationChannel;
|
|
80
|
+
/** Post session summaries after agent work */
|
|
81
|
+
postAfterSession?: boolean;
|
|
82
|
+
/** Post decisions that need human review */
|
|
83
|
+
postDecisions?: boolean;
|
|
84
|
+
/** Post escalations when agents are blocked */
|
|
85
|
+
postEscalations?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Communication adapter interface — pluggable agent-human communication.
|
|
89
|
+
*
|
|
90
|
+
* Abstracts the communication channel so Squad can post updates and read
|
|
91
|
+
* replies from GitHub Discussions, ADO Work Item discussions, Teams, or
|
|
92
|
+
* plain log files — depending on what the user has configured.
|
|
93
|
+
*/
|
|
94
|
+
export interface CommunicationAdapter {
|
|
95
|
+
readonly channel: CommunicationChannel;
|
|
96
|
+
/**
|
|
97
|
+
* Post an update to the communication channel.
|
|
98
|
+
* Used by Scribe (session summaries), Ralph (board status), and agents (escalations).
|
|
99
|
+
*/
|
|
100
|
+
postUpdate(options: {
|
|
101
|
+
title: string;
|
|
102
|
+
body: string;
|
|
103
|
+
category?: string;
|
|
104
|
+
/** Agent or role posting the update */
|
|
105
|
+
author?: string;
|
|
106
|
+
}): Promise<{
|
|
107
|
+
id: string;
|
|
108
|
+
url?: string;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* Poll for replies since a given timestamp.
|
|
112
|
+
* Returns new replies from humans on the channel.
|
|
113
|
+
*/
|
|
114
|
+
pollForReplies(options: {
|
|
115
|
+
/** Thread/discussion ID to check for replies */
|
|
116
|
+
threadId: string;
|
|
117
|
+
since: Date;
|
|
118
|
+
}): Promise<CommunicationReply[]>;
|
|
119
|
+
/**
|
|
120
|
+
* Get a URL that humans can open on any device (phone, browser, desktop).
|
|
121
|
+
* Returns undefined if the channel has no web UI (e.g., file-log).
|
|
122
|
+
*/
|
|
123
|
+
getNotificationUrl(threadId: string): string | undefined;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/dist/streams/filter.d.ts
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* SubSquad-Aware Issue Filtering
|
|
3
3
|
*
|
|
4
|
-
* Filters GitHub issues to only those matching a
|
|
5
|
-
* Intended to scope work to the active
|
|
4
|
+
* Filters GitHub issues to only those matching a SubSquad's labelFilter.
|
|
5
|
+
* Intended to scope work to the active SubSquad during triage.
|
|
6
6
|
*
|
|
7
7
|
* @module streams/filter
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { ResolvedSubSquad } from './types.js';
|
|
10
10
|
/** Minimal issue shape for filtering. */
|
|
11
|
-
export interface
|
|
11
|
+
export interface SubSquadIssue {
|
|
12
12
|
number: number;
|
|
13
13
|
title: string;
|
|
14
14
|
labels: Array<{
|
|
15
15
|
name: string;
|
|
16
16
|
}>;
|
|
17
17
|
}
|
|
18
|
-
/** @deprecated Use
|
|
19
|
-
export type
|
|
18
|
+
/** @deprecated Use SubSquadIssue instead */
|
|
19
|
+
export type WorkstreamIssue = SubSquadIssue;
|
|
20
|
+
/** @deprecated Use SubSquadIssue instead */
|
|
21
|
+
export type StreamIssue = SubSquadIssue;
|
|
20
22
|
/**
|
|
21
|
-
* Filter issues to only those matching the
|
|
23
|
+
* Filter issues to only those matching the SubSquad's label filter.
|
|
22
24
|
*
|
|
23
|
-
* Matching is case-insensitive. If the
|
|
25
|
+
* Matching is case-insensitive. If the SubSquad has no labelFilter,
|
|
24
26
|
* all issues are returned (passthrough).
|
|
25
27
|
*
|
|
26
28
|
* @param issues - Array of issues to filter
|
|
27
|
-
* @param
|
|
28
|
-
* @returns Filtered array of issues matching the
|
|
29
|
+
* @param subsquad - The resolved SubSquad to filter by
|
|
30
|
+
* @returns Filtered array of issues matching the SubSquad's label
|
|
29
31
|
*/
|
|
30
|
-
export declare function
|
|
31
|
-
/** @deprecated Use
|
|
32
|
-
export declare const
|
|
32
|
+
export declare function filterIssuesBySubSquad(issues: SubSquadIssue[], subsquad: ResolvedSubSquad): SubSquadIssue[];
|
|
33
|
+
/** @deprecated Use filterIssuesBySubSquad instead */
|
|
34
|
+
export declare const filterIssuesByWorkstream: typeof filterIssuesBySubSquad;
|
|
35
|
+
/** @deprecated Use filterIssuesBySubSquad instead */
|
|
36
|
+
export declare const filterIssuesByStream: typeof filterIssuesBySubSquad;
|
|
33
37
|
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/streams/filter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/streams/filter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,4CAA4C;AAC5C,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC;AAE5C,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAExC;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EAAE,EACvB,QAAQ,EAAE,gBAAgB,GACzB,aAAa,EAAE,CAUjB;AAED,qDAAqD;AACrD,eAAO,MAAM,wBAAwB,+BAAyB,CAAC;AAE/D,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,+BAAyB,CAAC"}
|