@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.
Files changed (68) hide show
  1. package/dist/config/init.d.ts +3 -3
  2. package/dist/config/init.d.ts.map +1 -1
  3. package/dist/config/init.js +72 -16
  4. package/dist/config/init.js.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/platform/azure-devops.d.ts +68 -0
  10. package/dist/platform/azure-devops.d.ts.map +1 -0
  11. package/dist/platform/azure-devops.js +271 -0
  12. package/dist/platform/azure-devops.js.map +1 -0
  13. package/dist/platform/comms-ado-discussions.d.ts +31 -0
  14. package/dist/platform/comms-ado-discussions.d.ts.map +1 -0
  15. package/dist/platform/comms-ado-discussions.js +82 -0
  16. package/dist/platform/comms-ado-discussions.js.map +1 -0
  17. package/dist/platform/comms-file-log.d.ts +31 -0
  18. package/dist/platform/comms-file-log.d.ts.map +1 -0
  19. package/dist/platform/comms-file-log.js +71 -0
  20. package/dist/platform/comms-file-log.js.map +1 -0
  21. package/dist/platform/comms-github-discussions.d.ts +30 -0
  22. package/dist/platform/comms-github-discussions.d.ts.map +1 -0
  23. package/dist/platform/comms-github-discussions.js +68 -0
  24. package/dist/platform/comms-github-discussions.js.map +1 -0
  25. package/dist/platform/comms.d.ts +19 -0
  26. package/dist/platform/comms.d.ts.map +1 -0
  27. package/dist/platform/comms.js +109 -0
  28. package/dist/platform/comms.js.map +1 -0
  29. package/dist/platform/detect.d.ts +56 -0
  30. package/dist/platform/detect.d.ts.map +1 -0
  31. package/dist/platform/detect.js +109 -0
  32. package/dist/platform/detect.js.map +1 -0
  33. package/dist/platform/github.d.ts +43 -0
  34. package/dist/platform/github.d.ts.map +1 -0
  35. package/dist/platform/github.js +192 -0
  36. package/dist/platform/github.js.map +1 -0
  37. package/dist/platform/index.d.ts +25 -0
  38. package/dist/platform/index.d.ts.map +1 -0
  39. package/dist/platform/index.js +61 -0
  40. package/dist/platform/index.js.map +1 -0
  41. package/dist/platform/planner.d.ts +57 -0
  42. package/dist/platform/planner.d.ts.map +1 -0
  43. package/dist/platform/planner.js +185 -0
  44. package/dist/platform/planner.js.map +1 -0
  45. package/dist/platform/ralph-commands.d.ts +25 -0
  46. package/dist/platform/ralph-commands.d.ts.map +1 -0
  47. package/dist/platform/ralph-commands.js +60 -0
  48. package/dist/platform/ralph-commands.js.map +1 -0
  49. package/dist/platform/types.d.ts +125 -0
  50. package/dist/platform/types.d.ts.map +1 -0
  51. package/dist/platform/types.js +8 -0
  52. package/dist/platform/types.js.map +1 -0
  53. package/dist/streams/filter.d.ts +18 -14
  54. package/dist/streams/filter.d.ts.map +1 -1
  55. package/dist/streams/filter.js +13 -11
  56. package/dist/streams/filter.js.map +1 -1
  57. package/dist/streams/index.d.ts +1 -1
  58. package/dist/streams/index.js +1 -1
  59. package/dist/streams/resolver.d.ts +27 -21
  60. package/dist/streams/resolver.d.ts.map +1 -1
  61. package/dist/streams/resolver.js +41 -35
  62. package/dist/streams/resolver.js.map +1 -1
  63. package/dist/streams/types.d.ts +29 -23
  64. package/dist/streams/types.d.ts.map +1 -1
  65. package/dist/streams/types.js +2 -2
  66. package/dist/types.d.ts +13 -0
  67. package/dist/types.d.ts.map +1 -1
  68. 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,8 @@
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 {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1,33 +1,37 @@
1
1
  /**
2
- * Workstream-Aware Issue Filtering
2
+ * SubSquad-Aware Issue Filtering
3
3
  *
4
- * Filters GitHub issues to only those matching a workstream's labelFilter.
5
- * Intended to scope work to the active workstream during triage.
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 { ResolvedWorkstream } from './types.js';
9
+ import type { ResolvedSubSquad } from './types.js';
10
10
  /** Minimal issue shape for filtering. */
11
- export interface WorkstreamIssue {
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 WorkstreamIssue instead */
19
- export type StreamIssue = WorkstreamIssue;
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 workstream's label filter.
23
+ * Filter issues to only those matching the SubSquad's label filter.
22
24
  *
23
- * Matching is case-insensitive. If the workstream has no labelFilter,
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 workstream - The resolved workstream to filter by
28
- * @returns Filtered array of issues matching the workstream's label
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 filterIssuesByWorkstream(issues: WorkstreamIssue[], workstream: ResolvedWorkstream): WorkstreamIssue[];
31
- /** @deprecated Use filterIssuesByWorkstream instead */
32
- export declare const filterIssuesByStream: typeof filterIssuesByWorkstream;
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,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,8CAA8C;AAC9C,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,eAAe,EAAE,EACzB,UAAU,EAAE,kBAAkB,GAC7B,eAAe,EAAE,CAUnB;AAED,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,iCAA2B,CAAC"}
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"}