instar 0.24.19 → 0.24.21
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/.claude/settings.json +120 -0
- package/.claude/skills/setup-wizard/skill.md +2 -2
- package/dashboard/index.html +146 -4
- package/dist/cli.js +0 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +18 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +23 -2
- package/dist/commands/setup.js.map +1 -1
- package/dist/core/GitSync.d.ts +3 -2
- package/dist/core/GitSync.d.ts.map +1 -1
- package/dist/core/GitSync.js +19 -4
- package/dist/core/GitSync.js.map +1 -1
- package/dist/core/SessionManager.d.ts +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +31 -0
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/messaging/slack/SlackAdapter.d.ts +25 -4
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
- package/dist/messaging/slack/SlackAdapter.js +156 -12
- package/dist/messaging/slack/SlackAdapter.js.map +1 -1
- package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -1
- package/dist/messaging/slack/SocketModeClient.js +11 -4
- package/dist/messaging/slack/SocketModeClient.js.map +1 -1
- package/dist/messaging/slack/types.d.ts +30 -0
- package/dist/messaging/slack/types.d.ts.map +1 -1
- package/dist/messaging/slack/types.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +4 -4
- package/upgrades/0.24.14.md +26 -0
- package/upgrades/0.24.18-beta.0.md +35 -0
- package/upgrades/0.24.18.md +26 -26
- package/upgrades/0.24.21.md +25 -0
- package/upgrades/NEXT.md +45 -0
- /package/.claude/skills/secret-setup/{skill.md → SKILL.md} +0 -0
package/.claude/settings.json
CHANGED
|
@@ -67,6 +67,126 @@
|
|
|
67
67
|
}
|
|
68
68
|
]
|
|
69
69
|
}
|
|
70
|
+
],
|
|
71
|
+
"PostToolUse": [
|
|
72
|
+
{
|
|
73
|
+
"matcher": "",
|
|
74
|
+
"hooks": [
|
|
75
|
+
{
|
|
76
|
+
"type": "command",
|
|
77
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
78
|
+
"timeout": 3000
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"SubagentStart": [
|
|
84
|
+
{
|
|
85
|
+
"matcher": "",
|
|
86
|
+
"hooks": [
|
|
87
|
+
{
|
|
88
|
+
"type": "command",
|
|
89
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
90
|
+
"timeout": 3000
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"SubagentStop": [
|
|
96
|
+
{
|
|
97
|
+
"matcher": "",
|
|
98
|
+
"hooks": [
|
|
99
|
+
{
|
|
100
|
+
"type": "command",
|
|
101
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
102
|
+
"timeout": 3000
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"Stop": [
|
|
108
|
+
{
|
|
109
|
+
"matcher": "",
|
|
110
|
+
"hooks": [
|
|
111
|
+
{
|
|
112
|
+
"type": "command",
|
|
113
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
114
|
+
"timeout": 3000
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"WorktreeCreate": [
|
|
120
|
+
{
|
|
121
|
+
"matcher": "",
|
|
122
|
+
"hooks": [
|
|
123
|
+
{
|
|
124
|
+
"type": "command",
|
|
125
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
126
|
+
"timeout": 3000
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"WorktreeRemove": [
|
|
132
|
+
{
|
|
133
|
+
"matcher": "",
|
|
134
|
+
"hooks": [
|
|
135
|
+
{
|
|
136
|
+
"type": "command",
|
|
137
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
138
|
+
"timeout": 3000
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"TaskCompleted": [
|
|
144
|
+
{
|
|
145
|
+
"matcher": "",
|
|
146
|
+
"hooks": [
|
|
147
|
+
{
|
|
148
|
+
"type": "command",
|
|
149
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
150
|
+
"timeout": 3000
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
"SessionEnd": [
|
|
156
|
+
{
|
|
157
|
+
"matcher": "",
|
|
158
|
+
"hooks": [
|
|
159
|
+
{
|
|
160
|
+
"type": "command",
|
|
161
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
162
|
+
"timeout": 3000
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
"PreCompact": [
|
|
168
|
+
{
|
|
169
|
+
"matcher": "",
|
|
170
|
+
"hooks": [
|
|
171
|
+
{
|
|
172
|
+
"type": "command",
|
|
173
|
+
"command": "node .instar/hooks/instar/hook-event-reporter.js",
|
|
174
|
+
"timeout": 3000
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"PermissionRequest": [
|
|
180
|
+
{
|
|
181
|
+
"matcher": "",
|
|
182
|
+
"hooks": [
|
|
183
|
+
{
|
|
184
|
+
"type": "command",
|
|
185
|
+
"command": "node .instar/hooks/instar/auto-approve-permissions.js",
|
|
186
|
+
"timeout": 5000
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
70
190
|
]
|
|
71
191
|
},
|
|
72
192
|
"mcpServers": {
|
|
@@ -1621,8 +1621,8 @@ Build the app manifest JSON with minimal Phase 1 scopes:
|
|
|
1621
1621
|
"oauth_config": {
|
|
1622
1622
|
"scopes": {
|
|
1623
1623
|
"bot": [
|
|
1624
|
-
"channels:history", "channels:manage", "channels:read",
|
|
1625
|
-
"chat:write", "im:history", "im:read", "im:write",
|
|
1624
|
+
"channels:history", "channels:join", "channels:manage", "channels:read",
|
|
1625
|
+
"chat:write", "files:read", "groups:history", "im:history", "im:read", "im:write",
|
|
1626
1626
|
"pins:write", "reactions:read", "reactions:write", "users:read"
|
|
1627
1627
|
]
|
|
1628
1628
|
}
|
package/dashboard/index.html
CHANGED
|
@@ -2004,6 +2004,19 @@
|
|
|
2004
2004
|
.systems-event-time { color: var(--text-dim); white-space: nowrap; font-size: 11px; min-width: 60px; }
|
|
2005
2005
|
.systems-event-text { color: var(--text); flex: 1; }
|
|
2006
2006
|
|
|
2007
|
+
/* Content Browser (browsable stats) */
|
|
2008
|
+
.cap-content-panel { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; margin-top: 12px; overflow: hidden; }
|
|
2009
|
+
.cap-content-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 12px; font-weight: 600; color: var(--text-bright); }
|
|
2010
|
+
.cap-content-body { max-height: 400px; overflow-y: auto; padding: 8px; }
|
|
2011
|
+
.cap-content-item { padding: 10px 12px; border: 1px solid var(--border); border-radius: 6px; margin-bottom: 6px; background: var(--bg-panel); }
|
|
2012
|
+
.cap-content-item-title { font-size: 13px; font-weight: 500; color: var(--text-bright); margin-bottom: 4px; }
|
|
2013
|
+
.cap-content-item-body { font-size: 12px; color: var(--text-dim); line-height: 1.5; word-break: break-word; }
|
|
2014
|
+
.cap-content-item-time { font-size: 11px; color: var(--text-dim); margin-top: 4px; }
|
|
2015
|
+
.cap-content-tag { display: inline-block; font-size: 10px; padding: 2px 8px; border-radius: 3px; background: rgba(255,255,255,0.06); color: var(--text-dim); margin-right: 4px; margin-top: 4px; }
|
|
2016
|
+
.cap-content-tag.applied { background: rgba(76,175,80,0.15); color: var(--accent); }
|
|
2017
|
+
.cap-content-empty { padding: 16px; text-align: center; color: var(--text-dim); font-size: 12px; }
|
|
2018
|
+
.cap-stat-card:hover { border-color: var(--accent); transition: border-color 0.15s; }
|
|
2019
|
+
|
|
2007
2020
|
.discovery-container {
|
|
2008
2021
|
grid-column: 1 / -1;
|
|
2009
2022
|
overflow-y: auto;
|
|
@@ -5484,7 +5497,7 @@
|
|
|
5484
5497
|
document.getElementById('systemsDetailView').classList.add('active');
|
|
5485
5498
|
const content = document.getElementById('systemsDetailContent');
|
|
5486
5499
|
|
|
5487
|
-
const statCards = buildStatCards(cap.stats || {});
|
|
5500
|
+
const statCards = buildStatCards(cap.stats || {}, capId);
|
|
5488
5501
|
const processRows = (cap.processes || []).map(p => {
|
|
5489
5502
|
const dotColor = p.status === 'running' ? 'var(--accent)' : 'var(--red)';
|
|
5490
5503
|
return `<div class="cap-process-row">
|
|
@@ -5506,7 +5519,7 @@
|
|
|
5506
5519
|
<div class="cap-detail-description">${esc(cap.description)}</div>
|
|
5507
5520
|
${lastAct}
|
|
5508
5521
|
</div>
|
|
5509
|
-
${statCards ? '<div class="cap-detail-section"><div class="cap-detail-section-title">Metrics</div><div class="cap-stats-grid">' + statCards + '</div></div>' : ''}
|
|
5522
|
+
${statCards ? '<div class="cap-detail-section"><div class="cap-detail-section-title">Metrics</div><div class="cap-stats-grid">' + statCards + '</div><div id="capContentBrowser"></div></div>' : ''}
|
|
5510
5523
|
<div class="cap-detail-section">
|
|
5511
5524
|
<div class="cap-detail-section-title">Components (${(cap.processes || []).length})</div>
|
|
5512
5525
|
<div class="cap-process-list">${processRows}</div>
|
|
@@ -5517,7 +5530,31 @@
|
|
|
5517
5530
|
</div>`;
|
|
5518
5531
|
}
|
|
5519
5532
|
|
|
5520
|
-
|
|
5533
|
+
// Map stat keys to browsable content endpoints
|
|
5534
|
+
const BROWSABLE_STATS = {
|
|
5535
|
+
// Evolution
|
|
5536
|
+
learnings: { endpoint: '/evolution/learnings', label: 'Learnings', renderer: 'renderLearnings' },
|
|
5537
|
+
proposals: { endpoint: '/evolution/proposals', label: 'Proposals', renderer: 'renderProposals' },
|
|
5538
|
+
gaps: { endpoint: '/evolution/gaps', label: 'Capability Gaps', renderer: 'renderGaps' },
|
|
5539
|
+
actions: { endpoint: '/evolution/actions', label: 'Actions', renderer: 'renderActions' },
|
|
5540
|
+
overdueActions: { endpoint: '/evolution/actions/overdue', label: 'Overdue Actions', renderer: 'renderActions' },
|
|
5541
|
+
// Health
|
|
5542
|
+
coherenceChecks: { endpoint: '/health/coherence', label: 'Coherence Report', renderer: 'renderCoherence' },
|
|
5543
|
+
coherencePassed: { endpoint: '/health/coherence', label: 'Coherence Report', renderer: 'renderCoherence' },
|
|
5544
|
+
coherenceFailed: { endpoint: '/health/coherence', label: 'Coherence Report', renderer: 'renderCoherence' },
|
|
5545
|
+
// Recovery
|
|
5546
|
+
totalTriages: { endpoint: '/triage/history?limit=20', label: 'Triage History', renderer: 'renderTriageHistory' },
|
|
5547
|
+
interventions: { endpoint: '/watchdog/status', label: 'Watchdog Status', renderer: 'renderWatchdog' },
|
|
5548
|
+
recoveries: { endpoint: '/watchdog/status', label: 'Watchdog Status', renderer: 'renderWatchdog' },
|
|
5549
|
+
// Jobs
|
|
5550
|
+
totalJobs: { endpoint: '/jobs', label: 'Jobs', renderer: 'renderJobs' },
|
|
5551
|
+
enabledJobs: { endpoint: '/jobs', label: 'Jobs', renderer: 'renderJobs' },
|
|
5552
|
+
// Telegram
|
|
5553
|
+
totalMessages: { endpoint: '/telegram/log-stats', label: 'Message Stats', renderer: 'renderTelegramStats' },
|
|
5554
|
+
topicMappings: { endpoint: '/telegram/log-stats', label: 'Message Stats', renderer: 'renderTelegramStats' },
|
|
5555
|
+
};
|
|
5556
|
+
|
|
5557
|
+
function buildStatCards(stats, capId) {
|
|
5521
5558
|
if (!stats || typeof stats !== 'object') return '';
|
|
5522
5559
|
const map = {
|
|
5523
5560
|
interventions: 'Interventions', recoveries: 'Recoveries', sessionDeaths: 'Deaths',
|
|
@@ -5535,12 +5572,117 @@
|
|
|
5535
5572
|
const cards = [];
|
|
5536
5573
|
for (const [key, label] of Object.entries(map)) {
|
|
5537
5574
|
if (stats[key] != null && typeof stats[key] === 'number') {
|
|
5538
|
-
|
|
5575
|
+
const browsable = BROWSABLE_STATS[key];
|
|
5576
|
+
const clickAttr = browsable ? ` onclick="browseStatContent('${key}')" style="cursor:pointer"` : '';
|
|
5577
|
+
const browseHint = browsable ? '<div style="font-size:9px;color:var(--accent);margin-top:2px">click to view</div>' : '';
|
|
5578
|
+
cards.push(`<div class="cap-stat-card"${clickAttr}><div class="cap-stat-card-value">${stats[key]}</div><div class="cap-stat-card-label">${esc(label)}</div>${browseHint}</div>`);
|
|
5539
5579
|
}
|
|
5540
5580
|
}
|
|
5541
5581
|
return cards.join('');
|
|
5542
5582
|
}
|
|
5543
5583
|
|
|
5584
|
+
async function browseStatContent(statKey) {
|
|
5585
|
+
const info = BROWSABLE_STATS[statKey];
|
|
5586
|
+
if (!info) return;
|
|
5587
|
+
const panel = document.getElementById('capContentBrowser');
|
|
5588
|
+
if (!panel) return;
|
|
5589
|
+
panel.innerHTML = '<div style="padding:12px;color:var(--text-dim);font-size:12px">Loading ' + esc(info.label) + '...</div>';
|
|
5590
|
+
try {
|
|
5591
|
+
const data = await apiFetch(info.endpoint);
|
|
5592
|
+
panel.innerHTML = '<div class="cap-content-panel">' +
|
|
5593
|
+
'<div class="cap-content-header"><span>' + esc(info.label) + '</span><button onclick="document.getElementById(\'capContentBrowser\').innerHTML=\'\'" style="border:none;background:none;color:var(--text-dim);cursor:pointer;font-size:14px">×</button></div>' +
|
|
5594
|
+
'<div class="cap-content-body">' + renderBrowsableContent(info.renderer, data) + '</div></div>';
|
|
5595
|
+
} catch (e) {
|
|
5596
|
+
panel.innerHTML = '<div style="padding:12px;color:var(--red);font-size:12px">Failed to load: ' + esc(e.message) + '</div>';
|
|
5597
|
+
}
|
|
5598
|
+
}
|
|
5599
|
+
|
|
5600
|
+
function renderBrowsableContent(renderer, data) {
|
|
5601
|
+
switch (renderer) {
|
|
5602
|
+
case 'renderLearnings': {
|
|
5603
|
+
const items = data.learnings || data || [];
|
|
5604
|
+
if (!Array.isArray(items) || items.length === 0) return '<div class="cap-content-empty">No learnings recorded</div>';
|
|
5605
|
+
return items.map(l => `<div class="cap-content-item">
|
|
5606
|
+
<div class="cap-content-item-title">${esc(l.title || l.insight || l.id || 'Untitled')}</div>
|
|
5607
|
+
${l.description || l.context ? '<div class="cap-content-item-body">' + esc(l.description || l.context || '') + '</div>' : ''}
|
|
5608
|
+
${l.category ? '<span class="cap-content-tag">' + esc(l.category) + '</span>' : ''}
|
|
5609
|
+
${l.applied ? '<span class="cap-content-tag applied">Applied</span>' : ''}
|
|
5610
|
+
${l.createdAt ? '<div class="cap-content-item-time">' + esc(timeAgo(l.createdAt)) + '</div>' : ''}
|
|
5611
|
+
</div>`).join('');
|
|
5612
|
+
}
|
|
5613
|
+
case 'renderProposals': {
|
|
5614
|
+
const items = data.proposals || data || [];
|
|
5615
|
+
if (!Array.isArray(items) || items.length === 0) return '<div class="cap-content-empty">No proposals</div>';
|
|
5616
|
+
return items.map(p => `<div class="cap-content-item">
|
|
5617
|
+
<div class="cap-content-item-title">${esc(p.title || p.id || 'Untitled')}</div>
|
|
5618
|
+
${p.description ? '<div class="cap-content-item-body">' + esc(p.description) + '</div>' : ''}
|
|
5619
|
+
${p.status ? '<span class="cap-content-tag">' + esc(p.status) + '</span>' : ''}
|
|
5620
|
+
${p.type ? '<span class="cap-content-tag">' + esc(p.type) + '</span>' : ''}
|
|
5621
|
+
</div>`).join('');
|
|
5622
|
+
}
|
|
5623
|
+
case 'renderGaps': {
|
|
5624
|
+
const items = data.gaps || data || [];
|
|
5625
|
+
if (!Array.isArray(items) || items.length === 0) return '<div class="cap-content-empty">No gaps detected</div>';
|
|
5626
|
+
return items.map(g => `<div class="cap-content-item">
|
|
5627
|
+
<div class="cap-content-item-title">${esc(g.title || g.capability || g.id || 'Untitled')}</div>
|
|
5628
|
+
${g.description ? '<div class="cap-content-item-body">' + esc(g.description) + '</div>' : ''}
|
|
5629
|
+
${g.severity ? '<span class="cap-content-tag">' + esc(g.severity) + '</span>' : ''}
|
|
5630
|
+
</div>`).join('');
|
|
5631
|
+
}
|
|
5632
|
+
case 'renderActions': {
|
|
5633
|
+
const items = data.actions || data || [];
|
|
5634
|
+
if (!Array.isArray(items) || items.length === 0) return '<div class="cap-content-empty">No actions</div>';
|
|
5635
|
+
return items.map(a => `<div class="cap-content-item">
|
|
5636
|
+
<div class="cap-content-item-title">${esc(a.title || a.action || a.id || 'Untitled')}</div>
|
|
5637
|
+
${a.status ? '<span class="cap-content-tag">' + esc(a.status) + '</span>' : ''}
|
|
5638
|
+
${a.dueAt ? '<div class="cap-content-item-time">Due: ' + esc(timeAgo(a.dueAt)) + '</div>' : ''}
|
|
5639
|
+
</div>`).join('');
|
|
5640
|
+
}
|
|
5641
|
+
case 'renderCoherence': {
|
|
5642
|
+
const report = data.lastReport || data;
|
|
5643
|
+
if (!report || !report.checks) return '<div class="cap-content-empty">No coherence data</div>';
|
|
5644
|
+
return report.checks.map(c => `<div class="cap-content-item" style="border-left:3px solid ${c.passed ? 'var(--accent)' : 'var(--red)'}">
|
|
5645
|
+
<div class="cap-content-item-title">${c.passed ? '✓' : '✗'} ${esc(c.name)}</div>
|
|
5646
|
+
<div class="cap-content-item-body">${esc(c.message)}</div>
|
|
5647
|
+
</div>`).join('');
|
|
5648
|
+
}
|
|
5649
|
+
case 'renderTriageHistory': {
|
|
5650
|
+
const items = data.history || data || [];
|
|
5651
|
+
if (!Array.isArray(items) || items.length === 0) return '<div class="cap-content-empty">No triage history</div>';
|
|
5652
|
+
return items.map(t => `<div class="cap-content-item">
|
|
5653
|
+
<div class="cap-content-item-title">Topic ${t.topicId} — ${esc(t.sessionName || 'unknown')}</div>
|
|
5654
|
+
<div class="cap-content-item-body">${t.result ? esc(JSON.stringify(t.result.actionsTaken || t.result, null, 0).substring(0, 200)) : ''}</div>
|
|
5655
|
+
${t.timestamp ? '<div class="cap-content-item-time">' + esc(timeAgo(t.timestamp)) + '</div>' : ''}
|
|
5656
|
+
</div>`).join('');
|
|
5657
|
+
}
|
|
5658
|
+
case 'renderWatchdog': {
|
|
5659
|
+
const hist = data.interventionHistory || [];
|
|
5660
|
+
if (hist.length === 0) return '<div class="cap-content-empty">No interventions recorded</div>';
|
|
5661
|
+
return hist.map(h => `<div class="cap-content-item">
|
|
5662
|
+
<div class="cap-content-item-title">PID ${h.stuckPid || '?'} — ${esc(h.level || h.outcome || 'intervention')}</div>
|
|
5663
|
+
${h.outcome ? '<span class="cap-content-tag">' + esc(h.outcome) + '</span>' : ''}
|
|
5664
|
+
${h.timestamp ? '<div class="cap-content-item-time">' + esc(timeAgo(h.timestamp)) + '</div>' : ''}
|
|
5665
|
+
</div>`).join('');
|
|
5666
|
+
}
|
|
5667
|
+
case 'renderJobs': {
|
|
5668
|
+
const jobs = data.jobs || data || [];
|
|
5669
|
+
if (!Array.isArray(jobs) || jobs.length === 0) return '<div class="cap-content-empty">No jobs</div>';
|
|
5670
|
+
return jobs.slice(0, 20).map(j => `<div class="cap-content-item">
|
|
5671
|
+
<div class="cap-content-item-title">${esc(j.slug || j.name || 'unnamed')}</div>
|
|
5672
|
+
<div class="cap-content-item-body">${esc(j.cron || '')} ${j.enabled === false ? '(disabled)' : ''}</div>
|
|
5673
|
+
</div>`).join('');
|
|
5674
|
+
}
|
|
5675
|
+
case 'renderTelegramStats': {
|
|
5676
|
+
return `<div class="cap-content-item">
|
|
5677
|
+
<div class="cap-content-item-title">Message Log</div>
|
|
5678
|
+
<div class="cap-content-item-body">Total messages: ${data.totalMessages || '?'}<br>Log size: ${data.logSizeBytes ? Math.round(data.logSizeBytes / 1024) + ' KB' : '?'}</div>
|
|
5679
|
+
</div>`;
|
|
5680
|
+
}
|
|
5681
|
+
default:
|
|
5682
|
+
return '<div class="cap-content-empty">No viewer for this content</div>';
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
|
|
5544
5686
|
function showSystemsOverview() {
|
|
5545
5687
|
document.getElementById('systemsOverview').style.display = '';
|
|
5546
5688
|
document.getElementById('systemsDetailView').classList.remove('active');
|
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AA+CH,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yFAAyF;IACzF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBrE;AAgzFD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAiBlF"}
|
package/dist/commands/init.js
CHANGED
|
@@ -31,7 +31,7 @@ import os from 'node:os';
|
|
|
31
31
|
import path from 'node:path';
|
|
32
32
|
import pc from 'picocolors';
|
|
33
33
|
import { randomUUID } from 'node:crypto';
|
|
34
|
-
import { execFileSync } from 'node:child_process';
|
|
34
|
+
import { execFileSync, execSync } from 'node:child_process';
|
|
35
35
|
import { detectTmuxPath, detectClaudePath, detectGitPath, detectGhPath, ensureStateDir, standaloneAgentsDir, getInstarVersion } from '../core/Config.js';
|
|
36
36
|
import { ensurePrerequisites } from '../core/Prerequisites.js';
|
|
37
37
|
import { allocatePort, registerAgent, validateAgentName } from '../core/AgentRegistry.js';
|
|
@@ -44,6 +44,24 @@ import { CanonicalState } from '../core/CanonicalState.js';
|
|
|
44
44
|
import { ManifestIntegrity } from '../security/ManifestIntegrity.js';
|
|
45
45
|
import { buildHttpHookSettings } from '../data/http-hook-templates.js';
|
|
46
46
|
import { generateAgentMd, generateUserMd, generateMemoryMd, generateClaudeMd, generateSoulMd, } from '../scaffold/templates.js';
|
|
47
|
+
/**
|
|
48
|
+
* Find a free port in the default range (4040-4099) by checking if anything
|
|
49
|
+
* is listening. Used as fallback when allocatePort() fails (e.g., registry
|
|
50
|
+
* is corrupted or locked).
|
|
51
|
+
*/
|
|
52
|
+
function findFreePortFallback() {
|
|
53
|
+
for (let port = 4040; port <= 4099; port++) {
|
|
54
|
+
try {
|
|
55
|
+
execSync(`lsof -iTCP:${port} -sTCP:LISTEN -P -n`, { stdio: 'ignore' });
|
|
56
|
+
// lsof found a listener — port is in use
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// lsof found nothing — port is free
|
|
60
|
+
return port;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return 4040; // All ports in range are busy — return default and let server fail with a clear error
|
|
64
|
+
}
|
|
47
65
|
/**
|
|
48
66
|
* Main init entry point. Handles both fresh and existing project modes.
|
|
49
67
|
*/
|
|
@@ -124,7 +142,7 @@ async function initFreshProject(projectName, options) {
|
|
|
124
142
|
console.log(` ${pc.green('✓')} Auto-allocated port ${port} (from ~/.instar/registry.json)`);
|
|
125
143
|
}
|
|
126
144
|
catch {
|
|
127
|
-
port =
|
|
145
|
+
port = findFreePortFallback();
|
|
128
146
|
}
|
|
129
147
|
}
|
|
130
148
|
// Generate identity (non-interactive for init, interactive for setup)
|
|
@@ -401,7 +419,7 @@ async function initExistingProject(options) {
|
|
|
401
419
|
port = allocatePort(projectDir);
|
|
402
420
|
}
|
|
403
421
|
catch {
|
|
404
|
-
port =
|
|
422
|
+
port = findFreePortFallback();
|
|
405
423
|
}
|
|
406
424
|
}
|
|
407
425
|
console.log(pc.bold(`\nInitializing instar in: ${pc.cyan(projectDir)}`));
|
|
@@ -732,7 +750,7 @@ async function initStandaloneAgent(agentName, options) {
|
|
|
732
750
|
console.log(` ${pc.green('✓')} Auto-allocated port ${port}`);
|
|
733
751
|
}
|
|
734
752
|
catch {
|
|
735
|
-
port =
|
|
753
|
+
port = findFreePortFallback();
|
|
736
754
|
}
|
|
737
755
|
}
|
|
738
756
|
// Create directory structure
|