botmux 3.12.0 → 3.12.1
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/.runtime-build-id +1 -1
- package/dist/adapters/backend/riff-backend.d.ts +18 -0
- package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
- package/dist/adapters/backend/riff-backend.js +143 -0
- package/dist/adapters/backend/riff-backend.js.map +1 -1
- package/dist/adapters/cli/kimi.d.ts.map +1 -1
- package/dist/adapters/cli/kimi.js +22 -8
- package/dist/adapters/cli/kimi.js.map +1 -1
- package/dist/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +3 -1
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +4 -1
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +65 -27
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +16 -2
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.js +1 -1
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +17 -1
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +13 -1
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +5 -0
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/skills/cli-admin-command.d.ts.map +1 -1
- package/dist/core/skills/cli-admin-command.js +142 -3
- package/dist/core/skills/cli-admin-command.js.map +1 -1
- package/dist/core/skills/frontmatter.d.ts.map +1 -1
- package/dist/core/skills/frontmatter.js +44 -7
- package/dist/core/skills/frontmatter.js.map +1 -1
- package/dist/core/skills/im-command.d.ts +6 -0
- package/dist/core/skills/im-command.d.ts.map +1 -1
- package/dist/core/skills/im-command.js +34 -7
- package/dist/core/skills/im-command.js.map +1 -1
- package/dist/core/skills/install-command.d.ts +4 -0
- package/dist/core/skills/install-command.d.ts.map +1 -0
- package/dist/core/skills/install-command.js +89 -0
- package/dist/core/skills/install-command.js.map +1 -0
- package/dist/core/skills/package.d.ts.map +1 -1
- package/dist/core/skills/package.js +10 -3
- package/dist/core/skills/package.js.map +1 -1
- package/dist/core/skills/policy.d.ts +5 -1
- package/dist/core/skills/policy.d.ts.map +1 -1
- package/dist/core/skills/policy.js +66 -3
- package/dist/core/skills/policy.js.map +1 -1
- package/dist/core/skills/references.d.ts +9 -1
- package/dist/core/skills/references.d.ts.map +1 -1
- package/dist/core/skills/references.js +35 -2
- package/dist/core/skills/references.js.map +1 -1
- package/dist/core/skills/registry-paths.d.ts +1 -0
- package/dist/core/skills/registry-paths.d.ts.map +1 -1
- package/dist/core/skills/registry-paths.js +3 -0
- package/dist/core/skills/registry-paths.js.map +1 -1
- package/dist/core/skills/session-resolver.d.ts +2 -1
- package/dist/core/skills/session-resolver.d.ts.map +1 -1
- package/dist/core/skills/session-resolver.js +1 -0
- package/dist/core/skills/session-resolver.js.map +1 -1
- package/dist/core/skills/session-runtime.d.ts.map +1 -1
- package/dist/core/skills/session-runtime.js +2 -0
- package/dist/core/skills/session-runtime.js.map +1 -1
- package/dist/core/skills/sources.d.ts +23 -0
- package/dist/core/skills/sources.d.ts.map +1 -1
- package/dist/core/skills/sources.js +128 -12
- package/dist/core/skills/sources.js.map +1 -1
- package/dist/core/skills/types.d.ts +22 -1
- package/dist/core/skills/types.d.ts.map +1 -1
- package/dist/core/types.d.ts +2 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +52 -1
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +2 -114
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts.map +1 -1
- package/dist/dashboard/connector-api.js +66 -6
- package/dist/dashboard/connector-api.js.map +1 -1
- package/dist/dashboard/public-redact.d.ts.map +1 -1
- package/dist/dashboard/public-redact.js +3 -0
- package/dist/dashboard/public-redact.js.map +1 -1
- package/dist/dashboard/skill-install-request.js +10 -11
- package/dist/dashboard/skill-install-request.js.map +1 -1
- package/dist/dashboard/skill-pack-response.d.ts +15 -0
- package/dist/dashboard/skill-pack-response.d.ts.map +1 -0
- package/dist/dashboard/skill-pack-response.js +32 -0
- package/dist/dashboard/skill-pack-response.js.map +1 -0
- package/dist/dashboard/web/connectors-page.d.ts +69 -0
- package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
- package/dist/dashboard/web/connectors-page.js +47 -7
- package/dist/dashboard/web/connectors-page.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +301 -26
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +4 -2
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +14 -6
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +99 -3
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +3 -1
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +13 -6
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/skills/bot-assignments-tab.d.ts +27 -0
- package/dist/dashboard/web/skills/bot-assignments-tab.d.ts.map +1 -0
- package/dist/dashboard/web/skills/bot-assignments-tab.js +257 -0
- package/dist/dashboard/web/skills/bot-assignments-tab.js.map +1 -0
- package/dist/dashboard/web/skills/delivery-settings-tab.d.ts +25 -0
- package/dist/dashboard/web/skills/delivery-settings-tab.d.ts.map +1 -0
- package/dist/dashboard/web/skills/delivery-settings-tab.js +20 -0
- package/dist/dashboard/web/skills/delivery-settings-tab.js.map +1 -0
- package/dist/dashboard/web/skills/shared.d.ts +86 -0
- package/dist/dashboard/web/skills/shared.d.ts.map +1 -0
- package/dist/dashboard/web/skills/shared.js +178 -0
- package/dist/dashboard/web/skills/shared.js.map +1 -0
- package/dist/dashboard/web/skills/skill-library-tab.d.ts +75 -0
- package/dist/dashboard/web/skills/skill-library-tab.d.ts.map +1 -0
- package/dist/dashboard/web/skills/skill-library-tab.js +108 -0
- package/dist/dashboard/web/skills/skill-library-tab.js.map +1 -0
- package/dist/dashboard/web/skills/skill-packs-tab.d.ts +21 -0
- package/dist/dashboard/web/skills/skill-packs-tab.d.ts.map +1 -0
- package/dist/dashboard/web/skills/skill-packs-tab.js +185 -0
- package/dist/dashboard/web/skills/skill-packs-tab.js.map +1 -0
- package/dist/dashboard/web/skills/types.d.ts +95 -0
- package/dist/dashboard/web/skills/types.d.ts.map +1 -0
- package/dist/dashboard/web/skills/types.js +2 -0
- package/dist/dashboard/web/skills/types.js.map +1 -0
- package/dist/dashboard/web/skills/use-skills-data.d.ts +31 -0
- package/dist/dashboard/web/skills/use-skills-data.d.ts.map +1 -0
- package/dist/dashboard/web/skills/use-skills-data.js +86 -0
- package/dist/dashboard/web/skills/use-skills-data.js.map +1 -0
- package/dist/dashboard/web/skills-page.d.ts +34 -31
- package/dist/dashboard/web/skills-page.d.ts.map +1 -1
- package/dist/dashboard/web/skills-page.js +321 -176
- package/dist/dashboard/web/skills-page.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts +18 -0
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +35 -1
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-USC6EZXP.js → bot-defaults-page-HL655CNR.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-KOPISPHN.js → chunk-5PAYQ3KT.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-RXRJB5SO.js → chunk-5ZL7NLR5.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-A7VC4BXR.js → chunk-BFUTTYVK.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-ELL53D62.js +55 -0
- package/dist/dashboard-web/chunks/connectors-page-3QQACF23.js +1 -0
- package/dist/dashboard-web/chunks/{groups-page-C6NSDTIN.js → groups-page-SDZMJ7UV.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-UTOVYLLY.js → insights-page-ZZ3JEJ6L.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-UKTJYTA2.js → monitor-room-ROJ5GZ4N.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-Q3CEZIVX.js → monitoring-page-IATV7KJF.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-GYCZOOVJ.js → office-page-TYO5OIIT.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-W2VBJ6OH.js → overview-page-VJUULZF2.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-U4SHER4K.js → roles-page-7RJJKZGK.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-TNPW3N3Q.js → schedules-page-JTEJ5IXW.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-KD7HDT3U.js +8 -0
- package/dist/dashboard-web/chunks/{settings-page-VKW5ZK5K.js → settings-page-7CTTFBRS.js} +1 -1
- package/dist/dashboard-web/chunks/skills-page-57NZECJ3.js +4 -0
- package/dist/dashboard-web/chunks/{team-federation-page-OMFGGBT2.js → team-federation-page-6YYIMJG3.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-PLXWK4KO.js → v3-page-ZGKBSBK3.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-NJQOEO2P.js → whiteboards-page-AACJF6DB.js} +1 -1
- package/dist/dashboard-web/style.css +1623 -160
- package/dist/dashboard.js +200 -16
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +2 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/index-daemon.js +6 -1
- package/dist/index-daemon.js.map +1 -1
- package/dist/services/connector-store.d.ts +14 -1
- package/dist/services/connector-store.d.ts.map +1 -1
- package/dist/services/connector-store.js.map +1 -1
- package/dist/services/connector-topic-template.d.ts +7 -0
- package/dist/services/connector-topic-template.d.ts.map +1 -0
- package/dist/services/connector-topic-template.js +210 -0
- package/dist/services/connector-topic-template.js.map +1 -0
- package/dist/services/project-scanner.d.ts +33 -0
- package/dist/services/project-scanner.d.ts.map +1 -1
- package/dist/services/project-scanner.js +40 -1
- package/dist/services/project-scanner.js.map +1 -1
- package/dist/services/skill-pack-store.d.ts +50 -0
- package/dist/services/skill-pack-store.d.ts.map +1 -0
- package/dist/services/skill-pack-store.js +270 -0
- package/dist/services/skill-pack-store.js.map +1 -0
- package/dist/services/skill-registry-store.d.ts +8 -0
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +100 -68
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/todo-state.d.ts +74 -0
- package/dist/services/todo-state.d.ts.map +1 -0
- package/dist/services/todo-state.js +351 -0
- package/dist/services/todo-state.js.map +1 -0
- package/dist/setup/agent-preset.d.ts.map +1 -1
- package/dist/setup/agent-preset.js +2 -0
- package/dist/setup/agent-preset.js.map +1 -1
- package/dist/setup/owner-identity.d.ts +47 -0
- package/dist/setup/owner-identity.d.ts.map +1 -0
- package/dist/setup/owner-identity.js +196 -0
- package/dist/setup/owner-identity.js.map +1 -0
- package/dist/setup/register-app.d.ts +4 -3
- package/dist/setup/register-app.d.ts.map +1 -1
- package/dist/setup/register-app.js.map +1 -1
- package/dist/setup/setup-args.d.ts +1 -1
- package/dist/setup/setup-args.d.ts.map +1 -1
- package/dist/setup/setup-args.js +7 -3
- package/dist/setup/setup-args.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +25 -0
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +47 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/worker.js +55 -16
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +44 -44
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/chunk-M6BHWQFO.js +0 -51
- package/dist/dashboard-web/chunks/connectors-page-4Z76HWRH.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-YWWDDV57.js +0 -6
- package/dist/dashboard-web/chunks/skills-page-ZCEDFGZZ.js +0 -4
package/dist/dashboard.js
CHANGED
|
@@ -62,14 +62,17 @@ import { listTeamReports, readTeamBoard, setTeamBoardEntry } from './services/te
|
|
|
62
62
|
import { createCliAdapterSync } from './adapters/cli/registry.js';
|
|
63
63
|
import { hd2dAssetPath, hd2dStatus, startHd2dDownload } from './dashboard/hd2d-assets.js';
|
|
64
64
|
import { buildSkillInstallAuditSummary, installLocalSkillLinks, readSkillRegistry, removeInstalledSkill, removeInstalledSkills, updateInstalledSkillAsync, } from './services/skill-registry-store.js';
|
|
65
|
+
import { readSkillPackRegistry } from './services/skill-pack-store.js';
|
|
66
|
+
import { cloneSkillPack, createSkillPack, deleteSkillPack, getSkillPack, listSkillPacks, updateSkillPack, SkillPackStoreError, } from './services/skill-pack-store.js';
|
|
65
67
|
import { redactGitUrlCredentials } from './core/skills/sources.js';
|
|
68
|
+
import { enrichPackForDashboard, enrichPacksForDashboard, sanitizeSkillForDashboard, } from './dashboard/skill-pack-response.js';
|
|
66
69
|
import { effectiveDefaultWorkingDir, getBot, loadBotConfigs, parseBotConfigsFromText } from './bot-registry.js';
|
|
67
70
|
import { addChatToFeedGroup, createFeedGroup, FEED_GROUP_SCOPES, FeedGroupApiError, listFeedGroups } from './dashboard/feed-groups.js';
|
|
68
71
|
import { generateAuthUrl, handleCallbackUrl, isCallbackUrl } from './utils/user-token.js';
|
|
69
72
|
import { findEntryIndex, readRawConfig, requireConfigPath, writeRawConfigAtomic } from './services/config-store.js';
|
|
70
73
|
import { emitCodexNotifierOutboxItem, installCodexNotifierHook, isCodexNotifierWorkerStateFresh, isCodexNotifierHookInstalled, listCodexNotifierOutbox, readCodexNotifierWorkerState, resolveCodexNotifierConfig, runCodexSideConversationMonitor, runCodexNotifierWorkerSupervisor, } from './features/codex-notifier/index.js';
|
|
71
74
|
import { discoverNativeCliSkillGroups } from './core/skills/discovery.js';
|
|
72
|
-
import { analyzeSkillReferences } from './core/skills/references.js';
|
|
75
|
+
import { analyzeSkillReferences, packsContainingSkill } from './core/skills/references.js';
|
|
73
76
|
import { discoverDashboardSkills, installDashboardSkill, parseDashboardSkillInstallRequest, parseInstallLocalLinksSources, MAX_LOCAL_LINK_SOURCES } from './dashboard/skill-install-request.js';
|
|
74
77
|
import { botDefaultsPayload, botSummaryPayload, brandMapByAppId } from './dashboard/bot-payload.js';
|
|
75
78
|
import { handleVcMeetingConsumerProfilesGet, handleVcMeetingConsumerProfilesPut, } from './dashboard/vc-consumer-profiles-api.js';
|
|
@@ -106,6 +109,13 @@ import { inspectGatewayEntry } from './core/plugins/mcp/gateway-installer.js';
|
|
|
106
109
|
import { fetchDaemonIpc } from './core/daemon-ipc-auth.js';
|
|
107
110
|
import { buildDashboardSummary, parseDashboardSummaryRows, } from './dashboard/dashboard-summary.js';
|
|
108
111
|
import { createDashboardSummaryEndpoint } from './dashboard/dashboard-summary-endpoint.js';
|
|
112
|
+
import { scrubWorkflowWorkerEnv } from './utils/child-env.js';
|
|
113
|
+
// The dashboard is an independent long-lived PM2 app and can be resurrected
|
|
114
|
+
// from a stale dump.pm2 without passing through cli.ts pm2Env(). Its start/stop
|
|
115
|
+
// and detached-restart children inherit process.env, so a leaked workflow
|
|
116
|
+
// marker would make those CLI commands fail at the workflow safety gate before
|
|
117
|
+
// they can reach their own cleanup boundary.
|
|
118
|
+
scrubWorkflowWorkerEnv(process.env);
|
|
109
119
|
const SECRET_PATH = dashboardSecretPath();
|
|
110
120
|
const TOKEN_PATH = join(homedir(), '.botmux', '.dashboard-token');
|
|
111
121
|
/** Per-daemon budget for the cross-daemon insight overview fan-out — bounds
|
|
@@ -2303,16 +2313,13 @@ function startSkillJob(type, run) {
|
|
|
2303
2313
|
})());
|
|
2304
2314
|
return job;
|
|
2305
2315
|
}
|
|
2306
|
-
function sanitizeSkillForDashboard(skill) {
|
|
2307
|
-
if (skill.source.type !== 'git')
|
|
2308
|
-
return skill;
|
|
2309
|
-
return {
|
|
2310
|
-
...skill,
|
|
2311
|
-
source: { ...skill.source, url: redactGitUrlCredentials(skill.source.url) },
|
|
2312
|
-
};
|
|
2313
|
-
}
|
|
2314
2316
|
function dashboardSkillCliIds() {
|
|
2315
2317
|
const ids = new Set();
|
|
2318
|
+
// Always scan all known CLI skill dirs, not just configured bots — users may
|
|
2319
|
+
// want to discover codex/trae/... skills even before creating a bot for them.
|
|
2320
|
+
const allCliIds = ['claude-code', 'seed', 'relay', 'aiden', 'coco', 'codex', 'codex-app', 'cursor', 'gemini', 'genius', 'opencode', 'antigravity', 'mtr', 'hermes', 'mira', 'mir', 'traex', 'pi', 'copilot', 'oh-my-pi', 'kimi', 'grok', 'kiro-cli', 'riff'];
|
|
2321
|
+
for (const cliId of allCliIds)
|
|
2322
|
+
ids.add(cliId);
|
|
2316
2323
|
try {
|
|
2317
2324
|
for (const cliId of configuredCliIds().values())
|
|
2318
2325
|
ids.add(cliId);
|
|
@@ -2342,6 +2349,76 @@ function dashboardSkillsPayload() {
|
|
|
2342
2349
|
delivery: globalSkills.delivery ?? 'auto',
|
|
2343
2350
|
};
|
|
2344
2351
|
}
|
|
2352
|
+
// --- Skill pack dashboard helpers ------------------------------------------
|
|
2353
|
+
function loadBotConfigsSafe() {
|
|
2354
|
+
try {
|
|
2355
|
+
return loadBotConfigs();
|
|
2356
|
+
}
|
|
2357
|
+
catch {
|
|
2358
|
+
return [];
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
function botsReferencingPack(packId, bots) {
|
|
2362
|
+
const selector = `pack:${packId}`;
|
|
2363
|
+
return bots
|
|
2364
|
+
.filter((bot) => Array.isArray(bot.skills?.include) && bot.skills.include.includes(selector))
|
|
2365
|
+
.map((bot) => ({ larkAppId: bot.larkAppId, botName: bot.name ?? bot.larkAppId }))
|
|
2366
|
+
.sort((a, b) => a.botName.localeCompare(b.botName));
|
|
2367
|
+
}
|
|
2368
|
+
function parsePackInput(body) {
|
|
2369
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
2370
|
+
throw new SkillPackStoreError({ code: 'SKILL_PACK_INVALID', reason: 'body must be an object' });
|
|
2371
|
+
const b = body;
|
|
2372
|
+
return {
|
|
2373
|
+
id: typeof b.id === 'string' ? b.id : '',
|
|
2374
|
+
name: typeof b.name === 'string' ? b.name : '',
|
|
2375
|
+
description: typeof b.description === 'string' ? b.description : undefined,
|
|
2376
|
+
tags: Array.isArray(b.tags) ? b.tags : undefined,
|
|
2377
|
+
include: Array.isArray(b.include) ? b.include : [],
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
function parsePackUpdate(body) {
|
|
2381
|
+
if (!body || typeof body !== 'object' || Array.isArray(body))
|
|
2382
|
+
throw new SkillPackStoreError({ code: 'SKILL_PACK_INVALID', reason: 'body must be an object' });
|
|
2383
|
+
const b = body;
|
|
2384
|
+
return {
|
|
2385
|
+
name: typeof b.name === 'string' ? b.name : undefined,
|
|
2386
|
+
description: b.description === null ? null : typeof b.description === 'string' ? b.description : undefined,
|
|
2387
|
+
tags: b.tags === null ? null : Array.isArray(b.tags) ? b.tags : undefined,
|
|
2388
|
+
include: Array.isArray(b.include) ? b.include : undefined,
|
|
2389
|
+
expectedRevision: typeof b.expectedRevision === 'number' ? b.expectedRevision : undefined,
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
function packErrorStatus(err) {
|
|
2393
|
+
if (err instanceof SkillPackStoreError) {
|
|
2394
|
+
switch (err.detail.code) {
|
|
2395
|
+
case 'SKILL_PACK_NOT_FOUND': return 404;
|
|
2396
|
+
case 'SKILL_PACK_ID_CONFLICT': return 409;
|
|
2397
|
+
case 'SKILL_PACK_REVISION_CONFLICT': return 409;
|
|
2398
|
+
case 'SKILL_PACK_IN_USE': return 409;
|
|
2399
|
+
default: return 400;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
return 400;
|
|
2403
|
+
}
|
|
2404
|
+
function packErrorBody(err) {
|
|
2405
|
+
if (err instanceof SkillPackStoreError) {
|
|
2406
|
+
const d = err.detail;
|
|
2407
|
+
const body = { ok: false, error: d.code };
|
|
2408
|
+
if (d.code === 'SKILL_PACK_REVISION_CONFLICT')
|
|
2409
|
+
body.current = d.current;
|
|
2410
|
+
if (d.code === 'SKILL_PACK_INVALID')
|
|
2411
|
+
body.reason = d.reason;
|
|
2412
|
+
if (d.code === 'SKILL_PACK_INVALID_SELECTOR')
|
|
2413
|
+
body.selector = d.selector;
|
|
2414
|
+
return body;
|
|
2415
|
+
}
|
|
2416
|
+
return {
|
|
2417
|
+
ok: false,
|
|
2418
|
+
error: 'internal_error',
|
|
2419
|
+
detail: redactGitUrlCredentials(err instanceof Error ? err.message : String(err)),
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2345
2422
|
function mergeSkillReferenceBot(refs, ref) {
|
|
2346
2423
|
const current = refs.get(ref.larkAppId);
|
|
2347
2424
|
if (!current) {
|
|
@@ -2353,11 +2430,18 @@ function mergeSkillReferenceBot(refs, ref) {
|
|
|
2353
2430
|
async function dashboardSkillReferencesMany(skillNames) {
|
|
2354
2431
|
const uniqueNames = [...new Set(skillNames)];
|
|
2355
2432
|
const refsBySkill = new Map(uniqueNames.map(name => [name, new Map()]));
|
|
2433
|
+
let packs;
|
|
2434
|
+
try {
|
|
2435
|
+
packs = readSkillPackRegistry().packs;
|
|
2436
|
+
}
|
|
2437
|
+
catch {
|
|
2438
|
+
// packs.json may be absent; fall back to direct-only analysis.
|
|
2439
|
+
}
|
|
2356
2440
|
try {
|
|
2357
2441
|
const configuredBots = loadBotConfigs();
|
|
2358
2442
|
for (const name of uniqueNames) {
|
|
2359
2443
|
const refs = refsBySkill.get(name);
|
|
2360
|
-
for (const ref of analyzeSkillReferences(name, { bots: configuredBots }).bots)
|
|
2444
|
+
for (const ref of analyzeSkillReferences(name, { bots: configuredBots, packs }).bots)
|
|
2361
2445
|
mergeSkillReferenceBot(refs, ref);
|
|
2362
2446
|
}
|
|
2363
2447
|
}
|
|
@@ -2383,15 +2467,16 @@ async function dashboardSkillReferencesMany(skillNames) {
|
|
|
2383
2467
|
const availableOnlineConfigs = onlineConfigs.filter(config => config !== null);
|
|
2384
2468
|
for (const name of uniqueNames) {
|
|
2385
2469
|
const refs = refsBySkill.get(name);
|
|
2386
|
-
for (const ref of analyzeSkillReferences(name, { bots: availableOnlineConfigs }).bots)
|
|
2470
|
+
for (const ref of analyzeSkillReferences(name, { bots: availableOnlineConfigs, packs }).bots)
|
|
2387
2471
|
mergeSkillReferenceBot(refs, ref);
|
|
2388
2472
|
}
|
|
2389
2473
|
return new Map([...refsBySkill].map(([name, refs]) => [name, {
|
|
2390
2474
|
bots: [...refs.values()].sort((a, b) => a.botName.localeCompare(b.botName)),
|
|
2475
|
+
packs: packsContainingSkill(name, packs),
|
|
2391
2476
|
}]));
|
|
2392
2477
|
}
|
|
2393
2478
|
async function dashboardSkillReferences(skillName) {
|
|
2394
|
-
return (await dashboardSkillReferencesMany([skillName])).get(skillName) ?? { bots: [] };
|
|
2479
|
+
return (await dashboardSkillReferencesMany([skillName])).get(skillName) ?? { bots: [], packs: [] };
|
|
2395
2480
|
}
|
|
2396
2481
|
/** Extract the sessionId from a terminal path `/s/<sessionId>[/...]`. Returns
|
|
2397
2482
|
* the first path segment after `/s/` (stops at the next `/`; query/hash are
|
|
@@ -3340,10 +3425,14 @@ const server = createServer(async (req, res) => {
|
|
|
3340
3425
|
if (missing.length > 0)
|
|
3341
3426
|
return jsonRes(res, 400, { ok: false, error: 'skill_not_installed', missing });
|
|
3342
3427
|
const referencesBySkill = await dashboardSkillReferencesMany(names);
|
|
3343
|
-
const references = names.map(name => ({ name, refs: referencesBySkill.get(name) ?? { bots: [] } }));
|
|
3428
|
+
const references = names.map(name => ({ name, refs: referencesBySkill.get(name) ?? { bots: [], packs: [] } }));
|
|
3344
3429
|
const affectedSkills = references
|
|
3345
|
-
.filter(item => item.refs.bots.length > 0)
|
|
3346
|
-
.map(item => ({
|
|
3430
|
+
.filter(item => item.refs.bots.length > 0 || item.refs.packs.length > 0)
|
|
3431
|
+
.map(item => ({
|
|
3432
|
+
name: item.name,
|
|
3433
|
+
affectedBots: item.refs.bots,
|
|
3434
|
+
affectedPacks: item.refs.packs,
|
|
3435
|
+
}));
|
|
3347
3436
|
if (body.force !== true && affectedSkills.length > 0) {
|
|
3348
3437
|
return jsonRes(res, 409, {
|
|
3349
3438
|
ok: false,
|
|
@@ -3474,11 +3563,12 @@ const server = createServer(async (req, res) => {
|
|
|
3474
3563
|
if (!readSkillRegistry().skills[name])
|
|
3475
3564
|
return jsonRes(res, 400, { ok: false, error: 'skill_not_installed' });
|
|
3476
3565
|
const refs = await dashboardSkillReferences(name);
|
|
3477
|
-
if (!force && refs.bots.length > 0) {
|
|
3566
|
+
if (!force && (refs.bots.length > 0 || refs.packs.length > 0)) {
|
|
3478
3567
|
return jsonRes(res, 409, {
|
|
3479
3568
|
ok: false,
|
|
3480
3569
|
error: 'skill_in_use',
|
|
3481
3570
|
affectedBots: refs.bots,
|
|
3571
|
+
affectedPacks: refs.packs,
|
|
3482
3572
|
});
|
|
3483
3573
|
}
|
|
3484
3574
|
const r = removeInstalledSkill(name);
|
|
@@ -3487,9 +3577,103 @@ const server = createServer(async (req, res) => {
|
|
|
3487
3577
|
return jsonRes(res, 200, {
|
|
3488
3578
|
ok: true,
|
|
3489
3579
|
affectedBots: refs.bots,
|
|
3580
|
+
affectedPacks: refs.packs,
|
|
3490
3581
|
...dashboardSkillsPayload(),
|
|
3491
3582
|
});
|
|
3492
3583
|
}
|
|
3584
|
+
// --- Skill pack CRUD ---------------------------------------------------
|
|
3585
|
+
if (req.method === 'GET' && url.pathname === '/api/skill-packs') {
|
|
3586
|
+
const registrySkills = readSkillRegistry().skills;
|
|
3587
|
+
const bots = loadBotConfigsSafe();
|
|
3588
|
+
const packs = enrichPacksForDashboard(listSkillPacks(), registrySkills, (packId) => botsReferencingPack(packId, bots));
|
|
3589
|
+
return jsonRes(res, 200, { ok: true, packs });
|
|
3590
|
+
}
|
|
3591
|
+
if (req.method === 'POST' && url.pathname === '/api/skill-packs') {
|
|
3592
|
+
let body;
|
|
3593
|
+
try {
|
|
3594
|
+
body = await readJsonBody(req);
|
|
3595
|
+
}
|
|
3596
|
+
catch {
|
|
3597
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3598
|
+
}
|
|
3599
|
+
try {
|
|
3600
|
+
const input = parsePackInput(body);
|
|
3601
|
+
const pack = createSkillPack(input);
|
|
3602
|
+
return jsonRes(res, 201, { ok: true, pack });
|
|
3603
|
+
}
|
|
3604
|
+
catch (err) {
|
|
3605
|
+
return jsonRes(res, packErrorStatus(err), packErrorBody(err));
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
let mPack;
|
|
3609
|
+
if (req.method === 'GET' && (mPack = url.pathname.match(/^\/api\/skill-packs\/([^/]+)$/))) {
|
|
3610
|
+
const id = decodeURIComponent(mPack[1]);
|
|
3611
|
+
const pack = getSkillPack(id);
|
|
3612
|
+
if (!pack)
|
|
3613
|
+
return jsonRes(res, 404, { ok: false, error: 'SKILL_PACK_NOT_FOUND' });
|
|
3614
|
+
const registrySkills = readSkillRegistry().skills;
|
|
3615
|
+
const bots = loadBotConfigsSafe();
|
|
3616
|
+
return jsonRes(res, 200, {
|
|
3617
|
+
ok: true,
|
|
3618
|
+
pack: enrichPackForDashboard(pack, registrySkills, botsReferencingPack(pack.id, bots)),
|
|
3619
|
+
});
|
|
3620
|
+
}
|
|
3621
|
+
if (req.method === 'PUT' && (mPack = url.pathname.match(/^\/api\/skill-packs\/([^/]+)$/))) {
|
|
3622
|
+
const id = decodeURIComponent(mPack[1]);
|
|
3623
|
+
let body;
|
|
3624
|
+
try {
|
|
3625
|
+
body = await readJsonBody(req);
|
|
3626
|
+
}
|
|
3627
|
+
catch {
|
|
3628
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3629
|
+
}
|
|
3630
|
+
try {
|
|
3631
|
+
const input = parsePackUpdate(body);
|
|
3632
|
+
const pack = updateSkillPack(id, input);
|
|
3633
|
+
return jsonRes(res, 200, { ok: true, pack });
|
|
3634
|
+
}
|
|
3635
|
+
catch (err) {
|
|
3636
|
+
return jsonRes(res, packErrorStatus(err), packErrorBody(err));
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
if (req.method === 'DELETE' && (mPack = url.pathname.match(/^\/api\/skill-packs\/([^/]+)$/))) {
|
|
3640
|
+
const id = decodeURIComponent(mPack[1]);
|
|
3641
|
+
const force = url.searchParams.get('force') === '1';
|
|
3642
|
+
const pack = getSkillPack(id);
|
|
3643
|
+
if (!pack)
|
|
3644
|
+
return jsonRes(res, 404, { ok: false, error: 'SKILL_PACK_NOT_FOUND' });
|
|
3645
|
+
const refs = botsReferencingPack(id, loadBotConfigsSafe());
|
|
3646
|
+
if (!force && refs.length > 0) {
|
|
3647
|
+
return jsonRes(res, 409, { ok: false, error: 'SKILL_PACK_IN_USE', references: refs });
|
|
3648
|
+
}
|
|
3649
|
+
try {
|
|
3650
|
+
deleteSkillPack(id);
|
|
3651
|
+
return jsonRes(res, 200, { ok: true, references: refs });
|
|
3652
|
+
}
|
|
3653
|
+
catch (err) {
|
|
3654
|
+
return jsonRes(res, packErrorStatus(err), packErrorBody(err));
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
if (req.method === 'POST' && (mPack = url.pathname.match(/^\/api\/skill-packs\/([^/]+)\/clone$/))) {
|
|
3658
|
+
const id = decodeURIComponent(mPack[1]);
|
|
3659
|
+
let body;
|
|
3660
|
+
try {
|
|
3661
|
+
body = await readJsonBody(req);
|
|
3662
|
+
}
|
|
3663
|
+
catch {
|
|
3664
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3665
|
+
}
|
|
3666
|
+
const newId = typeof body?.id === 'string' ? body.id.trim() : '';
|
|
3667
|
+
if (!newId)
|
|
3668
|
+
return jsonRes(res, 400, { ok: false, error: 'id_required' });
|
|
3669
|
+
try {
|
|
3670
|
+
const pack = cloneSkillPack(id, newId);
|
|
3671
|
+
return jsonRes(res, 201, { ok: true, pack });
|
|
3672
|
+
}
|
|
3673
|
+
catch (err) {
|
|
3674
|
+
return jsonRes(res, packErrorStatus(err), packErrorBody(err));
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3493
3677
|
if (req.method === 'GET' && url.pathname === '/api/whiteboards') {
|
|
3494
3678
|
return jsonRes(res, 200, { enabled: whiteboardEnabled(), whiteboards: listWhiteboards() });
|
|
3495
3679
|
}
|