@yemi33/minions 0.1.1567 → 0.1.1568
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/CHANGELOG.md +5 -0
- package/dashboard/js/render-other.js +35 -2
- package/dashboard/js/settings.js +13 -0
- package/dashboard.js +18 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,28 @@ function renderProjects(projects) {
|
|
|
21
21
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function _projectCachePath(project) {
|
|
25
|
+
return String((project && (project.localPath || project.path)) || '').replace(/\\/g, '/');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function optimisticallyAddProject(project) {
|
|
29
|
+
if (!project || !project.name) return;
|
|
30
|
+
const next = {
|
|
31
|
+
name: project.name,
|
|
32
|
+
description: project.description || '',
|
|
33
|
+
localPath: _projectCachePath(project),
|
|
34
|
+
path: _projectCachePath(project),
|
|
35
|
+
};
|
|
36
|
+
if (!window._lastStatus) window._lastStatus = {};
|
|
37
|
+
const current = Array.isArray(window._lastStatus.projects) ? window._lastStatus.projects.slice() : [];
|
|
38
|
+
const nextPath = _projectCachePath(next);
|
|
39
|
+
if (current.some(function(p) { return p.name === next.name || (nextPath && _projectCachePath(p) === nextPath); })) return;
|
|
40
|
+
current.push(next);
|
|
41
|
+
window._lastStatus.projects = current;
|
|
42
|
+
if (typeof cmdUpdateProjectList === 'function') cmdUpdateProjectList(current);
|
|
43
|
+
renderProjects(current);
|
|
44
|
+
}
|
|
45
|
+
|
|
24
46
|
async function projectChipRemove(name) {
|
|
25
47
|
if (!confirm('Remove project "' + name + '"? Pending work cancels, active agents are killed, data dir is archived to projects/.archived/.')) return;
|
|
26
48
|
showToast('cmd-toast', 'Removing project "' + name + '"...', true);
|
|
@@ -385,7 +407,18 @@ async function _addSelectedProjects() {
|
|
|
385
407
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
386
408
|
body: JSON.stringify({ path: repo.path })
|
|
387
409
|
});
|
|
388
|
-
|
|
410
|
+
var data = await res.json().catch(function() { return {}; });
|
|
411
|
+
if (res.ok) {
|
|
412
|
+
added++;
|
|
413
|
+
optimisticallyAddProject({
|
|
414
|
+
name: data.name || repo.name,
|
|
415
|
+
description: (data.detected && data.detected.description) || repo.description || '',
|
|
416
|
+
path: data.path || repo.path,
|
|
417
|
+
localPath: data.path || repo.path,
|
|
418
|
+
});
|
|
419
|
+
cb.disabled = true;
|
|
420
|
+
cb.closest('label').style.opacity = '0.5';
|
|
421
|
+
}
|
|
389
422
|
} catch { /* continue with next */ }
|
|
390
423
|
}
|
|
391
424
|
if (added > 0) {
|
|
@@ -394,4 +427,4 @@ async function _addSelectedProjects() {
|
|
|
394
427
|
}
|
|
395
428
|
}
|
|
396
429
|
|
|
397
|
-
window.MinionsOther = { renderProjects, projectChipRemove, renderMcpServers, renderMetrics, renderLlmPerf, renderTokenUsage, openScanProjectsModal };
|
|
430
|
+
window.MinionsOther = { renderProjects, optimisticallyAddProject, projectChipRemove, renderMcpServers, renderMetrics, renderLlmPerf, renderTokenUsage, openScanProjectsModal };
|
package/dashboard/js/settings.js
CHANGED
|
@@ -384,6 +384,19 @@ async function addProject() {
|
|
|
384
384
|
});
|
|
385
385
|
const addData = await addRes.json();
|
|
386
386
|
if (!addRes.ok) { alert('Failed: ' + (addData.error || 'unknown')); return; }
|
|
387
|
+
const addedProject = {
|
|
388
|
+
name: addData.name,
|
|
389
|
+
description: (addData.detected && addData.detected.description) || '',
|
|
390
|
+
path: addData.path,
|
|
391
|
+
localPath: addData.path,
|
|
392
|
+
};
|
|
393
|
+
if (_settingsData && Array.isArray(_settingsData.projects)) {
|
|
394
|
+
const exists = _settingsData.projects.some(function(p) {
|
|
395
|
+
return p.name === addedProject.name || String(p.localPath || p.path || '').replace(/\\/g, '/') === String(addedProject.localPath || '').replace(/\\/g, '/');
|
|
396
|
+
});
|
|
397
|
+
if (!exists) _settingsData.projects = _settingsData.projects.concat([addedProject]);
|
|
398
|
+
}
|
|
399
|
+
if (typeof optimisticallyAddProject === 'function') optimisticallyAddProject(addedProject);
|
|
387
400
|
try { showToast('cmd-toast', 'Project "' + addData.name + '" added — restart engine to pick it up', true); } catch { /* expected */ }
|
|
388
401
|
refresh();
|
|
389
402
|
} catch (e) { alert('Error: ' + e.message); }
|
package/dashboard.js
CHANGED
|
@@ -3807,6 +3807,17 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3807
3807
|
return jsonReply(res, 200, { confirmToken: token, ttlMs: PROJECT_CONFIRM_TOKEN_TTL_MS });
|
|
3808
3808
|
}
|
|
3809
3809
|
|
|
3810
|
+
function _execGitInRepo(repoPath, args, timeoutMs) {
|
|
3811
|
+
const { execFileSync } = require('child_process');
|
|
3812
|
+
return execFileSync('git', args, {
|
|
3813
|
+
cwd: repoPath,
|
|
3814
|
+
encoding: 'utf8',
|
|
3815
|
+
timeout: timeoutMs || 5000,
|
|
3816
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
3817
|
+
windowsHide: true,
|
|
3818
|
+
}).trim();
|
|
3819
|
+
}
|
|
3820
|
+
|
|
3810
3821
|
async function handleProjectsAdd(req, res) {
|
|
3811
3822
|
try {
|
|
3812
3823
|
const body = await readBody(req);
|
|
@@ -3840,14 +3851,16 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3840
3851
|
}
|
|
3841
3852
|
|
|
3842
3853
|
// Auto-discover from git repo
|
|
3843
|
-
const { execSync: ex } = require('child_process');
|
|
3844
3854
|
const detected = { name: path.basename(target), _found: [] };
|
|
3845
3855
|
try {
|
|
3846
|
-
|
|
3856
|
+
let head = '';
|
|
3857
|
+
try { head = _execGitInRepo(target, ['symbolic-ref', 'refs/remotes/origin/HEAD'], 5000); }
|
|
3858
|
+
catch { head = _execGitInRepo(target, ['symbolic-ref', 'HEAD'], 5000); }
|
|
3859
|
+
if (!head) throw new Error('empty git ref');
|
|
3847
3860
|
detected.mainBranch = head.replace('refs/remotes/origin/', '').replace('refs/heads/', '');
|
|
3848
3861
|
} catch { detected.mainBranch = 'main'; }
|
|
3849
3862
|
try {
|
|
3850
|
-
const remoteUrl =
|
|
3863
|
+
const remoteUrl = _execGitInRepo(target, ['remote', 'get-url', 'origin'], 5000);
|
|
3851
3864
|
if (remoteUrl.includes('github.com')) {
|
|
3852
3865
|
detected.repoHost = 'github';
|
|
3853
3866
|
const m = remoteUrl.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
|
|
@@ -3906,6 +3919,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3906
3919
|
config.projects.push(project);
|
|
3907
3920
|
safeWrite(configPath, config);
|
|
3908
3921
|
reloadConfig(); // Update in-memory project list immediately
|
|
3922
|
+
invalidateStatusCache();
|
|
3909
3923
|
|
|
3910
3924
|
// Create project-local state files
|
|
3911
3925
|
const minionsDir = path.join(target, '.minions');
|
|
@@ -3969,7 +3983,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3969
3983
|
const results = repos.map(repoPath => {
|
|
3970
3984
|
const result = { path: repoPath.replace(/\\/g, '/'), name: path.basename(repoPath), host: 'git', linked: existingPaths.has(path.resolve(repoPath)) };
|
|
3971
3985
|
try {
|
|
3972
|
-
const remoteUrl =
|
|
3986
|
+
const remoteUrl = _execGitInRepo(repoPath, ['remote', 'get-url', 'origin'], 3000);
|
|
3973
3987
|
const gh = remoteUrl.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
|
|
3974
3988
|
const ado = remoteUrl.match(/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/\s]+)/) || remoteUrl.match(/([^.]+)\.visualstudio\.com.*?\/([^/]+)\/_git\/([^/\s]+)/);
|
|
3975
3989
|
if (gh) { result.host = 'GitHub'; result.org = gh[1]; result.name = gh[2]; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1568",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|