@xopcai/xopc 0.0.172 → 0.0.174
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-C3Y-bESI.js → activity-store-CyEDJeIt.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CPyev9P7.js → agent-avatar-dicebear-DF7Bol6I.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BVxEFPQ5.js +2 -0
- package/dist/gateway/static/root/assets/{api-B7qEr_Rw.js → api-DYunqroX.js} +1 -1
- package/dist/gateway/static/root/assets/api-DwyUxpgY.js +1 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Br_9-7fs.js → app-management-settings-panel-B4xJyvDu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-uyLcRPai.js → appearance-settings-B2PQxRiu.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BtIgd82S.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-B19REnR5.js → archive-plugin-DWhBmmjD.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DLWCC4Yi.js → attachment-load-BOpZfa_I.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-ky5S5lly.js → automation-suggestion-card-Byu3I7Rs.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-CG_SCH5b.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CtPEzLlo.js → binary-plugins-6AG1qatz.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CQVR4Xij.js → block-editor-CJhrn98_.js} +5 -5
- package/dist/gateway/static/root/assets/browser-settings-page-CfLqPWZC.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CimCGbhq.js → browser-workflow-inputs-CBVb4mt9.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DewuCw3p.js → browser-workflows-page-Cq4XUKbu.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DCJmm6cR.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-B5RTs-Az.js → capability-presets-api-hbW4NAKO.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CnkAYvWI.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-Czu0YzIZ.js → channel-recipient-api-CzMjHb17.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DtqqFpDn.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-C-5yHbc0.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-Di3gnR_D.js → connector-logo-B9Au6gMZ.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CaHfs8YF.js +2 -0
- package/dist/gateway/static/root/assets/copy-VueTIC2x.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-CvFMKYdb.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-C3L6AI8_.js → desktop-pet-settings-CNff5TFb.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Dvq4iG6P.js → directory-picker-path-field-Bf956uo-.js} +1 -1
- package/dist/gateway/static/root/assets/dreaming-settings-CHM8FE1g.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BecQjU0J.js → extension-debug-page-ZqM_0eUs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BeVkPSm-.js → extension-page-D4hvXOMM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DMoo2mKx.js → extension-settings-page-GsqxaJjA.js} +1 -1
- package/dist/gateway/static/root/assets/focus-detail-page-CE6uwrl1.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-Bthb3_6v.js → gateway-config-api-B4THmgnS.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-Bh8nPvJQ.js → gateway-settings-CPv-MxGE.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-D3USVm9D.js → gateway-startup-retry-MP3K71pP.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-DAeb82xP.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-CwLSp01r.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-C_2QWBtb.js → goals-config-api-DCcDuIjG.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-DvJQ6_4M.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DhL643tc.js → goals-settings-o9QMXvNq.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-COVFwp7C.js → heartbeat-settings-DixwpXnH.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-BNQlnwpU.js → image-generation-api-BOGH9FGi.js} +1 -1
- package/dist/gateway/static/root/assets/index-CfXiRNN5.css +1 -0
- package/dist/gateway/static/root/assets/index-eyttVNS_.js +212 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DfdJRJVy.js → keyboard-shortcuts-settings-D4o4ZPF6.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CPcfqn_A.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-BvCPOgoi.js → local-apps-page-GzMmpO7G.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-BP0vD37A.js → locale-store-CAuhEGCn.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DXABWCZp.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-YO1rDk9m.js → markdown-split-CIX8D1pv.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CU_RRf-q.js → media-plugins-Bp3eIA45.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BiBdO1-O.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-CeFiOK3S.js → notes-page-RVFiYAoO.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DgJzZRX3.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-tiHmRJUA.js → page-tabs-BGAYH3Ef.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CU6XgaCz.js → preview-open-alternatives-BM6pDkHp.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-Dn4_qor4.js → product-open-page-BiMetEmn.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DF7F70Vg.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Cw3jyi5s.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-ChAJsaNY.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-edDUIbXo.js → save-bar-controls-BdjV8MK5.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DqJO_5Yb.js → schedule-field-ChlqXU46.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CMh0jzy5.js → schema-form-DDKf5ZSH.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BxZIxt7z.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DcDLS0xV.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Bb0Bc3nJ.js → settings-form-section-CPG0KGVs.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DQhADvz1.js → settings-loading-skeleton-DRSDHucM.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-b0M5HukN.js → settings-page-CeB7_xD0.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-hvjtIjvh.js → settings-page-layout-BENrkwd0.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-4Xa9NA7v.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-rbeaOpTg.js → share-preview-page-DIzczJkG.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BpN0o5Cf.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DvF2UAaL.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-CGKXpNfy.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BHo_hgnL.js → system-settings-panel-Dp4d5Q1B.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-C3KnnjcU.js → theme-store-CbGc1laW.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-D-G-uwVJ.js → time-picker-BhgCeDuO.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-DtRnG-YI.js → typed-models-lib-DwPk3OPL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CWWItX2g.js → use-channel-catalog-CXrEu2dw.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-Dy_fKAK_.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-BTnltQHZ.js → voice-api-key-field-DFoA79LB.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BWkjb1NK.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DLBNFse5.js +1 -0
- package/dist/gateway/static/root/assets/work-page-Bn5RXMIE.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D7vKChFZ.js → workflow-run-setup-panel-BuniGPO0.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-_vFhRrAl.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +3 -1
- package/dist/src/agent/agent-manager.js +4 -3
- package/dist/src/agent/capabilities/definitions.d.ts +2 -1
- package/dist/src/agent/capabilities/definitions.js +3 -1
- package/dist/src/agent/prompt/sections/tooling.js +4 -0
- package/dist/src/agent/service.d.ts +2 -1
- package/dist/src/agent/service.js +26 -0
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/install-target.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.d.ts +64 -0
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +27 -18
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
- package/dist/src/agent/skills/marketplace/search.d.ts +46 -0
- package/dist/src/agent/skills/marketplace/search.js +193 -0
- package/dist/src/agent/skills/skill-tool-gating.js +2 -1
- package/dist/src/agent/tools/delegate-tool.js +2 -0
- package/dist/src/agent/tools/factory.d.ts +4 -2
- package/dist/src/agent/tools/factory.js +11 -5
- package/dist/src/agent/tools/index.d.ts +2 -1
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/skill-install-tool.d.ts +17 -0
- package/dist/src/agent/tools/skill-install-tool.js +76 -8
- package/dist/src/agent/tools/skills-marketplace-search-tool.d.ts +17 -0
- package/dist/src/agent/tools/skills-marketplace-search-tool.js +77 -0
- package/dist/src/browser/providers/cloakbrowser.js +1 -1
- package/dist/src/capabilities/store-connector.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/extensions/api.js +1 -1
- package/dist/src/extensions/install.js +1 -1
- package/dist/src/focuses/candidate-repository.d.ts +15 -0
- package/dist/src/focuses/candidate-repository.js +91 -0
- package/dist/src/focuses/index.d.ts +7 -0
- package/dist/src/focuses/index.js +7 -0
- package/dist/src/focuses/insight-repository.d.ts +22 -0
- package/dist/src/focuses/insight-repository.js +77 -0
- package/dist/src/focuses/prompts.d.ts +2 -0
- package/dist/src/focuses/prompts.js +18 -0
- package/dist/src/focuses/reconciler.d.ts +5 -0
- package/dist/src/focuses/reconciler.js +26 -0
- package/dist/src/focuses/repository.d.ts +61 -0
- package/dist/src/focuses/repository.js +214 -0
- package/dist/src/focuses/run-processor.d.ts +18 -0
- package/dist/src/focuses/run-processor.js +162 -0
- package/dist/src/focuses/service.d.ts +42 -0
- package/dist/src/focuses/service.js +241 -0
- package/dist/src/focuses/types.d.ts +89 -0
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +2 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +2 -2
- package/dist/src/gateway/hono/routes/focuses.d.ts +3 -0
- package/dist/src/gateway/hono/routes/focuses.js +319 -0
- package/dist/src/gateway/hono/routes/home.js +15 -17
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/projects.js +2 -103
- package/dist/src/gateway/hono/routes/work-discovery.js +0 -239
- package/dist/src/gateway/service/marketplace-service.js +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +15 -11
- package/dist/src/storage/sqlite/migrations/066_first_class_focuses.sql +126 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/work-discovery/index.d.ts +0 -2
- package/dist/src/work-discovery/index.js +1 -3
- package/dist/src/work-discovery/service.d.ts +0 -30
- package/dist/src/work-discovery/service.js +1 -35
- package/dist/src/work-discovery/thread-service.d.ts +5 -0
- package/dist/src/work-discovery/thread-service.js +36 -88
- package/package.json +1 -1
- package/skills/tools/find-skills/SKILL.md +18 -428
- package/dist/gateway/static/root/assets/agents-Bf_kK2Ay.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DXFCP5-1.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-D8pT1o2O.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Bav_skKN.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BHaYYo9E.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BgchTh81.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BP0e62wt.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-DBWKfeGe.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CC5kh0de.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-D-ZUNHhn.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-D9i54kWO.js +0 -3
- package/dist/gateway/static/root/assets/goal-create-dialog-Dp0AyDHI.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CNt7nrdS.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-Bm_NZFiZ.js +0 -2
- package/dist/gateway/static/root/assets/index-C_XSKOH6.css +0 -1
- package/dist/gateway/static/root/assets/index-DUasAutC.js +0 -212
- package/dist/gateway/static/root/assets/local-app-workbench-page-DZwkD1co.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-dNL0Y1dA.js +0 -7
- package/dist/gateway/static/root/assets/messages-BWtP5TFz.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-B8MKxpZb.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-CWBuuX-S.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BJSsLsXH.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DXJDb8vB.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DeHpWgxM.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cf-TEYUd.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BFyfed_g.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CYnH9sTt.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Cr8_m-jS.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Chtc1xDO.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-D7qMR26X.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-CpqFZze9.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-t4dXpGC0.js +0 -1
- package/dist/gateway/static/root/assets/work-page-BXwDKiMZ.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Bos9HyqT.js +0 -11
- package/dist/src/proactive/calendar-signals.d.ts +0 -4
- package/dist/src/proactive/calendar-signals.js +0 -120
- package/dist/src/proactive/focus-service.d.ts +0 -62
- package/dist/src/proactive/focus-service.js +0 -173
- package/dist/src/proactive/index.d.ts +0 -7
- package/dist/src/proactive/index.js +0 -7
- package/dist/src/proactive/insight-repository.d.ts +0 -21
- package/dist/src/proactive/insight-repository.js +0 -109
- package/dist/src/proactive/run-processor.d.ts +0 -19
- package/dist/src/proactive/run-processor.js +0 -146
- package/dist/src/proactive/trial-expiry-reconciler.d.ts +0 -5
- package/dist/src/proactive/trial-expiry-reconciler.js +0 -30
- package/dist/src/proactive/types.d.ts +0 -66
- package/dist/src/proactive/value-score.d.ts +0 -13
- package/dist/src/proactive/value-score.js +0 -30
- package/dist/src/proactive/watch-repository.d.ts +0 -28
- package/dist/src/proactive/watch-repository.js +0 -129
- package/dist/src/work-discovery/governance.d.ts +0 -25
- package/dist/src/work-discovery/governance.js +0 -96
- package/dist/src/work-discovery/thread-repository.d.ts +0 -34
- package/dist/src/work-discovery/thread-repository.js +0 -112
- /package/dist/src/{proactive → focuses}/types.js +0 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { searchClawHubFederatedSkills } from "./adapters/clawhub/adapter.js";
|
|
2
|
+
import { listMarketplacePackages } from "../skills-marketplace.js";
|
|
3
|
+
//#region src/agent/skills/marketplace/search.ts
|
|
4
|
+
const SKILL_MARKETPLACE_SEARCH_SOURCES = [
|
|
5
|
+
"store",
|
|
6
|
+
"clawhub",
|
|
7
|
+
"skills-sh"
|
|
8
|
+
];
|
|
9
|
+
function boundedNumber(value) {
|
|
10
|
+
const parsed = Number(value);
|
|
11
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
12
|
+
}
|
|
13
|
+
function normalizeDate(value) {
|
|
14
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
15
|
+
const numeric = typeof value === "number" ? value : typeof value === "string" && /^\d+(?:\.\d+)?$/.test(value.trim()) ? Number(value) : null;
|
|
16
|
+
const timestamp = numeric !== null && Number.isFinite(numeric) ? Math.abs(numeric) < 0xe8d4a51000 ? numeric * 1e3 : numeric : value;
|
|
17
|
+
const date = new Date(timestamp);
|
|
18
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
19
|
+
}
|
|
20
|
+
function scannerStatus(value) {
|
|
21
|
+
const normalized = String(value ?? "").trim().toLowerCase();
|
|
22
|
+
if (normalized === "pass") return "pass";
|
|
23
|
+
if (normalized === "warn" || normalized === "warning" || normalized === "review") return "warn";
|
|
24
|
+
if (normalized === "fail" || normalized === "failed" || normalized === "block") return "fail";
|
|
25
|
+
return "unknown";
|
|
26
|
+
}
|
|
27
|
+
function securityFromClawHub(item) {
|
|
28
|
+
const scanners = Object.entries(item.trust?.upstreamScanners ?? {}).map(([name, evidence]) => ({
|
|
29
|
+
name,
|
|
30
|
+
status: scannerStatus(evidence.status),
|
|
31
|
+
checkedAt: normalizeDate(evidence.sourceCheckedAt),
|
|
32
|
+
url: evidence.sourceUrl ?? null
|
|
33
|
+
}));
|
|
34
|
+
const statuses = scanners.map((scanner) => scanner.status);
|
|
35
|
+
return {
|
|
36
|
+
status: statuses.includes("fail") ? "fail" : statuses.includes("warn") ? "warn" : statuses.length > 0 && statuses.every((value) => value === "pass") ? "pass" : scannerStatus(item.trust?.clawHubVerdict),
|
|
37
|
+
scanners
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function absoluteClawHubUrl(value) {
|
|
41
|
+
if (!value) return null;
|
|
42
|
+
try {
|
|
43
|
+
const base = process.env.CLAWHUB_REGISTRY?.trim() || "https://clawhub.ai";
|
|
44
|
+
return new URL(value, base).toString();
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function relevanceScore(query, result) {
|
|
50
|
+
const terms = query.toLowerCase().split(/[^a-z0-9]+/).filter((term) => term.length > 1);
|
|
51
|
+
if (terms.length === 0) return 0;
|
|
52
|
+
const name = result.name.toLowerCase();
|
|
53
|
+
const description = result.description.toLowerCase();
|
|
54
|
+
const matched = terms.reduce((score, term) => {
|
|
55
|
+
if (name === term) return score + 3;
|
|
56
|
+
if (name.includes(term)) return score + 2;
|
|
57
|
+
if (description.includes(term)) return score + 1;
|
|
58
|
+
return score;
|
|
59
|
+
}, 0);
|
|
60
|
+
return Math.min(35, Math.round(matched / (terms.length * 3) * 35));
|
|
61
|
+
}
|
|
62
|
+
function valueScore(query, result) {
|
|
63
|
+
const relevance = relevanceScore(query, result);
|
|
64
|
+
const adoption = Math.min(30, Math.log10(result.downloads + 1) * 7);
|
|
65
|
+
const endorsement = Math.min(15, Math.log10(result.stars + 1) * 6);
|
|
66
|
+
const updatedMs = result.updatedAt ? Date.parse(result.updatedAt) : 0;
|
|
67
|
+
const ageDays = updatedMs > 0 ? (Date.now() - updatedMs) / 864e5 : Number.POSITIVE_INFINITY;
|
|
68
|
+
const freshness = ageDays <= 90 ? 15 : ageDays <= 365 ? 10 : ageDays <= 730 ? 5 : 0;
|
|
69
|
+
const provenance = result.canonicalUrl && result.install.reference ? 5 : 0;
|
|
70
|
+
const security = result.security.status === "pass" ? 5 : result.security.status === "warn" ? -20 : result.security.status === "fail" ? -100 : 0;
|
|
71
|
+
return Math.round((relevance + adoption + endorsement + freshness + provenance + security) * 10) / 10;
|
|
72
|
+
}
|
|
73
|
+
function fromClawHub(item) {
|
|
74
|
+
const source = item.source === "skills-sh" ? "skills-sh" : "clawhub";
|
|
75
|
+
const owner = item.publisher?.handle ?? item.sourceIdentity?.owner ?? item.owner?.handle ?? item.ownerHandle ?? source;
|
|
76
|
+
const reference = item.install?.reference ?? (source === "clawhub" && owner !== "clawhub" ? `${owner}/${item.slug}` : item.slug);
|
|
77
|
+
return {
|
|
78
|
+
id: item.id ?? `${source}:${reference}`,
|
|
79
|
+
provider: "clawhub",
|
|
80
|
+
source,
|
|
81
|
+
name: item.displayName || item.slug,
|
|
82
|
+
description: item.summary || "",
|
|
83
|
+
author: owner,
|
|
84
|
+
downloads: boundedNumber(item.downloads ?? item.native?.skill?.stats?.downloads),
|
|
85
|
+
stars: boundedNumber(item.native?.skill?.stats?.stars ?? item.metrics?.bookmarks),
|
|
86
|
+
updatedAt: normalizeDate(item.metrics?.updatedAt ?? item.updatedAt),
|
|
87
|
+
canonicalUrl: absoluteClawHubUrl(item.canonicalUrl ?? item.links?.canonical),
|
|
88
|
+
install: {
|
|
89
|
+
kind: item.install?.kind ?? source,
|
|
90
|
+
reference,
|
|
91
|
+
sourceUrl: item.install?.sourceUrl ?? item.links?.source ?? null
|
|
92
|
+
},
|
|
93
|
+
security: securityFromClawHub(item),
|
|
94
|
+
valueScore: 0
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function dedupeAndRank(query, rows) {
|
|
98
|
+
const unique = /* @__PURE__ */ new Map();
|
|
99
|
+
for (const row of rows) {
|
|
100
|
+
const key = `${row.source}:${row.install.reference || row.id}`.toLowerCase();
|
|
101
|
+
const scored = {
|
|
102
|
+
...row,
|
|
103
|
+
valueScore: valueScore(query, row)
|
|
104
|
+
};
|
|
105
|
+
const current = unique.get(key);
|
|
106
|
+
if (!current || scored.valueScore > current.valueScore) unique.set(key, scored);
|
|
107
|
+
}
|
|
108
|
+
return [...unique.values()].sort((a, b) => b.valueScore - a.valueScore || b.downloads - a.downloads || a.name.localeCompare(b.name));
|
|
109
|
+
}
|
|
110
|
+
async function searchSkillMarketplaces(params) {
|
|
111
|
+
const requested = new Set(params.sources?.length ? params.sources : SKILL_MARKETPLACE_SEARCH_SOURCES);
|
|
112
|
+
const fetchLimit = Math.min(100, Math.max(params.limit ?? 10, 20));
|
|
113
|
+
const rows = [];
|
|
114
|
+
const statuses = [];
|
|
115
|
+
const jobs = [];
|
|
116
|
+
if (requested.has("store")) jobs.push((async () => {
|
|
117
|
+
try {
|
|
118
|
+
const response = await listMarketplacePackages(params.config, {
|
|
119
|
+
q: params.query,
|
|
120
|
+
page: 1,
|
|
121
|
+
pageSize: fetchLimit,
|
|
122
|
+
sort: "downloads"
|
|
123
|
+
}, "store");
|
|
124
|
+
for (const item of response.items) rows.push({
|
|
125
|
+
id: item.id,
|
|
126
|
+
provider: "store",
|
|
127
|
+
source: "store",
|
|
128
|
+
name: item.name,
|
|
129
|
+
description: item.description,
|
|
130
|
+
author: item.author.username,
|
|
131
|
+
downloads: boundedNumber(item.downloads),
|
|
132
|
+
stars: boundedNumber(item.stars),
|
|
133
|
+
updatedAt: normalizeDate(item.updatedAt),
|
|
134
|
+
canonicalUrl: null,
|
|
135
|
+
install: {
|
|
136
|
+
kind: "store",
|
|
137
|
+
reference: item.name,
|
|
138
|
+
sourceUrl: null
|
|
139
|
+
},
|
|
140
|
+
security: {
|
|
141
|
+
status: "unknown",
|
|
142
|
+
scanners: []
|
|
143
|
+
},
|
|
144
|
+
valueScore: 0
|
|
145
|
+
});
|
|
146
|
+
statuses.push({
|
|
147
|
+
source: "store",
|
|
148
|
+
ok: true,
|
|
149
|
+
count: response.items.length
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
statuses.push({
|
|
153
|
+
source: "store",
|
|
154
|
+
ok: false,
|
|
155
|
+
count: 0,
|
|
156
|
+
error: String(error)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
})());
|
|
160
|
+
if (requested.has("clawhub") || requested.has("skills-sh")) jobs.push((async () => {
|
|
161
|
+
try {
|
|
162
|
+
const converted = (await searchClawHubFederatedSkills(params.query, fetchLimit)).results.map(fromClawHub);
|
|
163
|
+
for (const source of ["clawhub", "skills-sh"]) {
|
|
164
|
+
if (!requested.has(source)) continue;
|
|
165
|
+
const matches = converted.filter((row) => row.source === source);
|
|
166
|
+
rows.push(...matches);
|
|
167
|
+
statuses.push({
|
|
168
|
+
source,
|
|
169
|
+
ok: true,
|
|
170
|
+
count: matches.length,
|
|
171
|
+
...source === "skills-sh" ? { via: "clawhub" } : {}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
for (const source of ["clawhub", "skills-sh"]) if (requested.has(source)) statuses.push({
|
|
176
|
+
source,
|
|
177
|
+
ok: false,
|
|
178
|
+
count: 0,
|
|
179
|
+
error: String(error),
|
|
180
|
+
...source === "skills-sh" ? { via: "clawhub" } : {}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
})());
|
|
184
|
+
await Promise.all(jobs);
|
|
185
|
+
const limit = Math.min(20, Math.max(1, params.limit ?? 10));
|
|
186
|
+
const orderedStatuses = SKILL_MARKETPLACE_SEARCH_SOURCES.filter((source) => requested.has(source)).map((source) => statuses.find((status) => status.source === source)).filter(Boolean);
|
|
187
|
+
return {
|
|
188
|
+
results: dedupeAndRank(params.query, rows).slice(0, limit),
|
|
189
|
+
sources: orderedStatuses
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export { SKILL_MARKETPLACE_SEARCH_SOURCES, searchSkillMarketplaces };
|
|
@@ -10,7 +10,7 @@ import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
|
10
10
|
import type { Model, Api } from '@earendil-works/pi-ai';
|
|
11
11
|
import type { Config } from '../../config/schema.js';
|
|
12
12
|
import type { MessageBus } from '../../infra/bus/index.js';
|
|
13
|
-
import { type SkillInstallToolOptions, type SkillInstallToolResult } from './index.js';
|
|
13
|
+
import { type SkillInstallToolOptions, type SkillInstallToolResult, type MarketplaceSkillInstallToolOptions, type MarketplaceSkillInstallToolResult } from './index.js';
|
|
14
14
|
import type { MemoryManager } from '../memory/manager.js';
|
|
15
15
|
import type { SessionStore } from '../../session/store.js';
|
|
16
16
|
import type { GatewayClarifyRequestFn } from './clarify-tool.js';
|
|
@@ -70,6 +70,8 @@ export interface ToolFactoryDeps {
|
|
|
70
70
|
registerSkillEnvPassthrough?: (names: string[]) => void;
|
|
71
71
|
/** Install managed skills from explicit sources when a capability/tool enables it. */
|
|
72
72
|
installSkillFromSource?: (opts: SkillInstallToolOptions) => Promise<SkillInstallToolResult>;
|
|
73
|
+
/** Install a managed skill from a built-in marketplace provider. */
|
|
74
|
+
installSkillFromMarketplace?: (opts: MarketplaceSkillInstallToolOptions) => Promise<MarketplaceSkillInstallToolResult>;
|
|
73
75
|
/** Workspace-scoped structural code intelligence runtime. */
|
|
74
76
|
getCodeIntelligenceRuntime?: (workspace: string) => CodeIntelligenceRuntimeLike;
|
|
75
77
|
}
|
|
@@ -86,7 +88,7 @@ export interface CreateCoreToolsOptions {
|
|
|
86
88
|
/** Shared user memories directory used for dreaming state (`user/memories`). */
|
|
87
89
|
dreamingRoot?: string;
|
|
88
90
|
agentId?: string;
|
|
89
|
-
/** When set, registers
|
|
91
|
+
/** When set, registers local skill tools plus marketplace discovery for this workspace. */
|
|
90
92
|
getSkillManager?: () => SkillManager;
|
|
91
93
|
}
|
|
92
94
|
export declare class AgentToolsFactory {
|
|
@@ -38,6 +38,7 @@ import { createGoalTool } from "./goal-tool.js";
|
|
|
38
38
|
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
39
39
|
import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
|
|
40
40
|
import { createSkillManageTool } from "./skill-manage-tool.js";
|
|
41
|
+
import { createSkillsMarketplaceSearchTool } from "./skills-marketplace-search-tool.js";
|
|
41
42
|
import { createSkillInstallTool } from "./skill-install-tool.js";
|
|
42
43
|
import { createToolManualTool } from "./tool-manual-tool.js";
|
|
43
44
|
import { createDesktopPetTool } from "./desktop-pet-tool.js";
|
|
@@ -234,6 +235,15 @@ var AgentToolsFactory = class {
|
|
|
234
235
|
onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate
|
|
235
236
|
})
|
|
236
237
|
] : [],
|
|
238
|
+
createSkillsMarketplaceSearchTool({
|
|
239
|
+
getConfig: () => this.deps.getConfig?.(),
|
|
240
|
+
getSkillManager: getSkillMgr
|
|
241
|
+
}),
|
|
242
|
+
...this.deps.installSkillFromSource || this.deps.installSkillFromMarketplace ? [createSkillInstallTool({
|
|
243
|
+
installSkillFromSource: this.deps.installSkillFromSource,
|
|
244
|
+
installSkillFromMarketplace: this.deps.installSkillFromMarketplace,
|
|
245
|
+
getSessionKey: () => this.deps.getCurrentContext()?.sessionKey
|
|
246
|
+
})] : [],
|
|
237
247
|
readTool,
|
|
238
248
|
...codeIntelligenceTools,
|
|
239
249
|
writeTool,
|
|
@@ -328,15 +338,11 @@ var AgentToolsFactory = class {
|
|
|
328
338
|
if (disabled?.has(toolName) || toolNames.has(toolName)) continue;
|
|
329
339
|
toolNames.add(toolName);
|
|
330
340
|
if (toolName === "create_desktop_pet") raw.push(createDesktopPetTool());
|
|
331
|
-
if (toolName === "skill_install") raw.push(createSkillInstallTool({
|
|
332
|
-
installSkillFromSource: this.deps.installSkillFromSource,
|
|
333
|
-
getSessionKey: () => this.deps.getCurrentContext()?.sessionKey
|
|
334
|
-
}));
|
|
335
341
|
}
|
|
336
342
|
return wrapToolsWithProtection(raw, this.deps.toolExecutorConfig);
|
|
337
343
|
}
|
|
338
344
|
getLazyCapabilityToolNames() {
|
|
339
|
-
return ["create_desktop_pet"
|
|
345
|
+
return ["create_desktop_pet"];
|
|
340
346
|
}
|
|
341
347
|
createAllTools(coreOptions) {
|
|
342
348
|
const coreTools = this.createCoreTools(coreOptions);
|
|
@@ -32,7 +32,8 @@ export { createGoalTool, type GoalToolOptions } from './goal-tool.js';
|
|
|
32
32
|
export { createXopcUseTool, type XopcUseToolDeps, type XopcUseToolInput } from './xopc-use-tool.js';
|
|
33
33
|
export { createSkillsListTool, createSkillViewTool, type SkillsToolsDeps } from './skills-tools.js';
|
|
34
34
|
export { createSkillManageTool, type SkillManageToolDeps } from './skill-manage-tool.js';
|
|
35
|
-
export {
|
|
35
|
+
export { createSkillsMarketplaceSearchTool, type SkillsMarketplaceSearchToolDeps, } from './skills-marketplace-search-tool.js';
|
|
36
|
+
export { createSkillInstallTool, type SkillInstallToolDeps, type SkillInstallToolOptions, type SkillInstallToolResult, type MarketplaceSkillInstallToolOptions, type MarketplaceSkillInstallToolResult, } from './skill-install-tool.js';
|
|
36
37
|
export { createToolManualTool } from './tool-manual-tool.js';
|
|
37
38
|
export { createDesktopPetTool, type DesktopPetCreateDetails } from './desktop-pet-tool.js';
|
|
38
39
|
export { createCodeIntelligenceTools } from '../code-intelligence/tools.js';
|
|
@@ -36,6 +36,7 @@ import { createGoalTool } from "./goal-tool.js";
|
|
|
36
36
|
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
37
37
|
import { createSkillViewTool, createSkillsListTool } from "./skills-tools.js";
|
|
38
38
|
import { createSkillManageTool } from "./skill-manage-tool.js";
|
|
39
|
+
import { createSkillsMarketplaceSearchTool } from "./skills-marketplace-search-tool.js";
|
|
39
40
|
import { createSkillInstallTool } from "./skill-install-tool.js";
|
|
40
41
|
import { createToolManualTool } from "./tool-manual-tool.js";
|
|
41
42
|
import { createDesktopPetTool } from "./desktop-pet-tool.js";
|
|
@@ -43,4 +44,4 @@ import { createCodeIntelligenceTools } from "../code-intelligence/tools.js";
|
|
|
43
44
|
import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
|
|
44
45
|
import { createImageTool } from "./image-tool.js";
|
|
45
46
|
import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
|
|
46
|
-
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCodeIntelligenceTools, createComposioTools, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
47
|
+
export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCodeIntelligenceTools, createComposioTools, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
@@ -21,8 +21,25 @@ export interface SkillInstallToolResult {
|
|
|
21
21
|
contentHash: string;
|
|
22
22
|
target?: SkillInstallTarget;
|
|
23
23
|
}
|
|
24
|
+
export interface MarketplaceSkillInstallToolOptions {
|
|
25
|
+
provider: 'store' | 'clawhub';
|
|
26
|
+
name: string;
|
|
27
|
+
version?: string;
|
|
28
|
+
target?: SkillInstallTarget;
|
|
29
|
+
sessionKey?: string;
|
|
30
|
+
force?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface MarketplaceSkillInstallToolResult {
|
|
33
|
+
skillId: string;
|
|
34
|
+
path: string;
|
|
35
|
+
provider: 'store' | 'clawhub';
|
|
36
|
+
name: string;
|
|
37
|
+
version?: string;
|
|
38
|
+
target?: SkillInstallTarget;
|
|
39
|
+
}
|
|
24
40
|
export interface SkillInstallToolDeps {
|
|
25
41
|
installSkillFromSource?: (opts: SkillInstallToolOptions) => Promise<SkillInstallToolResult>;
|
|
42
|
+
installSkillFromMarketplace?: (opts: MarketplaceSkillInstallToolOptions) => Promise<MarketplaceSkillInstallToolResult>;
|
|
26
43
|
getSessionKey?: () => string | undefined;
|
|
27
44
|
}
|
|
28
45
|
export declare function createSkillInstallTool(deps: SkillInstallToolDeps): AgentTool;
|
|
@@ -2,11 +2,14 @@ import { isSkillInstallTarget } from "../skills/install-target.js";
|
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
3
|
//#region src/agent/tools/skill-install-tool.ts
|
|
4
4
|
const SkillInstallSchema = Type.Object({
|
|
5
|
-
source: Type.String({ description: "Explicit
|
|
5
|
+
source: Type.Optional(Type.String({ description: "Explicit source install: Git URL, GitHub repository URL, https .zip/.tar.gz URL, file:// URL, or local archive/path." })),
|
|
6
|
+
provider: Type.Optional(Type.Union([Type.Literal("store"), Type.Literal("clawhub")], { description: "Marketplace provider. Use with name; copy it from skills_marketplace_search." })),
|
|
7
|
+
name: Type.Optional(Type.String({ description: "Marketplace package name or install.reference. For ClawHub prefer owner/slug to disambiguate publishers." })),
|
|
8
|
+
version: Type.Optional(Type.String({ description: "Optional marketplace package version." })),
|
|
6
9
|
ref: Type.Optional(Type.String({ description: "Optional Git branch/tag/ref." })),
|
|
7
10
|
path: Type.Optional(Type.String({ description: "Optional subdirectory inside the source that contains SKILL.md." })),
|
|
8
|
-
skillId: Type.Optional(Type.String({ description: "Optional target managed skill id under the
|
|
9
|
-
target: Type.Optional(Type.Union([Type.Literal("workspace"), Type.Literal("global")], { description: "Install target. Defaults to
|
|
11
|
+
skillId: Type.Optional(Type.String({ description: "Optional target managed skill id under the selected global or workspace skills root." })),
|
|
12
|
+
target: Type.Optional(Type.Union([Type.Literal("workspace"), Type.Literal("global")], { description: "Install target. Defaults to global (~/.xopc/skills). Use workspace only when the user explicitly asks to scope the skill to the current agent workspace." })),
|
|
10
13
|
force: Type.Optional(Type.Boolean({ description: "Replace an existing managed skill with the same id." })),
|
|
11
14
|
strictScan: Type.Optional(Type.Boolean({ description: "Fail when the current scanner reports critical findings." }))
|
|
12
15
|
});
|
|
@@ -17,9 +20,70 @@ function createSkillInstallTool(deps) {
|
|
|
17
20
|
return {
|
|
18
21
|
name: "skill_install",
|
|
19
22
|
label: "Install skill",
|
|
20
|
-
description: "Install an xopc skill from an explicit
|
|
23
|
+
description: "Install an xopc skill from a Store/ClawHub marketplace result or an explicit source. Use only when the user clearly asks to install or update a skill; never treat search or a pasted URL as installation consent.",
|
|
21
24
|
parameters: SkillInstallSchema,
|
|
22
25
|
async execute(_toolCallId, params) {
|
|
26
|
+
const provider = clean(params.provider);
|
|
27
|
+
const name = clean(params.name);
|
|
28
|
+
const target = isSkillInstallTarget(params.target) ? params.target : "global";
|
|
29
|
+
const sessionKey = deps.getSessionKey?.();
|
|
30
|
+
if (provider || name) {
|
|
31
|
+
if (provider !== "store" && provider !== "clawhub") return {
|
|
32
|
+
content: [{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Marketplace installs require provider: store or clawhub."
|
|
35
|
+
}],
|
|
36
|
+
details: { errorCode: "missing_provider" }
|
|
37
|
+
};
|
|
38
|
+
if (!name) return {
|
|
39
|
+
content: [{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: "Marketplace installs require name from the search result."
|
|
42
|
+
}],
|
|
43
|
+
details: { errorCode: "missing_name" }
|
|
44
|
+
};
|
|
45
|
+
if (!deps.installSkillFromMarketplace) return {
|
|
46
|
+
content: [{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: "Marketplace skill installation is not available in this runtime context."
|
|
49
|
+
}],
|
|
50
|
+
details: { errorCode: "marketplace_install_unavailable" }
|
|
51
|
+
};
|
|
52
|
+
try {
|
|
53
|
+
const result = await deps.installSkillFromMarketplace({
|
|
54
|
+
provider,
|
|
55
|
+
name,
|
|
56
|
+
version: clean(params.version),
|
|
57
|
+
target,
|
|
58
|
+
sessionKey,
|
|
59
|
+
force: params.force === true
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
content: [{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: [
|
|
65
|
+
`Installed skill "${result.skillId}" from ${result.provider}.`,
|
|
66
|
+
`Package: ${result.name}${result.version ? `@${result.version}` : ""}`,
|
|
67
|
+
`Target: ${result.target ?? target}`,
|
|
68
|
+
`Path: ${result.path}`
|
|
69
|
+
].join("\n")
|
|
70
|
+
}],
|
|
71
|
+
details: { result }
|
|
72
|
+
};
|
|
73
|
+
} catch (err) {
|
|
74
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
75
|
+
return {
|
|
76
|
+
content: [{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: `Marketplace skill install failed: ${message}`
|
|
79
|
+
}],
|
|
80
|
+
details: {
|
|
81
|
+
errorCode: "install_failed",
|
|
82
|
+
errorMessage: message
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
23
87
|
if (!deps.installSkillFromSource) return {
|
|
24
88
|
content: [{
|
|
25
89
|
type: "text",
|
|
@@ -41,8 +105,8 @@ function createSkillInstallTool(deps) {
|
|
|
41
105
|
ref: clean(params.ref),
|
|
42
106
|
path: clean(params.path),
|
|
43
107
|
skillId: clean(params.skillId),
|
|
44
|
-
target
|
|
45
|
-
sessionKey
|
|
108
|
+
target,
|
|
109
|
+
sessionKey,
|
|
46
110
|
force: params.force === true,
|
|
47
111
|
strictScan: params.strictScan === true
|
|
48
112
|
});
|
|
@@ -51,7 +115,7 @@ function createSkillInstallTool(deps) {
|
|
|
51
115
|
type: "text",
|
|
52
116
|
text: [
|
|
53
117
|
`Installed skill "${result.skillId}".`,
|
|
54
|
-
`Target: ${result.target ??
|
|
118
|
+
`Target: ${result.target ?? target}`,
|
|
55
119
|
`Source: ${result.source} (${result.kind})`,
|
|
56
120
|
`Path: ${result.path}`,
|
|
57
121
|
`Tree hash: ${result.contentHash.slice(0, 16)}`
|
|
@@ -72,7 +136,11 @@ function createSkillInstallTool(deps) {
|
|
|
72
136
|
}
|
|
73
137
|
};
|
|
74
138
|
}
|
|
75
|
-
}
|
|
139
|
+
},
|
|
140
|
+
mutatesWorkspace: true,
|
|
141
|
+
mutationScope: "unknown",
|
|
142
|
+
idempotent: false,
|
|
143
|
+
finalGuardRelevant: true
|
|
76
144
|
};
|
|
77
145
|
}
|
|
78
146
|
//#endregion
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import type { Config } from '../../config/schema.js';
|
|
3
|
+
import type { SkillManager } from '../skills/skill-manager.js';
|
|
4
|
+
import { searchSkillMarketplaces, type SkillsMarketplaceSearchSource } from '../skills/marketplace/search.js';
|
|
5
|
+
type SearchResponse = Awaited<ReturnType<typeof searchSkillMarketplaces>>;
|
|
6
|
+
export interface SkillsMarketplaceSearchToolDeps {
|
|
7
|
+
getConfig: () => Config | undefined;
|
|
8
|
+
getSkillManager?: () => SkillManager | undefined;
|
|
9
|
+
search?: (params: {
|
|
10
|
+
config: Config;
|
|
11
|
+
query: string;
|
|
12
|
+
sources?: SkillsMarketplaceSearchSource[];
|
|
13
|
+
limit?: number;
|
|
14
|
+
}) => Promise<SearchResponse>;
|
|
15
|
+
}
|
|
16
|
+
export declare function createSkillsMarketplaceSearchTool(deps: SkillsMarketplaceSearchToolDeps): AgentTool;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { searchSkillMarketplaces } from "../skills/marketplace/search.js";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
//#region src/agent/tools/skills-marketplace-search-tool.ts
|
|
4
|
+
const SkillsMarketplaceSearchSchema = Type.Object({
|
|
5
|
+
query: Type.String({
|
|
6
|
+
minLength: 2,
|
|
7
|
+
description: "Capability or task to search for, using concise English keywords when possible"
|
|
8
|
+
}),
|
|
9
|
+
sources: Type.Optional(Type.Array(Type.Union([
|
|
10
|
+
Type.Literal("store"),
|
|
11
|
+
Type.Literal("clawhub"),
|
|
12
|
+
Type.Literal("skills-sh")
|
|
13
|
+
]), {
|
|
14
|
+
minItems: 1,
|
|
15
|
+
maxItems: 3,
|
|
16
|
+
uniqueItems: true
|
|
17
|
+
})),
|
|
18
|
+
limit: Type.Optional(Type.Integer({
|
|
19
|
+
minimum: 1,
|
|
20
|
+
maximum: 20,
|
|
21
|
+
default: 10
|
|
22
|
+
}))
|
|
23
|
+
});
|
|
24
|
+
function jsonResult(payload) {
|
|
25
|
+
return {
|
|
26
|
+
content: [{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: JSON.stringify(payload, null, 2)
|
|
29
|
+
}],
|
|
30
|
+
details: {}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function createSkillsMarketplaceSearchTool(deps) {
|
|
34
|
+
return {
|
|
35
|
+
name: "skills_marketplace_search",
|
|
36
|
+
label: "🔎 Find skills",
|
|
37
|
+
description: "Search the XOPC Store, native ClawHub catalog, and skills.sh results federated by ClawHub. Returns normalized provenance, install references, adoption metrics, partial-source errors, and a heuristic value score. Read-only; never installs a skill.",
|
|
38
|
+
parameters: SkillsMarketplaceSearchSchema,
|
|
39
|
+
mutatesWorkspace: false,
|
|
40
|
+
mutationScope: "none",
|
|
41
|
+
supportsParallel: true,
|
|
42
|
+
idempotent: true,
|
|
43
|
+
async execute(_toolCallId, params) {
|
|
44
|
+
const config = deps.getConfig();
|
|
45
|
+
if (!config) return jsonResult({
|
|
46
|
+
success: false,
|
|
47
|
+
error: "XOPC config is not available in this runtime context."
|
|
48
|
+
});
|
|
49
|
+
const query = params.query.trim();
|
|
50
|
+
if (query.length < 2) return jsonResult({
|
|
51
|
+
success: false,
|
|
52
|
+
error: "query must contain at least 2 characters."
|
|
53
|
+
});
|
|
54
|
+
const response = await (deps.search ?? searchSkillMarketplaces)({
|
|
55
|
+
config,
|
|
56
|
+
query,
|
|
57
|
+
sources: params.sources,
|
|
58
|
+
limit: params.limit
|
|
59
|
+
});
|
|
60
|
+
const manager = deps.getSkillManager?.();
|
|
61
|
+
const results = response.results.map((result) => ({
|
|
62
|
+
...result,
|
|
63
|
+
installed: Boolean(manager?.findSkill(result.name))
|
|
64
|
+
}));
|
|
65
|
+
return jsonResult({
|
|
66
|
+
success: true,
|
|
67
|
+
query,
|
|
68
|
+
scoreIsHeuristic: true,
|
|
69
|
+
sources: response.sources,
|
|
70
|
+
results,
|
|
71
|
+
installationRequiresConfirmation: true
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { createSkillsMarketplaceSearchTool };
|
|
@@ -11,8 +11,8 @@ import { createReadStream, createWriteStream } from "node:fs";
|
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
import { mkdir, mkdtemp, rm, stat } from "node:fs/promises";
|
|
14
|
-
import { Readable, Transform } from "node:stream";
|
|
15
14
|
import AdmZip from "adm-zip";
|
|
15
|
+
import { Readable, Transform } from "node:stream";
|
|
16
16
|
import { pipeline } from "node:stream/promises";
|
|
17
17
|
//#region src/browser/providers/cloakbrowser.ts
|
|
18
18
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { installConnectorDefinition } from "../connectors/install.js";
|
|
2
1
|
import { downloadConnectorStoreZipBuffer, fetchStoreConnectorPackageDetail, listConnectorPackages, resolveSkillsStoreBaseUrl } from "../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
2
|
+
import { installConnectorDefinition } from "../connectors/install.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
5
|
import AdmZip from "adm-zip";
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v66).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
2
1
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
3
2
|
import "../agent-manifest/index.js";
|
|
3
|
+
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
4
4
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
5
5
|
import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
6
6
|
//#region src/config/agent-profile.ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { registerMarketplaceAdapter, unregisterMarketplaceAdapter } from "../agent/skills/marketplace/registry.js";
|
|
3
4
|
import { registerSpeechProvider } from "../voice/tts/speech-registry.js";
|
|
4
5
|
import { HOOK_EXECUTION_MODES } from "./types/hooks.js";
|
|
5
6
|
import { commandRegistry } from "../chat-commands/registry.js";
|
|
6
7
|
import { TypedEventBus } from "./typed-event-bus.js";
|
|
7
8
|
import { ExtensionRegistryImpl } from "./extension-registry-impl.js";
|
|
8
|
-
import { registerMarketplaceAdapter, unregisterMarketplaceAdapter } from "../agent/skills/marketplace/registry.js";
|
|
9
9
|
import { registerMediaUnderstandingProvider } from "../media-understanding/registry.js";
|
|
10
10
|
import { registerMigration } from "../migrations/registry.js";
|
|
11
11
|
import { isAbsolute, resolve } from "path";
|
|
@@ -2,8 +2,8 @@ import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
4
|
import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir as resolveExtensionsDir$1 } from "../config/paths.js";
|
|
5
|
-
import { checkEngineCompatibility } from "./engine-check.js";
|
|
6
5
|
import { MAX_EXTENSION_STORE_ZIP_BYTES } from "./store-zip-limits.js";
|
|
6
|
+
import { checkEngineCompatibility } from "./engine-check.js";
|
|
7
7
|
import { collectExtensionPackageDependencyIssues } from "./package-contract.js";
|
|
8
8
|
import { dirname, isAbsolute, join, resolve, sep } from "path";
|
|
9
9
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FocusCandidate, FocusCandidateStatus, FocusEvidence } from './types.js';
|
|
2
|
+
import type { Focus } from './types.js';
|
|
3
|
+
export declare function getFocusCandidate(id: string): FocusCandidate | null;
|
|
4
|
+
export declare function listFocusCandidates(status?: FocusCandidateStatus, limit?: number): FocusCandidate[];
|
|
5
|
+
export declare function upsertFocusCandidate(input: {
|
|
6
|
+
canonicalKey: string;
|
|
7
|
+
title: string;
|
|
8
|
+
summary: string;
|
|
9
|
+
confidence: number;
|
|
10
|
+
evidence?: FocusEvidence[];
|
|
11
|
+
projectIds?: string[];
|
|
12
|
+
nowMs?: number;
|
|
13
|
+
}): FocusCandidate;
|
|
14
|
+
export declare function setFocusCandidateStatus(id: string, status: FocusCandidateStatus, nowMs?: number): FocusCandidate | null;
|
|
15
|
+
export declare function acceptFocusCandidate(id: string, nowMs?: number): Focus | null;
|