@yancyyu/openhermit 1.6.18 → 1.6.19

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 (2) hide show
  1. package/bin/hermit.mjs +64 -38
  2. package/package.json +1 -1
package/bin/hermit.mjs CHANGED
@@ -96,7 +96,7 @@ const ccConnectConfigPath =
96
96
  process.env.HERMIT_CC_CONNECT_CONFIG ||
97
97
  process.env.CC_CONNECT_CONFIG ||
98
98
  path.join(hermitHome, 'cc-connect', 'config.toml');
99
- const bootstrapProjectNames = new Set(['default', '__openhermit_bootstrap__']);
99
+ const starterProjectName = 'my-project';
100
100
 
101
101
  // ---------------------------------------------------------------------------
102
102
  // Update command
@@ -384,34 +384,11 @@ function isManagedBootstrapBlock(block) {
384
384
  );
385
385
  }
386
386
 
387
- function stripManagedBootstrapProjects(raw) {
388
- let next = raw;
389
- for (const name of bootstrapProjectNames) {
390
- const block = findProjectBlock(next, name);
391
- if (block && isManagedBootstrapBlock(block.match[0])) {
392
- next = next.replace(block.pattern, '').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
393
- }
394
- }
395
- return next;
396
- }
397
-
398
- function hasRealProjectEntries(raw) {
399
- const projectPattern = /\[\[projects\]\]\nname\s*=\s*"([^"]+)"[\s\S]*?(?=\n\[\[projects\]\]|\s*$)/g;
400
- for (const match of raw.matchAll(projectPattern)) {
401
- const name = match[1];
402
- if (!bootstrapProjectNames.has(name) || !isManagedBootstrapBlock(match[0])) {
403
- return true;
404
- }
405
- }
406
- return false;
407
- }
387
+ function buildStarterConfigToml(managementToken, bridgeToken) {
388
+ return `# cc-connect configuration
389
+ # Docs: https://github.com/chenhg5/cc-connect
408
390
 
409
- function ensureCcConnectConfig() {
410
- mkdirSync(path.dirname(ccConnectConfigPath), { recursive: true });
411
- if (!existsSync(ccConnectConfigPath)) {
412
- const managementToken = randomToken();
413
- const bridgeToken = randomToken();
414
- const config = `data_dir = "${escapeTomlPath(path.join(hermitHome, 'cc-connect', 'data'))}"
391
+ data_dir = "${escapeTomlPath(path.join(hermitHome, 'cc-connect', 'data'))}"
415
392
  language = "zh"
416
393
 
417
394
  [management]
@@ -429,17 +406,62 @@ path = "/bridge/ws"
429
406
 
430
407
  [log]
431
408
  level = "info"
409
+
410
+ [[projects]]
411
+ name = "my-project"
412
+
413
+ [projects.agent]
414
+ type = "claudecode" # "claudecode", "codex", "cursor", "gemini", "qoder", "opencode", or "iflow"
415
+
416
+ [projects.agent.options]
417
+ work_dir = "/path/to/your/project"
418
+ mode = "default"
419
+ # model = "claude-sonnet-4-20250514"
420
+
421
+ # --- Choose at least one platform below ---
422
+
423
+ [[projects.platforms]]
424
+ type = "feishu"
425
+
426
+ [projects.platforms.options]
427
+ app_id = "your-feishu-app-id"
428
+ app_secret = "your-feishu-app-secret"
432
429
  `;
433
- writeFileSync(ccConnectConfigPath, config, 'utf-8');
430
+ }
431
+
432
+ function isStarterProjectConfig(raw) {
433
+ const block = findProjectBlock(raw, starterProjectName);
434
+ if (!block) return false;
435
+ const text = block.match[0];
436
+ return (
437
+ text.includes('name = "my-project"') &&
438
+ text.includes('type = "claudecode"') &&
439
+ text.includes('work_dir = "/path/to/your/project"') &&
440
+ text.includes('app_id = "your-feishu-app-id"') &&
441
+ text.includes('app_secret = "your-feishu-app-secret"')
442
+ );
443
+ }
444
+
445
+ function hasRunnableProjectEntries(raw) {
446
+ const projectPattern = /\[\[projects\]\]\nname\s*=\s*"([^"]+)"[\s\S]*?(?=\n\[\[projects\]\]|\s*$)/g;
447
+ for (const match of raw.matchAll(projectPattern)) {
448
+ if (!isStarterProjectConfig(match[0]) && !isManagedBootstrapBlock(match[0])) {
449
+ return true;
450
+ }
434
451
  }
452
+ return false;
453
+ }
435
454
 
436
- let raw = readFileSync(ccConnectConfigPath, 'utf-8');
437
- const migrated = stripManagedBootstrapProjects(raw);
438
- if (migrated !== raw) {
439
- raw = migrated;
440
- writeFileSync(ccConnectConfigPath, raw, 'utf-8');
455
+ function ensureCcConnectConfig() {
456
+ mkdirSync(path.dirname(ccConnectConfigPath), { recursive: true });
457
+ if (!existsSync(ccConnectConfigPath)) {
458
+ const managementToken = randomToken();
459
+ const bridgeToken = randomToken();
460
+ writeFileSync(ccConnectConfigPath, buildStarterConfigToml(managementToken, bridgeToken), 'utf-8');
441
461
  }
442
462
 
463
+ const raw = readFileSync(ccConnectConfigPath, 'utf-8');
464
+
443
465
  return {
444
466
  managementToken:
445
467
  process.env.CC_CONNECT_TOKEN ||
@@ -449,7 +471,8 @@ level = "info"
449
471
  process.env.CC_CONNECT_BRIDGE_TOKEN ||
450
472
  process.env.CC_CONNECT_TOKEN ||
451
473
  parseTomlToken(raw, 'bridge'),
452
- hasRealProjects: hasRealProjectEntries(raw),
474
+ hasRunnableProjects: hasRunnableProjectEntries(raw),
475
+ isStarterConfig: isStarterProjectConfig(raw),
453
476
  };
454
477
  }
455
478
 
@@ -543,9 +566,12 @@ if (!skipCcConnect) {
543
566
  const alreadyRunning = await waitForCcConnect(ccBaseUrl, ccTokens.managementToken, 1_000);
544
567
  if (alreadyRunning) {
545
568
  console.log(`[openHermit] Runtime service already running: ${ccBaseUrl}`);
546
- } else if (!ccTokens.hasRealProjects) {
547
- console.log('[openHermit] No runtime projects configured; starting control panel only.');
548
- console.log('[openHermit] Create a team in the UI to install/configure a runtime.');
569
+ } else if (!ccTokens.hasRunnableProjects) {
570
+ console.log('[openHermit] Runtime config is a starter template; starting control panel only.');
571
+ console.log(`[openHermit] Edit runtime config in the UI before starting the runtime service.`);
572
+ if (ccTokens.isStarterConfig) {
573
+ console.log(`[openHermit] Starter config: ${ccConnectConfigPath}`);
574
+ }
549
575
  } else {
550
576
  console.log('[openHermit] Starting bundled runtime service...');
551
577
  console.log(`[openHermit] Runtime config: ${ccConnectConfigPath}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yancyyu/openhermit",
3
3
  "type": "module",
4
- "version": "1.6.18",
4
+ "version": "1.6.19",
5
5
  "description": "openHermit: team-oriented agent management workbench atop cc-connect.",
6
6
  "license": "AGPL-3.0",
7
7
  "author": {