@atolis-hq/wake 0.2.3 → 0.2.5

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.
@@ -180,6 +180,22 @@ export async function readControlPlaneUiUrl(wakeRoot) {
180
180
  return undefined;
181
181
  }
182
182
  }
183
+ export function formatGitHubError(error) {
184
+ if (error instanceof Error) {
185
+ const octokit = error;
186
+ if (octokit.status !== undefined) {
187
+ const headers = octokit.response?.headers ?? {};
188
+ const parts = [`status=${octokit.status}`];
189
+ if (headers['x-ratelimit-remaining'] !== undefined)
190
+ parts.push(`ratelimit-remaining=${headers['x-ratelimit-remaining']}`);
191
+ if (headers['retry-after'] !== undefined)
192
+ parts.push(`retry-after=${headers['retry-after']}`);
193
+ return parts.join(' ');
194
+ }
195
+ return error.message.slice(0, 300);
196
+ }
197
+ return String(error).slice(0, 300);
198
+ }
183
199
  export function formatWakeComment(payload, controlPlaneUrl) {
184
200
  const body = typeof payload.body === 'string' ? payload.body : '';
185
201
  const kind = typeof payload.kind === 'string' ? payload.kind : undefined;
@@ -314,7 +330,7 @@ export function createGitHubIssuesWorkSource(deps) {
314
330
  });
315
331
  }
316
332
  catch (error) {
317
- console.error(`[github-work-source] poll failed for ${repoRef}, skipping this tick: ${error instanceof Error ? error.message : String(error)}`);
333
+ console.error(`[github-work-source] poll failed for ${repoRef}, skipping this tick: ${formatGitHubError(error)}`);
318
334
  }
319
335
  }
320
336
  return events;
@@ -1,6 +1,6 @@
1
1
  import { buildResourceUri } from '../../domain/resource-uri.js';
2
2
  import { createUnkeyedEventEnvelope, createEventEnvelope } from '../../lib/event-log.js';
3
- import { formatWakeComment, readControlPlaneUiUrl } from './github-issues-work-source.js';
3
+ import { formatGitHubError, formatWakeComment, readControlPlaneUiUrl, } from './github-issues-work-source.js';
4
4
  const githubPrSource = 'github-pr';
5
5
  const wakeCommentMarker = '<!-- wake:agent -->';
6
6
  function prResourceUri(repo, number) {
@@ -122,7 +122,7 @@ export function createGitHubPullRequestActivitySource(deps) {
122
122
  }
123
123
  }
124
124
  catch (error) {
125
- console.error(`[github-pr-activity-source] discovery failed for ${repoRef}, skipping this tick: ${error instanceof Error ? error.message : String(error)}`);
125
+ console.error(`[github-pr-activity-source] discovery failed for ${repoRef}, skipping this tick: ${formatGitHubError(error)}`);
126
126
  }
127
127
  }
128
128
  return { events, seenPrData, confirmedOpenRepos };
@@ -247,7 +247,7 @@ export function createGitHubPullRequestActivitySource(deps) {
247
247
  }
248
248
  }
249
249
  catch (error) {
250
- console.error(`[github-pr-activity-source] activity poll failed for ${resourceUri}, skipping this tick: ${error instanceof Error ? error.message : String(error)}`);
250
+ console.error(`[github-pr-activity-source] activity poll failed for ${resourceUri}, skipping this tick: ${formatGitHubError(error)}`);
251
251
  }
252
252
  return events;
253
253
  }
@@ -391,7 +391,7 @@ export function createGitHubPullRequestActivitySource(deps) {
391
391
  return await pollRequiredCheckFailures(ref, watchRef.resourceUri, ingestedAt, seenPrData.get(watchRef.resourceUri));
392
392
  }
393
393
  catch (error) {
394
- console.error(`[github-pr-activity-source] check poll failed for ${watchRef.resourceUri}, skipping this tick: ${error instanceof Error ? error.message : String(error)}`);
394
+ console.error(`[github-pr-activity-source] check poll failed for ${watchRef.resourceUri}, skipping this tick: ${formatGitHubError(error)}`);
395
395
  return [];
396
396
  }
397
397
  }));
@@ -73,6 +73,10 @@ export const indexHtml = `<!DOCTYPE html>
73
73
  .ok { color: #7fe3a3; }
74
74
  input[type=text] { background: #1a1d23; border: 1px solid #2c313a; color: #e8e8e8; padding: 0.3rem 0.5rem; border-radius: 6px; margin-bottom: 0.6rem; width: 260px; transition: border-color 0.12s ease, box-shadow 0.12s ease; }
75
75
  input[type=text]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.15); }
76
+ a { color: var(--accent-light); text-decoration: none; }
77
+ a:hover { text-decoration: underline; }
78
+ .resource-list { list-style: none; padding: 0; margin: 0 0 1rem; }
79
+ .resource-list li { display: flex; align-items: baseline; gap: 0.4rem; margin-bottom: 0.35rem; font-size: 0.8rem; }
76
80
  </style>
77
81
  </head>
78
82
  <body>
@@ -195,6 +199,21 @@ async function renderBoard() {
195
199
  main.appendChild(columns);
196
200
  }
197
201
 
202
+ function resourceUriToUrl(resourceUri) {
203
+ const parts = resourceUri.split(':');
204
+ if (parts.length < 3) return null;
205
+ const provider = parts[0];
206
+ const type = parts[1];
207
+ const locator = parts.slice(2).join(':');
208
+ const m = locator.match(/^(.+)#([0-9]+)$/);
209
+ if (!m) return null;
210
+ if (provider === 'github') {
211
+ if (type === 'issue') return 'https://github.com/' + m[1] + '/issues/' + m[2];
212
+ if (type === 'pr') return 'https://github.com/' + m[1] + '/pull/' + m[2];
213
+ }
214
+ return null;
215
+ }
216
+
198
217
  async function openItem(repo, number) {
199
218
  const drawer = document.getElementById('drawer');
200
219
  const body = document.getElementById('drawer-body');
@@ -203,12 +222,27 @@ async function openItem(repo, number) {
203
222
  const detail = await getJson('/items/' + encodeURIComponent(repo) + '/' + number);
204
223
  if (!detail) { body.textContent = 'Not found'; return; }
205
224
  body.innerHTML = '';
206
- body.appendChild(el('h2', { text: repo + '#' + number }));
225
+ const headLink = el('a', { href: detail.item.issue.url, target: '_blank', rel: 'noopener noreferrer', text: repo + '#' + number });
226
+ body.appendChild(el('h2', {}, [headLink]));
207
227
  body.appendChild(el('p', { text: detail.item.issue.title }));
208
228
  body.appendChild(el('p', { class: 'meta', text: 'stage: ' + detail.item.wake.stage + (detail.item.wake.sessionId ? ' · session: ' + detail.item.wake.sessionId : '') }));
209
229
  if (detail.item.wake.workspacePath) {
210
230
  body.appendChild(el('p', { class: 'meta', text: 'workspace: ' + detail.item.wake.workspacePath }));
211
231
  }
232
+ const resources = detail.item.correlatedResources || [];
233
+ if (resources.length > 0) {
234
+ body.appendChild(el('h3', { text: 'Resources' }));
235
+ const resourceList = el('ul', { class: 'resource-list' });
236
+ for (const res of resources) {
237
+ const resUrl = resourceUriToUrl(res.resourceUri);
238
+ const badge = el('span', { class: 'chip', text: res.role });
239
+ const linkOrText = resUrl
240
+ ? el('a', { href: resUrl, target: '_blank', rel: 'noopener noreferrer', text: res.resourceUri })
241
+ : el('span', { class: 'meta', text: res.resourceUri });
242
+ resourceList.appendChild(el('li', {}, [badge, linkOrText]));
243
+ }
244
+ body.appendChild(resourceList);
245
+ }
212
246
  body.appendChild(el('h3', { text: 'Runs' }));
213
247
  const runsTable = el('table', {}, [
214
248
  el('tr', {}, ['action', 'status', 'sentinel', 'started', 'runId'].map((h) => el('th', { text: h }))),
@@ -1 +1 @@
1
- export const wakeVersion = "0.2.3+gfb2197d";
1
+ export const wakeVersion = "0.2.5+ga2cf757";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atolis-hq/wake",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Local autonomous agent control plane for software development",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {