@ian2018cs/agenthub 0.1.96 → 0.1.98

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/dist/index.html CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  <!-- Prevent zoom on iOS -->
27
27
  <meta name="format-detection" content="telephone=no" />
28
- <script type="module" crossorigin src="/assets/index-iWtHvEkb.js"></script>
28
+ <script type="module" crossorigin src="/assets/index-CW6M7hpM.js"></script>
29
29
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-C_uEg43g.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-B2saKA4-.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/vendor-utils-00TdZexr.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ian2018cs/agenthub",
3
- "version": "0.1.96",
3
+ "version": "0.1.98",
4
4
  "description": "A web-based UI for AI Agents",
5
5
  "type": "module",
6
6
  "main": "server/index.js",
@@ -51,7 +51,7 @@
51
51
  "access": "public"
52
52
  },
53
53
  "dependencies": {
54
- "@anthropic-ai/claude-agent-sdk": "^0.2.80",
54
+ "@anthropic-ai/claude-agent-sdk": "^0.2.85",
55
55
  "@codemirror/lang-css": "^6.3.1",
56
56
  "@codemirror/lang-html": "^6.4.9",
57
57
  "@codemirror/lang-javascript": "^6.2.4",
@@ -266,6 +266,14 @@ async function getProjects(userUuid) {
266
266
  const projects = [];
267
267
  const existingProjects = new Set();
268
268
 
269
+ // Build a reverse map: originalPath → config entry, for merging agentInfo into CLI-scanned projects
270
+ const pathToConfigEntry = {};
271
+ for (const [, entry] of Object.entries(config)) {
272
+ if (entry.originalPath) {
273
+ pathToConfigEntry[entry.originalPath] = entry;
274
+ }
275
+ }
276
+
269
277
  try {
270
278
  // Check if the .claude/projects directory exists
271
279
  await fs.access(claudeDir);
@@ -282,7 +290,8 @@ async function getProjects(userUuid) {
282
290
  const actualProjectDir = await extractProjectDirectory(entry.name, userUuid);
283
291
 
284
292
  // Get display name from config or generate one
285
- const customName = config[entry.name]?.displayName;
293
+ const manualEntry = pathToConfigEntry[actualProjectDir];
294
+ const customName = config[entry.name]?.displayName || manualEntry?.displayName;
286
295
  const autoDisplayName = await generateDisplayName(entry.name, actualProjectDir);
287
296
  const fullPath = actualProjectDir;
288
297
 
@@ -293,7 +302,7 @@ async function getProjects(userUuid) {
293
302
  fullPath: fullPath,
294
303
  isCustomName: !!customName,
295
304
  sessions: [],
296
- ...(config[entry.name]?.agentInfo ? { agentInfo: config[entry.name].agentInfo } : {})
305
+ ...(config[entry.name]?.agentInfo ? { agentInfo: config[entry.name].agentInfo } : (manualEntry?.agentInfo ? { agentInfo: manualEntry.agentInfo } : {}))
297
306
  };
298
307
 
299
308
  // Try to get sessions for this project (just first 5 for performance)
@@ -8,7 +8,7 @@ import { getUserPaths, getPublicPaths } from '../services/user-directories.js';
8
8
  import { scanAgents, ensureAgentRepo, incrementPatchVersion, publishAgentToRepo } from '../services/system-agent-repo.js';
9
9
  import { ensureSystemRepo, SYSTEM_REPO_URL } from '../services/system-repo.js';
10
10
  import { ensureSystemMcpRepo, SYSTEM_MCP_REPO_URL } from '../services/system-mcp-repo.js';
11
- import { addProjectManually, loadProjectConfig, saveProjectConfig } from '../projects.js';
11
+ import { addProjectManually, loadProjectConfig, saveProjectConfig, extractProjectDirectory } from '../projects.js';
12
12
  import { agentSubmissionDb, userDb } from '../database/db.js';
13
13
  import { chatCompletion } from '../services/llm.js';
14
14
 
@@ -1064,9 +1064,21 @@ router.get('/preview', async (req, res) => {
1064
1064
 
1065
1065
  const config = await loadProjectConfig(userUuid);
1066
1066
  const entry = config[projectKey];
1067
- if (!entry) return res.status(404).json({ error: 'Project not found' });
1068
1067
 
1069
- const projectPath = entry.originalPath || projectKey.replace(/-/g, '/');
1068
+ let projectPath;
1069
+ if (entry?.originalPath) {
1070
+ projectPath = entry.originalPath;
1071
+ } else if (entry) {
1072
+ projectPath = projectKey.replace(/-/g, '/');
1073
+ } else {
1074
+ // Project may be a Claude CLI-scanned project not in manual config — try session scanning
1075
+ try {
1076
+ projectPath = await extractProjectDirectory(projectKey, userUuid);
1077
+ } catch {
1078
+ return res.status(404).json({ error: 'Project not found' });
1079
+ }
1080
+ }
1081
+
1070
1082
  const userPaths = getUserPaths(userUuid);
1071
1083
 
1072
1084
  // Check CLAUDE.md
@@ -1325,8 +1337,18 @@ router.post('/submit', async (req, res) => {
1325
1337
  // Resolve project path from config
1326
1338
  const config = await loadProjectConfig(userUuid);
1327
1339
  const entry = config[projectKey];
1328
- if (!entry) return res.status(404).json({ error: 'Project not found' });
1329
- const projectPath = entry.originalPath || projectKey.replace(/-/g, '/');
1340
+ let projectPath;
1341
+ if (entry?.originalPath) {
1342
+ projectPath = entry.originalPath;
1343
+ } else if (entry) {
1344
+ projectPath = projectKey.replace(/-/g, '/');
1345
+ } else {
1346
+ try {
1347
+ projectPath = await extractProjectDirectory(projectKey, userUuid);
1348
+ } catch {
1349
+ return res.status(404).json({ error: 'Project not found' });
1350
+ }
1351
+ }
1330
1352
 
1331
1353
  // Build ZIP: agent.yaml + CLAUDE.md (if exists)
1332
1354
  const zip = new AdmZip();
@@ -2042,11 +2064,29 @@ router.post('/submissions/:id/approve', async (req, res) => {
2042
2064
  if (submitterUser?.uuid) {
2043
2065
  const config = await loadProjectConfig(submitterUser.uuid);
2044
2066
  let updated = false;
2045
- for (const [, entry] of Object.entries(config)) {
2067
+ for (const [key, entry] of Object.entries(config)) {
2046
2068
  if (entry.agentInfo?.isAgent && entry.agentInfo.agentName === submission.agent_name) {
2069
+ // Already marked as agent install — just update version
2047
2070
  entry.agentInfo.installedVersion = newVersion;
2048
2071
  entry.agentInfo.installedAt = new Date().toISOString();
2049
2072
  updated = true;
2073
+ } else {
2074
+ // Check if this is the submitter's original project (same directory name, not yet marked as agent)
2075
+ const projectPath = entry.originalPath || key.replace(/-/g, '/');
2076
+ if (path.basename(projectPath) === submission.agent_name && !entry.agentInfo?.isAgent) {
2077
+ entry.agentInfo = {
2078
+ agentName: submission.agent_name,
2079
+ isAgent: true,
2080
+ installedVersion: newVersion,
2081
+ installedAt: new Date().toISOString(),
2082
+ claudeMdHash: '',
2083
+ installedFiles: [],
2084
+ installedSkills: [],
2085
+ installedMcps: [],
2086
+ gitRepos: [],
2087
+ };
2088
+ updated = true;
2089
+ }
2050
2090
  }
2051
2091
  }
2052
2092
  if (updated) {