@axhub/genie 0.2.10 → 0.2.12

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 (96) hide show
  1. package/dist/api-docs.html +2 -2
  2. package/dist/assets/App-Clb2COtW.js +274 -0
  3. package/dist/assets/ImagePlaygroundPage-DqhMSbM8.js +106 -0
  4. package/dist/assets/ImagePlaygroundPage-MEn3NN80.css +1 -0
  5. package/dist/assets/ReviewApp-CDcLYe-u.js +1 -0
  6. package/dist/assets/{_basePickBy-DVVb07UV.js → _basePickBy-jUZsM51q.js} +1 -1
  7. package/dist/assets/{_baseUniq-BtbziL5G.js → _baseUniq-BXglE6_v.js} +1 -1
  8. package/dist/assets/{arc-BsCC8yBD.js → arc-D-oFCFBv.js} +1 -1
  9. package/dist/assets/{architectureDiagram-2XIMDMQ5-woFp6eNI.js → architectureDiagram-2XIMDMQ5-DC8bAnQt.js} +1 -1
  10. package/dist/assets/{blockDiagram-WCTKOSBZ-ya8VAc2k.js → blockDiagram-WCTKOSBZ-C4semIRc.js} +1 -1
  11. package/dist/assets/{c4Diagram-IC4MRINW-CY1dZmIZ.js → c4Diagram-IC4MRINW-FHj1QO3y.js} +1 -1
  12. package/dist/assets/channel-BF4woPXX.js +1 -0
  13. package/dist/assets/{chunk-4BX2VUAB-CR1lAd74.js → chunk-4BX2VUAB-D-LjsQ_s.js} +1 -1
  14. package/dist/assets/{chunk-55IACEB6-CP98WcFC.js → chunk-55IACEB6-DI3j_d7A.js} +1 -1
  15. package/dist/assets/{chunk-FMBD7UC4-D9c7ijAB.js → chunk-FMBD7UC4-BEVnaLFN.js} +1 -1
  16. package/dist/assets/{chunk-JSJVCQXG-DQAGYOn-.js → chunk-JSJVCQXG-CSxpcErk.js} +1 -1
  17. package/dist/assets/{chunk-KX2RTZJC-BbTXiDq7.js → chunk-KX2RTZJC-BbuhDN4h.js} +1 -1
  18. package/dist/assets/{chunk-NQ4KR5QH-BI6AX0dr.js → chunk-NQ4KR5QH-C3x61XQa.js} +1 -1
  19. package/dist/assets/{chunk-QZHKN3VN-DB3V2Ifo.js → chunk-QZHKN3VN-DxWOFtPh.js} +1 -1
  20. package/dist/assets/{chunk-WL4C6EOR-DhzTthv6.js → chunk-WL4C6EOR-Bt2OauD2.js} +1 -1
  21. package/dist/assets/classDiagram-VBA2DB6C-D2kHlnQ7.js +1 -0
  22. package/dist/assets/classDiagram-v2-RAHNMMFH-D2kHlnQ7.js +1 -0
  23. package/dist/assets/clone-CqBvwCJW.js +1 -0
  24. package/dist/assets/{cose-bilkent-S5V4N54A-BQ09ZE2j.js → cose-bilkent-S5V4N54A-Dexadrue.js} +1 -1
  25. package/dist/assets/{dagre-KLK3FWXG-Dc2ueD_R.js → dagre-KLK3FWXG-F9U4X2xC.js} +1 -1
  26. package/dist/assets/{diagram-E7M64L7V-DP-LsQoL.js → diagram-E7M64L7V-B3V17aH3.js} +1 -1
  27. package/dist/assets/{diagram-IFDJBPK2-Cg6r42cB.js → diagram-IFDJBPK2-CdHAmLL1.js} +1 -1
  28. package/dist/assets/{diagram-P4PSJMXO-aHsfoUZE.js → diagram-P4PSJMXO-CrTNfk8K.js} +1 -1
  29. package/dist/assets/{erDiagram-INFDFZHY-qBXJ4aAz.js → erDiagram-INFDFZHY-vDh9SWK9.js} +1 -1
  30. package/dist/assets/{flowDiagram-PKNHOUZH-D_13emJM.js → flowDiagram-PKNHOUZH-DpltMg7L.js} +1 -1
  31. package/dist/assets/{ganttDiagram-A5KZAMGK-BvIcOLwz.js → ganttDiagram-A5KZAMGK-COTk2xur.js} +1 -1
  32. package/dist/assets/{gitGraphDiagram-K3NZZRJ6-ad0vvNcU.js → gitGraphDiagram-K3NZZRJ6-BNV7bvvj.js} +1 -1
  33. package/dist/assets/{graph-CeJCMjan.js → graph-Dkeg9oys.js} +1 -1
  34. package/dist/assets/{highlighted-body-TPN3WLV5-B_novwSz.js → highlighted-body-TPN3WLV5-DaiQEBwR.js} +1 -1
  35. package/dist/assets/index-DgGmiqsP.css +1 -0
  36. package/dist/assets/index-DvA901Vs.js +2 -0
  37. package/dist/assets/{infoDiagram-LFFYTUFH-lOxAqb3m.js → infoDiagram-LFFYTUFH-CZioW3Gt.js} +1 -1
  38. package/dist/assets/{ishikawaDiagram-PHBUUO56-DIr-51gj.js → ishikawaDiagram-PHBUUO56-BbqR3i1B.js} +1 -1
  39. package/dist/assets/{journeyDiagram-4ABVD52K-CYcIW0ZU.js → journeyDiagram-4ABVD52K-wfb-WHzl.js} +1 -1
  40. package/dist/assets/{kanban-definition-K7BYSVSG-C1ZK616a.js → kanban-definition-K7BYSVSG-B3c4y3VN.js} +1 -1
  41. package/dist/assets/{layout-CI2RM-v6.js → layout-Xr9Z2VGF.js} +1 -1
  42. package/dist/assets/{linear-DE7bISck.js → linear-JBmzAJtl.js} +1 -1
  43. package/dist/assets/{mermaid-O7DHMXV3-XxAJo8EK.js → mermaid-O7DHMXV3-fDuyNLKe.js} +238 -220
  44. package/dist/assets/{mindmap-definition-YRQLILUH-Dz6EFjmn.js → mindmap-definition-YRQLILUH-B5NTN_jD.js} +1 -1
  45. package/dist/assets/{pieDiagram-SKSYHLDU-DPpEzUed.js → pieDiagram-SKSYHLDU-CuO98GVu.js} +1 -1
  46. package/dist/assets/{quadrantDiagram-337W2JSQ-xdoXNet7.js → quadrantDiagram-337W2JSQ-LL3f4vLf.js} +1 -1
  47. package/dist/assets/{requirementDiagram-Z7DCOOCP-DUq8H3CL.js → requirementDiagram-Z7DCOOCP-Di-2O6LH.js} +1 -1
  48. package/dist/assets/{sankeyDiagram-WA2Y5GQK-CmqEUxRu.js → sankeyDiagram-WA2Y5GQK-9lHqrXqR.js} +1 -1
  49. package/dist/assets/{sequenceDiagram-2WXFIKYE-DhtXRNiH.js → sequenceDiagram-2WXFIKYE-BQu-SoGr.js} +1 -1
  50. package/dist/assets/{stateDiagram-RAJIS63D-Dj0HOlbN.js → stateDiagram-RAJIS63D-BUxvd2BC.js} +1 -1
  51. package/dist/assets/stateDiagram-v2-FVOUBMTO-CDVexTiR.js +1 -0
  52. package/dist/assets/{timeline-definition-YZTLITO2-DUuJzZB5.js → timeline-definition-YZTLITO2-oP47UEU6.js} +1 -1
  53. package/dist/assets/{treemap-KZPCXAKY-DpYBQ0qr.js → treemap-KZPCXAKY-BRjDo2aE.js} +1 -1
  54. package/dist/assets/{vendor-codemirror-CMHSJ_9p.js → vendor-codemirror-BiCeS-y4.js} +1 -1
  55. package/dist/assets/{vendor-react-xmA_f8ig.js → vendor-react-DVlYPmi3.js} +1 -1
  56. package/dist/assets/{vennDiagram-LZ73GAT5-DpePUyOd.js → vennDiagram-LZ73GAT5-DrRqcDqo.js} +1 -1
  57. package/dist/assets/{xychartDiagram-JWTSCODW-Cfp1I4_U.js → xychartDiagram-JWTSCODW-DUXrymAi.js} +1 -1
  58. package/dist/index.html +4 -4
  59. package/package.json +25 -6
  60. package/scripts/refresh-acp-default-capabilities.mjs +160 -0
  61. package/server/acp-runtime/client.js +1137 -181
  62. package/server/acp-runtime/command-overrides.js +48 -0
  63. package/server/acp-runtime/index.js +576 -16
  64. package/server/acp-runtime/registry.js +6 -4
  65. package/server/acp-runtime/session-store.js +235 -92
  66. package/server/database/db.js +12 -3
  67. package/server/external-agent/ws.js +212 -11
  68. package/server/index.js +156 -53
  69. package/server/projects-watcher-config.js +4 -0
  70. package/server/projects.js +485 -125
  71. package/server/routes/cc-connect.js +5 -4
  72. package/server/routes/codex.js +24 -0
  73. package/server/routes/commands.js +166 -10
  74. package/server/routes/runs.js +641 -0
  75. package/server/routes/session-core.js +357 -109
  76. package/server/session-core/eventStore.js +0 -121
  77. package/server/session-core/providerAdapters.js +644 -163
  78. package/server/session-core/providerDiscovery.js +66 -38
  79. package/server/session-core/runRegistry.js +244 -0
  80. package/server/session-core/runtimeState.js +75 -3
  81. package/server/session-core/runtimeWriter.js +132 -10
  82. package/server/utils/codexImagePlayground.js +479 -0
  83. package/server/utils/localTerminal.js +56 -0
  84. package/server/utils/shellCommand.js +70 -0
  85. package/shared/acpCapabilities.js +393 -0
  86. package/shared/acpDefaultCapabilities.generated.json +141 -0
  87. package/shared/conversationEvents.js +425 -121
  88. package/dist/assets/App-CYCCsgwf.js +0 -264
  89. package/dist/assets/ReviewApp-0srHIXwb.js +0 -1
  90. package/dist/assets/channel-BMhScXFe.js +0 -1
  91. package/dist/assets/classDiagram-VBA2DB6C-CMIxlWcT.js +0 -1
  92. package/dist/assets/classDiagram-v2-RAHNMMFH-CMIxlWcT.js +0 -1
  93. package/dist/assets/clone-BPqOt4r3.js +0 -1
  94. package/dist/assets/index-C514cLyb.js +0 -2
  95. package/dist/assets/index-h1DBl_g3.css +0 -1
  96. package/dist/assets/stateDiagram-v2-FVOUBMTO-C9utf5gv.js +0 -1
@@ -27,6 +27,7 @@ import {
27
27
  const router = express.Router();
28
28
 
29
29
  const CC_CONNECT_COMMAND = 'cc-connect';
30
+ const CC_CONNECT_NPM_PACKAGE = 'cc-connect@latest';
30
31
  const COMMAND_TIMEOUT_MS = 5000;
31
32
  const INSTALL_TIMEOUT_MS = 120000;
32
33
  const DAEMON_COMMAND_TIMEOUT_MS = 20000;
@@ -772,17 +773,17 @@ router.get('/platforms', async (req, res) => {
772
773
  router.post('/install', async (req, res) => {
773
774
  try {
774
775
  const existing = await getCcConnectStatus();
775
- if (existing.installed && existing.isBeta) {
776
+ if (existing.installed && !existing.isBeta) {
776
777
  return res.json({
777
778
  success: true,
778
779
  version: existing.version,
779
- message: 'cc-connect@beta is already installed.'
780
+ message: 'cc-connect is already installed.'
780
781
  });
781
782
  }
782
783
 
783
784
  const result = runCommandSync({
784
785
  command: getNpmCommand(),
785
- args: ['install', '-g', 'cc-connect@beta'],
786
+ args: ['install', '-g', CC_CONNECT_NPM_PACKAGE],
786
787
  timeoutMs: INSTALL_TIMEOUT_MS,
787
788
  env: buildCommandEnv()
788
789
  });
@@ -798,7 +799,7 @@ router.post('/install', async (req, res) => {
798
799
  return res.json({
799
800
  success: true,
800
801
  version: installed.version,
801
- message: 'cc-connect@beta installed successfully.'
802
+ message: 'cc-connect installed successfully.'
802
803
  });
803
804
  } catch (error) {
804
805
  return res.status(500).json({ success: false, error: error.message });
@@ -8,6 +8,10 @@ import {
8
8
  getCodexSessionMessages,
9
9
  getCodexSessions
10
10
  } from '../projects.js';
11
+ import {
12
+ buildCodexImagePlaygroundLaunch,
13
+ resolveCodexImagePlaygroundConfig
14
+ } from '../utils/codexImagePlayground.js';
11
15
 
12
16
  const router = express.Router();
13
17
  const CODEX_CONFIG_PATH = path.join(os.homedir(), '.codex', 'config.toml');
@@ -66,6 +70,26 @@ router.get('/config', async (_req, res) => {
66
70
  }
67
71
  });
68
72
 
73
+ router.get('/image-playground/launch', async (req, res) => {
74
+ try {
75
+ const projectPath = typeof req.query.projectPath === 'string' && req.query.projectPath.trim()
76
+ ? req.query.projectPath.trim()
77
+ : null;
78
+ const config = await resolveCodexImagePlaygroundConfig({ projectPath });
79
+ const routePath = typeof req.query.routePath === 'string' && req.query.routePath.trim()
80
+ ? req.query.routePath.trim()
81
+ : '/image-playground';
82
+
83
+ res.json({
84
+ success: true,
85
+ launch: buildCodexImagePlaygroundLaunch({ routePath, config })
86
+ });
87
+ } catch (error) {
88
+ console.error('Error building Codex image playground launch:', error);
89
+ res.status(500).json({ success: false, error: error.message });
90
+ }
91
+ });
92
+
69
93
  router.get('/sessions', async (req, res) => {
70
94
  const projectPath = String(req.query.projectPath || '').trim();
71
95
 
@@ -4,6 +4,7 @@ import os from 'os';
4
4
  import path from 'path';
5
5
  import { fileURLToPath } from 'url';
6
6
  import matter from 'gray-matter';
7
+ import { spawnCommand } from '../utils/spawnCommand.js';
7
8
  import {
8
9
  CLAUDE_MODELS,
9
10
  CODEX_MODELS,
@@ -17,15 +18,16 @@ const __filename = fileURLToPath(import.meta.url);
17
18
  const __dirname = path.dirname(__filename);
18
19
  const PACKAGE_JSON_PATH = path.join(__dirname, '..', '..', 'package.json');
19
20
 
20
- const BUILTIN_COMMANDS = [
21
- { name: '/help', description: 'Show the built-in and custom slash commands available here.' },
22
- { name: '/clear', description: 'Clear the current in-memory conversation preview.' },
23
- { name: '/model', description: 'Show the active model and available provider model lists.' },
24
- { name: '/memory', description: 'Open the project-level CLAUDE.md memory file.' },
25
- { name: '/config', description: 'Open the local settings modal.' },
26
- { name: '/status', description: 'Show runtime metadata for the local Genie server.' },
27
- { name: '/rewind', description: 'Drop the last N user/assistant turns from the current chat.' }
28
- ];
21
+ const BUILTIN_COMMANDS = [];
22
+ const DISABLED_BUILTIN_COMMANDS = new Set([
23
+ '/help',
24
+ '/clear',
25
+ '/model',
26
+ '/memory',
27
+ '/config',
28
+ '/status',
29
+ '/rewind',
30
+ ]);
29
31
 
30
32
  const FALLBACK_PROVIDER_MODELS = {
31
33
  claude: CLAUDE_MODELS.OPTIONS.map((option) => option.value),
@@ -34,6 +36,15 @@ const FALLBACK_PROVIDER_MODELS = {
34
36
  opencode: OPENCODE_MODELS.OPTIONS.map((option) => option.value)
35
37
  };
36
38
 
39
+ const SKILLS_LIST_TIMEOUT_MS = 5000;
40
+ const PROVIDER_AGENT_NAMES = {
41
+ claude: 'Claude Code',
42
+ codex: 'Codex',
43
+ openai: 'Codex',
44
+ gemini: 'Gemini',
45
+ opencode: 'OpenCode'
46
+ };
47
+
37
48
  function trimText(value) {
38
49
  return typeof value === 'string' ? value.trim() : '';
39
50
  }
@@ -79,6 +90,136 @@ function inferDescription(frontmatter, markdownBody) {
79
90
  return firstMeaningfulLine.replace(/^#+\s*/, '').trim() || 'Custom slash command';
80
91
  }
81
92
 
93
+ function providerAgentName(provider) {
94
+ return PROVIDER_AGENT_NAMES[trimText(provider).toLowerCase()] || '';
95
+ }
96
+
97
+ function normalizeSlashName(value) {
98
+ const normalized = trimText(value);
99
+ if (!normalized) return '';
100
+ return normalized.startsWith('/') ? normalized : `/${normalized}`;
101
+ }
102
+
103
+ async function inferSkillDescription(skillPath) {
104
+ const normalizedPath = trimText(skillPath);
105
+ if (!normalizedPath) {
106
+ return 'Project skill';
107
+ }
108
+
109
+ try {
110
+ const rawDocument = await fs.readFile(path.join(normalizedPath, 'SKILL.md'), 'utf8');
111
+ const parsedDocument = matter(rawDocument);
112
+ const explicit = trimText(parsedDocument.data?.description);
113
+ if (explicit) {
114
+ return explicit;
115
+ }
116
+
117
+ const firstMeaningfulLine = parsedDocument.content
118
+ .split('\n')
119
+ .map((line) => line.trim())
120
+ .find((line) => line && !line.startsWith('---'));
121
+
122
+ return firstMeaningfulLine?.replace(/^#+\s*/, '').trim() || 'Project skill';
123
+ } catch {
124
+ return 'Project skill';
125
+ }
126
+ }
127
+
128
+ function parseSkillsListOutput(stdout) {
129
+ if (!trimText(stdout)) {
130
+ return [];
131
+ }
132
+
133
+ const parsed = JSON.parse(stdout);
134
+ return Array.isArray(parsed) ? parsed : [];
135
+ }
136
+
137
+ async function runProjectSkillsList(projectPath) {
138
+ return new Promise((resolve) => {
139
+ const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
140
+ let stdout = '';
141
+ let stderr = '';
142
+ let settled = false;
143
+ const child = spawnCommand(command, ['skills', 'ls', '--json'], {
144
+ cwd: projectPath,
145
+ env: {
146
+ ...process.env,
147
+ DISABLE_TELEMETRY: process.env.DISABLE_TELEMETRY ?? '1'
148
+ },
149
+ stdio: ['ignore', 'pipe', 'pipe']
150
+ });
151
+
152
+ const finish = (value) => {
153
+ if (settled) return;
154
+ settled = true;
155
+ clearTimeout(timer);
156
+ resolve(value);
157
+ };
158
+
159
+ const timer = setTimeout(() => {
160
+ child.kill?.();
161
+ finish([]);
162
+ }, SKILLS_LIST_TIMEOUT_MS);
163
+
164
+ child.stdout?.setEncoding?.('utf8');
165
+ child.stderr?.setEncoding?.('utf8');
166
+ child.stdout?.on('data', (chunk) => {
167
+ stdout += chunk;
168
+ });
169
+ child.stderr?.on('data', (chunk) => {
170
+ stderr += chunk;
171
+ });
172
+ child.on('error', () => finish([]));
173
+ child.on('close', (code) => {
174
+ if (code !== 0) {
175
+ finish([]);
176
+ return;
177
+ }
178
+
179
+ try {
180
+ finish(parseSkillsListOutput(stdout));
181
+ } catch {
182
+ finish([]);
183
+ }
184
+ });
185
+ });
186
+ }
187
+
188
+ async function listProjectSkills(projectPath, provider) {
189
+ const normalizedProjectPath = trimText(projectPath);
190
+ const targetAgent = providerAgentName(provider);
191
+ if (!normalizedProjectPath || !targetAgent) {
192
+ return [];
193
+ }
194
+
195
+ const rawSkills = await runProjectSkillsList(normalizedProjectPath);
196
+ const normalizedSkills = [];
197
+
198
+ for (const skill of rawSkills) {
199
+ if (!skill || typeof skill !== 'object') continue;
200
+
201
+ const name = normalizeSlashName(skill.name);
202
+ const agents = Array.isArray(skill.agents)
203
+ ? skill.agents.map((agent) => trimText(agent)).filter(Boolean)
204
+ : [];
205
+ if (!name || !agents.includes(targetAgent)) continue;
206
+
207
+ const skillPath = trimText(skill.path);
208
+ normalizedSkills.push({
209
+ name,
210
+ path: skillPath,
211
+ scope: trimText(skill.scope) || 'project',
212
+ agents,
213
+ namespace: 'skill',
214
+ type: 'skill',
215
+ source: 'skill',
216
+ description: await inferSkillDescription(skillPath)
217
+ });
218
+ }
219
+
220
+ return normalizedSkills.sort((left, right) => left.name.localeCompare(right.name));
221
+ }
222
+
82
223
  async function walkCommandTree(rootPath, namespace) {
83
224
  const collected = [];
84
225
 
@@ -216,6 +357,10 @@ async function buildModelPayload(context) {
216
357
  }
217
358
 
218
359
  async function runBuiltinCommand(commandName, args, context) {
360
+ if (BUILTIN_COMMANDS.length === 0) {
361
+ return null;
362
+ }
363
+
219
364
  switch (commandName) {
220
365
  case '/help':
221
366
  return {
@@ -340,9 +485,11 @@ async function runBuiltinCommand(commandName, args, context) {
340
485
  router.post('/list', async (req, res) => {
341
486
  try {
342
487
  const projectPath = trimText(req.body?.projectPath);
488
+ const provider = trimText(req.body?.provider);
343
489
  const builtin = BUILTIN_COMMANDS.map(toBuiltinRecord);
344
490
  const discoveredRoots = commandRootsFor(projectPath);
345
491
  const custom = [];
492
+ const skills = await listProjectSkills(projectPath, provider);
346
493
 
347
494
  for (const root of discoveredRoots) {
348
495
  custom.push(...await walkCommandTree(root.rootPath, root.namespace));
@@ -350,8 +497,9 @@ router.post('/list', async (req, res) => {
350
497
 
351
498
  res.json({
352
499
  builtIn: builtin,
500
+ skills,
353
501
  custom,
354
- count: builtin.length + custom.length
502
+ count: builtin.length + skills.length + custom.length
355
503
  });
356
504
  } catch (error) {
357
505
  console.error('Error listing commands:', error);
@@ -402,6 +550,14 @@ router.post('/execute', async (req, res) => {
402
550
  });
403
551
  }
404
552
 
553
+ if (DISABLED_BUILTIN_COMMANDS.has(commandName)) {
554
+ return res.status(404).json({
555
+ error: 'Command not found',
556
+ message: `${commandName} is currently disabled`,
557
+ command: commandName
558
+ });
559
+ }
560
+
405
561
  try {
406
562
  const builtinResult = await runBuiltinCommand(commandName, args, context);
407
563
  if (builtinResult) {