instar 0.28.64 → 0.28.66

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 (85) hide show
  1. package/dashboard/index.html +225 -0
  2. package/dist/cli.js +0 -0
  3. package/dist/commands/init.js +6 -8
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/server.d.ts.map +1 -1
  6. package/dist/commands/server.js +44 -2
  7. package/dist/commands/server.js.map +1 -1
  8. package/dist/core/AutoDispatcher.d.ts +4 -1
  9. package/dist/core/AutoDispatcher.d.ts.map +1 -1
  10. package/dist/core/AutoDispatcher.js +5 -4
  11. package/dist/core/AutoDispatcher.js.map +1 -1
  12. package/dist/core/AutoUpdater.d.ts +6 -1
  13. package/dist/core/AutoUpdater.d.ts.map +1 -1
  14. package/dist/core/AutoUpdater.js +7 -4
  15. package/dist/core/AutoUpdater.js.map +1 -1
  16. package/dist/core/PostUpdateMigrator.d.ts +12 -1
  17. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  18. package/dist/core/PostUpdateMigrator.js +158 -0
  19. package/dist/core/PostUpdateMigrator.js.map +1 -1
  20. package/dist/lifeline/TelegramLifeline.d.ts +9 -1
  21. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  22. package/dist/lifeline/TelegramLifeline.js +48 -2
  23. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  24. package/dist/lifeline/droppedMessages.d.ts +67 -0
  25. package/dist/lifeline/droppedMessages.d.ts.map +1 -0
  26. package/dist/lifeline/droppedMessages.js +179 -0
  27. package/dist/lifeline/droppedMessages.js.map +1 -0
  28. package/dist/lifeline/retryWithBackoff.d.ts +22 -0
  29. package/dist/lifeline/retryWithBackoff.d.ts.map +1 -0
  30. package/dist/lifeline/retryWithBackoff.js +32 -0
  31. package/dist/lifeline/retryWithBackoff.js.map +1 -0
  32. package/dist/messaging/shared/compactionResumePayload.d.ts +1 -1
  33. package/dist/messaging/shared/compactionResumePayload.d.ts.map +1 -1
  34. package/dist/messaging/shared/compactionResumePayload.js +14 -5
  35. package/dist/messaging/shared/compactionResumePayload.js.map +1 -1
  36. package/dist/monitoring/CommitmentTracker.d.ts +37 -0
  37. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
  38. package/dist/monitoring/CommitmentTracker.js +151 -5
  39. package/dist/monitoring/CommitmentTracker.js.map +1 -1
  40. package/dist/monitoring/HelperWatchdog.d.ts +84 -0
  41. package/dist/monitoring/HelperWatchdog.d.ts.map +1 -0
  42. package/dist/monitoring/HelperWatchdog.js +155 -0
  43. package/dist/monitoring/HelperWatchdog.js.map +1 -0
  44. package/dist/monitoring/PresenceProxy.d.ts +71 -0
  45. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  46. package/dist/monitoring/PresenceProxy.js +210 -0
  47. package/dist/monitoring/PresenceProxy.js.map +1 -1
  48. package/dist/monitoring/ProxyCoordinator.d.ts +33 -0
  49. package/dist/monitoring/ProxyCoordinator.d.ts.map +1 -1
  50. package/dist/monitoring/ProxyCoordinator.js +42 -0
  51. package/dist/monitoring/ProxyCoordinator.js.map +1 -1
  52. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  53. package/dist/monitoring/SessionWatchdog.js +9 -6
  54. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  55. package/dist/server/AgentServer.d.ts +2 -0
  56. package/dist/server/AgentServer.d.ts.map +1 -1
  57. package/dist/server/AgentServer.js +1 -0
  58. package/dist/server/AgentServer.js.map +1 -1
  59. package/dist/server/routes.d.ts +4 -0
  60. package/dist/server/routes.d.ts.map +1 -1
  61. package/dist/server/routes.js +95 -0
  62. package/dist/server/routes.js.map +1 -1
  63. package/dist/threadline/PipeSessionSpawner.d.ts +5 -0
  64. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  65. package/dist/threadline/PipeSessionSpawner.js +11 -0
  66. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  67. package/package.json +1 -1
  68. package/playbook-scripts/build-state.py +102 -0
  69. package/src/data/builtin-manifest.json +70 -70
  70. package/upgrades/0.28.65.md +44 -0
  71. package/upgrades/0.28.66.md +44 -0
  72. package/upgrades/side-effects/0.28.64.md +5 -0
  73. package/upgrades/side-effects/0.28.66.md +130 -0
  74. package/upgrades/side-effects/build-stall-visibility-fix2-3.md +125 -0
  75. package/upgrades/side-effects/build-stop-hook-deployment.md +98 -0
  76. package/upgrades/side-effects/dashboard-secrets-tab.md +86 -0
  77. package/upgrades/side-effects/lifeline-message-drop-stage-a.md +155 -0
  78. package/upgrades/side-effects/threadline-relay-rapid-fire-pipe-guard.md +46 -0
  79. package/upgrades/side-effects/watchdog-mcp-version-pin.md +121 -0
  80. package/dist/core/InitiativeDigestJob.d.ts +0 -54
  81. package/dist/core/InitiativeDigestJob.d.ts.map +0 -1
  82. package/dist/core/InitiativeDigestJob.js +0 -128
  83. package/dist/core/InitiativeDigestJob.js.map +0 -1
  84. package/upgrades/0.28.61.md +0 -80
  85. package/upgrades/NEXT.md +0 -53
@@ -2410,6 +2410,7 @@
2410
2410
  <button class="tab active" data-tab="sessions" onclick="switchTab('sessions')">Sessions <span class="tab-count" id="tabSessionCount">0</span></button>
2411
2411
  <button class="tab" data-tab="files" onclick="switchTab('files')">Files</button>
2412
2412
  <button class="tab" data-tab="dropzone" onclick="switchTab('dropzone')">Send Content</button>
2413
+ <button class="tab" data-tab="secrets" onclick="switchTab('secrets')">Secrets <span class="tab-count" id="tabSecretCount">0</span></button>
2413
2414
  <button class="tab" data-tab="jobs" onclick="switchTab('jobs')">Jobs <span class="tab-count" id="tabJobCount">0</span></button>
2414
2415
  <button class="tab" data-tab="features" onclick="switchTab('features')">Features</button>
2415
2416
  <button class="tab" data-tab="systems" onclick="switchTab('systems')">Health</button>
@@ -2810,6 +2811,24 @@
2810
2811
  </div>
2811
2812
 
2812
2813
  <!-- Commitments Tab (Open Promises) -->
2814
+ <div id="secretsPanel" style="display:none;flex-direction:column;padding:20px;gap:16px;overflow-y:auto">
2815
+ <div style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap">
2816
+ <h2 style="margin:0">Secrets</h2>
2817
+ <div style="display:flex;gap:8px">
2818
+ <button onclick="createTestSecretRequest()" style="padding:6px 12px" title="Create a short-lived test Secret Drop request">Create test request</button>
2819
+ <button onclick="loadSecrets()" style="padding:6px 12px">Refresh</button>
2820
+ </div>
2821
+ </div>
2822
+ <div style="font-size:12px;color:var(--text-dim);line-height:1.4">
2823
+ Secret Drop — one-time-use links for users to submit credentials safely (never through chat).
2824
+ Links expire automatically and are destroyed after submission.
2825
+ </div>
2826
+ <div id="secretsEmpty" style="padding:40px;text-align:center;color:var(--text-dim);display:none">
2827
+ No pending secret requests.
2828
+ </div>
2829
+ <div id="secretsList" style="display:flex;flex-direction:column;gap:12px"></div>
2830
+ </div>
2831
+
2813
2832
  <div id="commitmentsPanel" style="display:none;flex-direction:column;padding:20px;gap:16px;overflow-y:auto">
2814
2833
  <div style="display:flex;justify-content:space-between;align-items:center">
2815
2834
  <h2 style="margin:0">Commitments</h2>
@@ -3873,6 +3892,18 @@
3873
3892
  display: ['flex'],
3874
3893
  onActivate: () => { if (typeof loadCommitments === 'function') loadCommitments(); },
3875
3894
  },
3895
+ {
3896
+ id: 'secrets',
3897
+ panels: ['secretsPanel'],
3898
+ display: ['flex'],
3899
+ onActivate: () => {
3900
+ if (typeof loadSecrets === 'function') loadSecrets();
3901
+ if (typeof startSecretsTicker === 'function') startSecretsTicker();
3902
+ },
3903
+ onDeactivate: () => {
3904
+ if (typeof stopSecretsTicker === 'function') stopSecretsTicker();
3905
+ },
3906
+ },
3876
3907
  ];
3877
3908
 
3878
3909
  function switchTab(tabName) {
@@ -6048,6 +6079,200 @@
6048
6079
  }
6049
6080
  }
6050
6081
 
6082
+ // ── Secrets Tab ──────────────────────────────────────────────
6083
+ let secretsTickerTimer = null;
6084
+ let secretsLastPending = [];
6085
+
6086
+ function formatCountdown(ms) {
6087
+ if (ms <= 0) return 'expired';
6088
+ const totalSec = Math.floor(ms / 1000);
6089
+ const m = Math.floor(totalSec / 60);
6090
+ const s = totalSec % 60;
6091
+ if (m > 0) return `${m}m ${s}s`;
6092
+ return `${s}s`;
6093
+ }
6094
+
6095
+ function renderSecretsCountdowns() {
6096
+ const now = Date.now();
6097
+ for (const p of secretsLastPending) {
6098
+ const el = document.getElementById(`secretCountdown-${p.token}`);
6099
+ if (!el) continue;
6100
+ const remaining = p.expiresAt - now;
6101
+ el.textContent = formatCountdown(remaining);
6102
+ if (remaining <= 0) {
6103
+ el.style.color = '#c66';
6104
+ }
6105
+ }
6106
+ }
6107
+
6108
+ function startSecretsTicker() {
6109
+ stopSecretsTicker();
6110
+ secretsTickerTimer = setInterval(renderSecretsCountdowns, 1000);
6111
+ }
6112
+
6113
+ function stopSecretsTicker() {
6114
+ if (secretsTickerTimer) {
6115
+ clearInterval(secretsTickerTimer);
6116
+ secretsTickerTimer = null;
6117
+ }
6118
+ }
6119
+
6120
+ async function loadSecrets() {
6121
+ const list = document.getElementById('secretsList');
6122
+ const empty = document.getElementById('secretsEmpty');
6123
+ const countBadge = document.getElementById('tabSecretCount');
6124
+ while (list.firstChild) list.removeChild(list.firstChild);
6125
+ empty.style.display = 'none';
6126
+
6127
+ let res = null;
6128
+ try {
6129
+ res = await apiFetch('/secrets/pending');
6130
+ } catch { /* fall through */ }
6131
+
6132
+ const pending = (res && Array.isArray(res.pending)) ? res.pending : [];
6133
+ secretsLastPending = pending;
6134
+
6135
+ // Badge shows non-expired count.
6136
+ const now = Date.now();
6137
+ const liveCount = pending.filter(p => p.expiresAt > now).length;
6138
+ if (countBadge) countBadge.textContent = String(liveCount);
6139
+
6140
+ if (pending.length === 0) {
6141
+ empty.style.display = 'block';
6142
+ empty.textContent = 'No pending secret requests.';
6143
+ return;
6144
+ }
6145
+
6146
+ const fmtTs = (ms) => {
6147
+ if (!ms) return '—';
6148
+ try { return new Date(ms).toLocaleString(); } catch { return String(ms); }
6149
+ };
6150
+
6151
+ for (const p of pending) {
6152
+ const card = document.createElement('div');
6153
+ card.style.cssText = 'padding:14px;border:1px solid var(--border);border-radius:6px;background:var(--bg-dim);display:flex;flex-direction:column;gap:8px';
6154
+
6155
+ const header = document.createElement('div');
6156
+ header.style.cssText = 'display:flex;justify-content:space-between;gap:12px;align-items:flex-start';
6157
+ const label = document.createElement('div');
6158
+ label.style.cssText = 'flex:1;font-weight:600;line-height:1.3';
6159
+ label.textContent = p.label || '(no label)';
6160
+ header.appendChild(label);
6161
+
6162
+ const badge = document.createElement('span');
6163
+ const expired = !!p.expired;
6164
+ badge.textContent = expired ? 'expired' : 'pending';
6165
+ badge.style.cssText = `font-size:11px;padding:3px 8px;border-radius:4px;background:${expired ? '#c66' : '#4a9a4a'};color:#fff;white-space:nowrap`;
6166
+ header.appendChild(badge);
6167
+ card.appendChild(header);
6168
+
6169
+ const meta = document.createElement('div');
6170
+ meta.style.cssText = 'display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:6px;font-size:12px;color:var(--text-dim)';
6171
+
6172
+ const rows = [
6173
+ ['token', (p.token || '').slice(0, 12) + '…'],
6174
+ ['topic', p.topicId != null ? String(p.topicId) : '—'],
6175
+ ['created', fmtTs(p.createdAt)],
6176
+ ['expires', fmtTs(p.expiresAt)],
6177
+ ];
6178
+ for (const [k, v] of rows) {
6179
+ const cell = document.createElement('div');
6180
+ const kEl = document.createElement('span');
6181
+ kEl.textContent = `${k}: `;
6182
+ kEl.style.opacity = '0.7';
6183
+ const vEl = document.createElement('span');
6184
+ vEl.textContent = v;
6185
+ vEl.style.color = 'var(--text)';
6186
+ cell.appendChild(kEl);
6187
+ cell.appendChild(vEl);
6188
+ meta.appendChild(cell);
6189
+ }
6190
+
6191
+ const countdownCell = document.createElement('div');
6192
+ const cLabel = document.createElement('span');
6193
+ cLabel.textContent = 'expires in: ';
6194
+ cLabel.style.opacity = '0.7';
6195
+ const cVal = document.createElement('span');
6196
+ cVal.id = `secretCountdown-${p.token}`;
6197
+ cVal.style.color = 'var(--text)';
6198
+ cVal.style.fontVariantNumeric = 'tabular-nums';
6199
+ cVal.textContent = formatCountdown(p.expiresAt - now);
6200
+ countdownCell.appendChild(cLabel);
6201
+ countdownCell.appendChild(cVal);
6202
+ meta.appendChild(countdownCell);
6203
+
6204
+ card.appendChild(meta);
6205
+
6206
+ // Links and actions.
6207
+ const actions = document.createElement('div');
6208
+ actions.style.cssText = 'display:flex;gap:8px;align-items:center;flex-wrap:wrap';
6209
+
6210
+ const url = p.tunnelUrl || p.localUrl;
6211
+ if (url) {
6212
+ const openBtn = document.createElement('a');
6213
+ openBtn.textContent = 'Open drop link';
6214
+ openBtn.href = url;
6215
+ openBtn.target = '_blank';
6216
+ openBtn.rel = 'noopener noreferrer';
6217
+ openBtn.style.cssText = 'padding:6px 10px;border:1px solid var(--border);border-radius:4px;text-decoration:none;color:var(--text);cursor:pointer';
6218
+ actions.appendChild(openBtn);
6219
+
6220
+ const copyBtn = document.createElement('button');
6221
+ copyBtn.textContent = 'Copy link';
6222
+ copyBtn.style.cssText = 'padding:6px 10px;cursor:pointer';
6223
+ copyBtn.addEventListener('click', async () => {
6224
+ try {
6225
+ await navigator.clipboard.writeText(url);
6226
+ copyBtn.textContent = 'Copied';
6227
+ setTimeout(() => { copyBtn.textContent = 'Copy link'; }, 1200);
6228
+ } catch {
6229
+ copyBtn.textContent = 'Copy failed';
6230
+ }
6231
+ });
6232
+ actions.appendChild(copyBtn);
6233
+ }
6234
+
6235
+ const cancelBtn = document.createElement('button');
6236
+ cancelBtn.textContent = 'Cancel';
6237
+ cancelBtn.style.cssText = 'padding:6px 10px;cursor:pointer';
6238
+ cancelBtn.addEventListener('click', async () => {
6239
+ cancelBtn.disabled = true;
6240
+ try {
6241
+ await apiFetch(`/secrets/pending/${encodeURIComponent(p.token)}`, { method: 'DELETE' });
6242
+ await loadSecrets();
6243
+ } catch (err) {
6244
+ cancelBtn.disabled = false;
6245
+ alert('Cancel failed: ' + (err && err.message ? err.message : String(err)));
6246
+ }
6247
+ });
6248
+ actions.appendChild(cancelBtn);
6249
+
6250
+ card.appendChild(actions);
6251
+ list.appendChild(card);
6252
+ }
6253
+ }
6254
+
6255
+ async function createTestSecretRequest() {
6256
+ try {
6257
+ const res = await apiFetch('/secrets/request', {
6258
+ method: 'POST',
6259
+ headers: { 'Content-Type': 'application/json' },
6260
+ body: JSON.stringify({
6261
+ label: 'Dashboard test request',
6262
+ description: 'Created from the Secrets tab for verification. Safe to cancel.',
6263
+ ttlMs: 5 * 60 * 1000,
6264
+ }),
6265
+ });
6266
+ await loadSecrets();
6267
+ const url = (res && (res.tunnelUrl || res.localUrl)) || '';
6268
+ if (url) {
6269
+ try { await navigator.clipboard.writeText(url); } catch { /* ignore */ }
6270
+ }
6271
+ } catch (err) {
6272
+ alert('Test request failed: ' + (err && err.message ? err.message : String(err)));
6273
+ }
6274
+ }
6275
+
6051
6276
  // ── Integrated-Being Tab (v1) ────────────────────────────────
6052
6277
  let integratedBeingPollTimer = null;
6053
6278
 
package/dist/cli.js CHANGED
File without changes
@@ -3549,14 +3549,12 @@ done
3549
3549
  // Real safety is in PreToolUse hooks (dangerous-command-guard, external-communication-guard).
3550
3550
  fs.writeFileSync(path.join(hooksDir, 'auto-approve-permissions.js'), getAutoApprovePermissionsScript(), { mode: 0o755 });
3551
3551
  // Build stop hook — structural enforcement for /build pipeline.
3552
- // Installed from template; only needs to exist when /build is active (registered dynamically).
3553
- const buildModDir = path.dirname(new URL(import.meta.url).pathname);
3554
- const buildStopHookSrc = path.join(buildModDir, '..', '..', 'src', 'templates', 'hooks', 'build-stop-hook.sh');
3555
- const buildStopHookDst = path.join(hooksDir, 'build-stop-hook.sh');
3556
- if (fs.existsSync(buildStopHookSrc) && !fs.existsSync(buildStopHookDst)) {
3557
- fs.copyFileSync(buildStopHookSrc, buildStopHookDst);
3558
- fs.chmodSync(buildStopHookDst, 0o755);
3559
- }
3552
+ // Shares the PostUpdateMigrator content so init and upgrade produce the same
3553
+ // file. Previously read from src/templates/hooks/build-stop-hook.sh, which
3554
+ // meant agents initialized before this block was added never received the
3555
+ // hook, yet settings.json references it — silent "No such file" on every
3556
+ // Stop event until they ran an upgrade.
3557
+ fs.writeFileSync(path.join(hooksDir, 'build-stop-hook.sh'), migrator.getHookContent('build-stop-hook'), { mode: 0o755 });
3560
3558
  }
3561
3559
  function getHookEventReporterScript() {
3562
3560
  return `#!/usr/bin/env node