@skaile/workspaces 5.6.0 → 5.7.0
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/CHANGELOG.md +73 -0
- package/README.md +4 -2
- package/dist/{asset-feeds-4O2JK5S4.js → asset-feeds-K36CR52Q.js} +17 -17
- package/dist/{asset-feeds-4O2JK5S4.js.map → asset-feeds-K36CR52Q.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +9 -9
- package/dist/asset-manager/index.js +14 -14
- package/dist/asset-manager/installer.js +10 -10
- package/dist/asset-manager/renderers.js +9 -9
- package/dist/asset-manager/src/index.d.ts +106 -16
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts +4 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +11 -11
- package/dist/bridge/drivers/codex.js +10 -10
- package/dist/bridge/drivers/continue.js +12 -12
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/gemini.js +5 -5
- package/dist/bridge/drivers/goose.js +12 -12
- package/dist/bridge/drivers/omp.js +2 -2
- package/dist/bridge/drivers/opencode.js +12 -12
- package/dist/bridge/drivers/qwen.js +5 -5
- package/dist/bridge/index.js +12 -12
- package/dist/{chunk-VX3INFBA.js → chunk-34C42MJX.js} +3 -3
- package/dist/{chunk-VX3INFBA.js.map → chunk-34C42MJX.js.map} +1 -1
- package/dist/{chunk-NLXIALVO.js → chunk-53MSCGR2.js} +5 -5
- package/dist/{chunk-NLXIALVO.js.map → chunk-53MSCGR2.js.map} +1 -1
- package/dist/chunk-6C654TFI.js +84 -0
- package/dist/chunk-6C654TFI.js.map +1 -0
- package/dist/{chunk-6NPINANG.js → chunk-6UFFKMVC.js} +5 -5
- package/dist/{chunk-6NPINANG.js.map → chunk-6UFFKMVC.js.map} +1 -1
- package/dist/{chunk-XOGG7VDZ.js → chunk-6VRJH4MR.js} +16 -24
- package/dist/chunk-6VRJH4MR.js.map +1 -0
- package/dist/{chunk-IPWR33AW.js → chunk-74EEFB52.js} +31 -15
- package/dist/chunk-74EEFB52.js.map +1 -0
- package/dist/{chunk-OGLDAJFL.js → chunk-7FJQT3GT.js} +4 -4
- package/dist/{chunk-OGLDAJFL.js.map → chunk-7FJQT3GT.js.map} +1 -1
- package/dist/{chunk-VKSXST23.js → chunk-AVCUPPG6.js} +3 -3
- package/dist/{chunk-VKSXST23.js.map → chunk-AVCUPPG6.js.map} +1 -1
- package/dist/{chunk-5B5IZVEP.js → chunk-BTK7ECLH.js} +2 -2
- package/dist/{chunk-5B5IZVEP.js.map → chunk-BTK7ECLH.js.map} +1 -1
- package/dist/{chunk-O5GDKC5I.js → chunk-BWZF2ZIF.js} +3 -3
- package/dist/{chunk-O5GDKC5I.js.map → chunk-BWZF2ZIF.js.map} +1 -1
- package/dist/{chunk-PJS2YWGG.js → chunk-CWM3MYGX.js} +6 -6
- package/dist/{chunk-PJS2YWGG.js.map → chunk-CWM3MYGX.js.map} +1 -1
- package/dist/{chunk-4CTGEEN6.js → chunk-D5HOETOB.js} +424 -98
- package/dist/chunk-D5HOETOB.js.map +1 -0
- package/dist/{chunk-MX3UQXLU.js → chunk-DFFD4BFG.js} +96 -20
- package/dist/chunk-DFFD4BFG.js.map +1 -0
- package/dist/{chunk-KXTO7HON.js → chunk-EAZECHPM.js} +3 -3
- package/dist/{chunk-KXTO7HON.js.map → chunk-EAZECHPM.js.map} +1 -1
- package/dist/{chunk-ZBBM6O6P.js → chunk-EB4XN3KE.js} +3 -3
- package/dist/{chunk-ZBBM6O6P.js.map → chunk-EB4XN3KE.js.map} +1 -1
- package/dist/{chunk-MX6LZE2C.js → chunk-EU3Q5AQ4.js} +26 -18
- package/dist/chunk-EU3Q5AQ4.js.map +1 -0
- package/dist/{chunk-BTISGSK4.js → chunk-FAP63KV7.js} +4 -4
- package/dist/{chunk-BTISGSK4.js.map → chunk-FAP63KV7.js.map} +1 -1
- package/dist/{chunk-46OVMT76.js → chunk-G67BOI2J.js} +3 -3
- package/dist/{chunk-46OVMT76.js.map → chunk-G67BOI2J.js.map} +1 -1
- package/dist/{chunk-V7NN3HXR.js → chunk-GIC3G5YG.js} +6 -6
- package/dist/{chunk-V7NN3HXR.js.map → chunk-GIC3G5YG.js.map} +1 -1
- package/dist/{chunk-27HS2DHB.js → chunk-GWXFSLBK.js} +3 -3
- package/dist/{chunk-27HS2DHB.js.map → chunk-GWXFSLBK.js.map} +1 -1
- package/dist/{chunk-VSQFGU5D.js → chunk-ILFGVSTJ.js} +3 -3
- package/dist/{chunk-VSQFGU5D.js.map → chunk-ILFGVSTJ.js.map} +1 -1
- package/dist/{chunk-KYXOGHY6.js → chunk-IUUYRXT6.js} +4 -4
- package/dist/{chunk-KYXOGHY6.js.map → chunk-IUUYRXT6.js.map} +1 -1
- package/dist/{chunk-436GRQC2.js → chunk-IZLQ4GDO.js} +63 -44
- package/dist/chunk-IZLQ4GDO.js.map +1 -0
- package/dist/{chunk-LLKKLKZJ.js → chunk-JLSCA5T5.js} +3 -3
- package/dist/{chunk-LLKKLKZJ.js.map → chunk-JLSCA5T5.js.map} +1 -1
- package/dist/{chunk-SX4UIDKT.js → chunk-KM7XWC4Y.js} +3 -3
- package/dist/{chunk-SX4UIDKT.js.map → chunk-KM7XWC4Y.js.map} +1 -1
- package/dist/{chunk-KUFNKVBM.js → chunk-KNWCFEWU.js} +3 -3
- package/dist/{chunk-KUFNKVBM.js.map → chunk-KNWCFEWU.js.map} +1 -1
- package/dist/{chunk-MFHKHXDE.js → chunk-L5VSIPQD.js} +5 -5
- package/dist/chunk-L5VSIPQD.js.map +1 -0
- package/dist/{chunk-AOAZCSDI.js → chunk-LBQ4BBX4.js} +3 -3
- package/dist/{chunk-AOAZCSDI.js.map → chunk-LBQ4BBX4.js.map} +1 -1
- package/dist/{chunk-2W4LBLIN.js → chunk-LCU5U5IW.js} +6 -6
- package/dist/{chunk-2W4LBLIN.js.map → chunk-LCU5U5IW.js.map} +1 -1
- package/dist/{chunk-DZM73WDN.js → chunk-LXY4BUA3.js} +5 -5
- package/dist/{chunk-DZM73WDN.js.map → chunk-LXY4BUA3.js.map} +1 -1
- package/dist/{chunk-7KLC4LZO.js → chunk-MKLBK7HI.js} +8 -8
- package/dist/{chunk-7KLC4LZO.js.map → chunk-MKLBK7HI.js.map} +1 -1
- package/dist/{chunk-4GNJELPH.js → chunk-N6FBTXQ5.js} +2 -2
- package/dist/{chunk-4GNJELPH.js.map → chunk-N6FBTXQ5.js.map} +1 -1
- package/dist/{chunk-2XFUXGV6.js → chunk-NWQB7UTY.js} +3 -3
- package/dist/{chunk-2XFUXGV6.js.map → chunk-NWQB7UTY.js.map} +1 -1
- package/dist/{chunk-SDFROXSA.js → chunk-O4Z7MAW7.js} +3 -3
- package/dist/{chunk-SDFROXSA.js.map → chunk-O4Z7MAW7.js.map} +1 -1
- package/dist/{chunk-AO7VJ6G6.js → chunk-O7VPNKYN.js} +8 -3
- package/dist/chunk-O7VPNKYN.js.map +1 -0
- package/dist/{chunk-TZCQ7ZWQ.js → chunk-OOLT6HGP.js} +10 -11
- package/dist/chunk-OOLT6HGP.js.map +1 -0
- package/dist/{chunk-2GRB5ITE.js → chunk-PSA6ONFB.js} +4 -4
- package/dist/{chunk-2GRB5ITE.js.map → chunk-PSA6ONFB.js.map} +1 -1
- package/dist/{chunk-45VFGT7A.js → chunk-RNPHRRLG.js} +3 -3
- package/dist/{chunk-45VFGT7A.js.map → chunk-RNPHRRLG.js.map} +1 -1
- package/dist/{chunk-7ZHLYXTI.js → chunk-RVIZQ5XD.js} +3 -3
- package/dist/{chunk-7ZHLYXTI.js.map → chunk-RVIZQ5XD.js.map} +1 -1
- package/dist/{chunk-BF33SCLY.js → chunk-SWO25LTO.js} +4 -4
- package/dist/{chunk-BF33SCLY.js.map → chunk-SWO25LTO.js.map} +1 -1
- package/dist/{chunk-UAP2XHRF.js → chunk-SZWRPEF7.js} +8 -8
- package/dist/{chunk-UAP2XHRF.js.map → chunk-SZWRPEF7.js.map} +1 -1
- package/dist/{chunk-S7QXEXKY.js → chunk-THEJJBOU.js} +3 -3
- package/dist/{chunk-S7QXEXKY.js.map → chunk-THEJJBOU.js.map} +1 -1
- package/dist/{chunk-PA7WLID3.js → chunk-TTPSDC2G.js} +33 -3
- package/dist/chunk-TTPSDC2G.js.map +1 -0
- package/dist/{chunk-VBBBZDI7.js → chunk-UX3K4RKE.js} +3 -3
- package/dist/{chunk-VBBBZDI7.js.map → chunk-UX3K4RKE.js.map} +1 -1
- package/dist/{chunk-RGXVQZOV.js → chunk-VOOI7B2L.js} +23 -21
- package/dist/chunk-VOOI7B2L.js.map +1 -0
- package/dist/{chunk-OLLAQLFJ.js → chunk-WIEC3ZE4.js} +5 -5
- package/dist/{chunk-OLLAQLFJ.js.map → chunk-WIEC3ZE4.js.map} +1 -1
- package/dist/cli/index.js +944 -600
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts +12 -3
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-index.d.ts +41 -4
- package/dist/cli/src/commands/library-index.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts +9 -0
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/manage.d.ts +8 -2
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-agents.d.ts.map +1 -1
- package/dist/cli/src/commands/outdated.d.ts +3 -2
- package/dist/cli/src/commands/outdated.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts +13 -4
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +4 -3
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/update.d.ts +1 -1
- package/dist/cli/src/commands/update.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/skill-checks.d.ts +21 -10
- package/dist/cli/src/skill-checks.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -6
- package/dist/connectors/index.js +15 -15
- package/dist/{connectors-HWENZFKW.js → connectors-SSOTIDHT.js} +18 -18
- package/dist/{connectors-HWENZFKW.js.map → connectors-SSOTIDHT.js.map} +1 -1
- package/dist/core/index.js +8 -8
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +6 -6
- package/dist/core/src/cache-paths.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +1 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +3 -3
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +6 -1
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +8 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/store.js +2 -2
- package/dist/core/workspace-config.js +5 -5
- package/dist/deploy/index.js +8 -8
- package/dist/discovery/index.js +4 -4
- package/dist/discovery/src/index.d.ts +1 -1
- package/dist/discovery/src/index.d.ts.map +1 -1
- package/dist/discovery/src/source-config.d.ts +12 -0
- package/dist/discovery/src/source-config.d.ts.map +1 -1
- package/dist/discovery/src/tree-entries.d.ts.map +1 -1
- package/dist/{ensure-sources-VCPKNPK2.js → ensure-sources-277VI7R3.js} +17 -17
- package/dist/{ensure-sources-VCPKNPK2.js.map → ensure-sources-277VI7R3.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +15 -15
- package/dist/factory-assets/connectors/deploy.js +15 -15
- package/dist/factory-assets/connectors/devserver.js +15 -15
- package/dist/factory-assets/connectors/flow/adapter.js +15 -15
- package/dist/factory-assets/connectors/flow/engine.js +9 -9
- package/dist/factory-assets/connectors/flow/run-flow.js +17 -17
- package/dist/factory-assets/connectors/flow.js +15 -15
- package/dist/factory-assets/connectors/git.js +15 -15
- package/dist/factory-assets/connectors/gmail.js +15 -15
- package/dist/factory-assets/connectors/googledrive.js +15 -15
- package/dist/factory-assets/connectors/local.js +15 -15
- package/dist/factory-assets/connectors/mattermost.js +15 -15
- package/dist/factory-assets/connectors/memory.js +15 -15
- package/dist/factory-assets/connectors/minio.js +15 -15
- package/dist/factory-assets/connectors/postgres.js +15 -15
- package/dist/factory-assets/connectors/s3.js +15 -15
- package/dist/factory-assets/connectors/sharepoint.js +15 -15
- package/dist/factory-assets/connectors/sqlite.js +15 -15
- package/dist/factory-assets/connectors/static-server.js +15 -15
- package/dist/factory-assets/connectors/tunnel.js +15 -15
- package/dist/factory-assets/connectors/webdav.js +15 -15
- package/dist/factory-assets/connectors/xstate-store.js +15 -15
- package/dist/factory-assets/connectors/xstate.js +15 -15
- package/dist/{flows-ENQY2DV7.js → flows-J2UEU2QM.js} +13 -13
- package/dist/{flows-ENQY2DV7.js.map → flows-J2UEU2QM.js.map} +1 -1
- package/dist/{helpers-IW36CEJX.js → helpers-KC5O7CML.js} +17 -17
- package/dist/{helpers-IW36CEJX.js.map → helpers-KC5O7CML.js.map} +1 -1
- package/dist/library/index.js +11 -11
- package/dist/library/install.js +3 -3
- package/dist/library/src/index.d.ts +3 -3
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/local/library-manager.d.ts +6 -0
- package/dist/library/src/local/library-manager.d.ts.map +1 -1
- package/dist/library/src/local/local-catalog-source.d.ts +5 -2
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts +23 -1
- package/dist/library/src/manifest-writer.d.ts.map +1 -1
- package/dist/library/src/sync/git-driver.d.ts +12 -0
- package/dist/library/src/sync/git-driver.d.ts.map +1 -1
- package/dist/{library-publish-R3DQLMTD.js → library-publish-FGXF5TJO.js} +85 -41
- package/dist/library-publish-FGXF5TJO.js.map +1 -0
- package/dist/{open-library-FAJZRDKE.js → open-library-P3D337NH.js} +20 -20
- package/dist/{open-library-FAJZRDKE.js.map → open-library-P3D337NH.js.map} +1 -1
- package/dist/open-registry-Z3P2X2AB.js +32 -0
- package/dist/{open-registry-NVPCQPND.js.map → open-registry-Z3P2X2AB.js.map} +1 -1
- package/dist/paths-JKEKXM52.js +22 -0
- package/dist/{paths-YUCP7K6U.js.map → paths-JKEKXM52.js.map} +1 -1
- package/dist/{plugin-store-66QFBNEO.js → plugin-store-WI4MZJLP.js} +10 -10
- package/dist/{plugin-store-66QFBNEO.js.map → plugin-store-WI4MZJLP.js.map} +1 -1
- package/dist/project-WFUDVYNN.js +41 -0
- package/dist/{project-ALJIVFHI.js.map → project-WFUDVYNN.js.map} +1 -1
- package/dist/resolver/index.js +9 -9
- package/dist/runner/index.js +28 -28
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +14 -14
- package/dist/sdk/bridge.js +12 -12
- package/dist/sdk/core.js +8 -8
- package/dist/sdk/flow.js +9 -9
- package/dist/sdk/index.js +28 -28
- package/dist/sdk/resolver.js +9 -9
- package/dist/sdk/runner.js +28 -28
- package/dist/secrets/index.js +2 -2
- package/dist/{setup-35JXIA3N.js → setup-RAMLTORM.js} +22 -22
- package/dist/{setup-35JXIA3N.js.map → setup-RAMLTORM.js.map} +1 -1
- package/dist/skills-EOHZ2DZ4.js +26 -0
- package/dist/{skills-CS7NE5TT.js.map → skills-EOHZ2DZ4.js.map} +1 -1
- package/dist/{source-ISR4KRZV.js → source-FYVSFYEI.js} +21 -21
- package/dist/{source-ISR4KRZV.js.map → source-FYVSFYEI.js.map} +1 -1
- package/dist/{source-manifest-publish-P22IPK5F.js → source-manifest-publish-4FPIPPLV.js} +23 -23
- package/dist/{source-manifest-publish-P22IPK5F.js.map → source-manifest-publish-4FPIPPLV.js.map} +1 -1
- package/dist/tui/index.js +28 -28
- package/dist/workspace-plugin/adapters/mcp.js +22 -22
- package/dist/workspace-plugin/adapters/omp.js +14 -14
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +3 -1
- package/dist/chunk-2NYXQYHN.js +0 -22
- package/dist/chunk-2NYXQYHN.js.map +0 -1
- package/dist/chunk-436GRQC2.js.map +0 -1
- package/dist/chunk-4CTGEEN6.js.map +0 -1
- package/dist/chunk-AO7VJ6G6.js.map +0 -1
- package/dist/chunk-IPWR33AW.js.map +0 -1
- package/dist/chunk-MFHKHXDE.js.map +0 -1
- package/dist/chunk-MX3UQXLU.js.map +0 -1
- package/dist/chunk-MX6LZE2C.js.map +0 -1
- package/dist/chunk-PA7WLID3.js.map +0 -1
- package/dist/chunk-RGXVQZOV.js.map +0 -1
- package/dist/chunk-TZCQ7ZWQ.js.map +0 -1
- package/dist/chunk-XOGG7VDZ.js.map +0 -1
- package/dist/library-publish-R3DQLMTD.js.map +0 -1
- package/dist/open-registry-NVPCQPND.js +0 -32
- package/dist/paths-YUCP7K6U.js +0 -22
- package/dist/project-ALJIVFHI.js +0 -41
- package/dist/skills-CS7NE5TT.js +0 -26
package/dist/cli/index.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-
|
|
3
|
-
import { makeSourceCommand, syncProjectSources } from '../chunk-
|
|
4
|
-
import {
|
|
5
|
-
import { checkSkillManifest } from '../chunk-2NYXQYHN.js';
|
|
6
|
-
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, refFor } from '../chunk-DZM73WDN.js';
|
|
7
|
-
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, reportInstalledSoftDeps } from '../chunk-MX6LZE2C.js';
|
|
2
|
+
import { makeProvidersCommand, loadRegistryView, addProviderEntry, ProviderRegistryWriteError } from '../chunk-53MSCGR2.js';
|
|
3
|
+
import { makeSourceCommand, syncProjectSources } from '../chunk-IZLQ4GDO.js';
|
|
4
|
+
import { makeInstallCommand, makeCheckCommand, makeCleanCommand, REF_HINT, reportInstalledSoftDeps } from '../chunk-EU3Q5AQ4.js';
|
|
8
5
|
import { createSpinner } from '../chunk-NESV47MF.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import '../chunk-
|
|
16
|
-
import '../chunk-
|
|
6
|
+
import { AI_RESOURCES } from '../chunk-7FJQT3GT.js';
|
|
7
|
+
import { findAssetManifestFile, declaredVersion, checkAssetManifest } from '../chunk-6C654TFI.js';
|
|
8
|
+
import { getStoreConfig, storeFetch, deviceLogin, loadStoreAuthConfig, logout, hasStoredAuth, isStoreAuthenticated, getStoreToken, getStoreIdentity, assetEntryRef, refFor } from '../chunk-LXY4BUA3.js';
|
|
9
|
+
import { openCatalogSource, LocalCatalogDisabledError, openLibraryManager, openLibrary } from '../chunk-GIC3G5YG.js';
|
|
10
|
+
import { logErr, S, logOk, logInfo, logWarn, TARGET_DEFAULT_HINT, deferredWarnings, warnLegacyClaudeCopies, kindColorPad, kindColor, colorRef, formatSoftDepSection, bareSoftDepName, formatSoftDepHint, formatRelativeTime, formatSoftDepRemovePreview, formatSoftDepAddPreview, fitWidth, KIND_COL_WIDTH } from '../chunk-THEJJBOU.js';
|
|
11
|
+
import { getKindRegistry, getKnownKinds } from '../chunk-WIEC3ZE4.js';
|
|
12
|
+
import { LocalSecretsProvider } from '../chunk-ILFGVSTJ.js';
|
|
13
|
+
import { runAgentChat, isCompositionError, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, hashAgentFiles, createCompositionContentSource, compileComposition, instanceForSession, resolveAgentInstance, describeComposition, MarkdownStreamer } from '../chunk-VOOI7B2L.js';
|
|
14
|
+
import { buildClaudePluginFiles } from '../chunk-N6FBTXQ5.js';
|
|
15
|
+
import '../chunk-6UFFKMVC.js';
|
|
16
|
+
import '../chunk-KM7XWC4Y.js';
|
|
17
17
|
import '../chunk-R6O6YWU7.js';
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
18
|
+
import '../chunk-IUUYRXT6.js';
|
|
19
|
+
import '../chunk-RNPHRRLG.js';
|
|
20
20
|
import '../chunk-4ZTPYIBE.js';
|
|
21
|
-
import '../chunk-
|
|
21
|
+
import '../chunk-NWQB7UTY.js';
|
|
22
22
|
import '../chunk-X5YPJV4N.js';
|
|
23
23
|
import '../chunk-O7SG5PC2.js';
|
|
24
24
|
import '../chunk-7QBNJTTQ.js';
|
|
@@ -27,67 +27,67 @@ import '../chunk-5LKOAX7I.js';
|
|
|
27
27
|
import '../chunk-32NA4TVC.js';
|
|
28
28
|
import '../chunk-W3UDISS2.js';
|
|
29
29
|
import '../chunk-HCYS7GFP.js';
|
|
30
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
30
|
+
import { runFlow, resumeFlow } from '../chunk-MKLBK7HI.js';
|
|
31
31
|
import '../chunk-4R6DROGN.js';
|
|
32
|
-
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-
|
|
33
|
-
import '../chunk-
|
|
32
|
+
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-EB4XN3KE.js';
|
|
33
|
+
import '../chunk-O4Z7MAW7.js';
|
|
34
34
|
import '../chunk-CT6NQSA4.js';
|
|
35
|
-
import '../chunk-
|
|
35
|
+
import '../chunk-SZWRPEF7.js';
|
|
36
36
|
import '../chunk-FK6HPLQA.js';
|
|
37
|
-
import '../chunk-
|
|
38
|
-
import '../chunk-
|
|
39
|
-
import '../chunk-
|
|
37
|
+
import '../chunk-PSA6ONFB.js';
|
|
38
|
+
import '../chunk-34C42MJX.js';
|
|
39
|
+
import '../chunk-UX3K4RKE.js';
|
|
40
40
|
import '../chunk-EINLFFP6.js';
|
|
41
41
|
import '../chunk-LOO5CB5M.js';
|
|
42
42
|
import '../chunk-NARITJS2.js';
|
|
43
|
-
import '../chunk-
|
|
43
|
+
import '../chunk-GWXFSLBK.js';
|
|
44
44
|
import '../chunk-XBSQ4KMC.js';
|
|
45
45
|
import '../chunk-YROR332M.js';
|
|
46
|
-
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-
|
|
46
|
+
import { getProviderPreset, AI_PROVIDER_PRESETS } from '../chunk-BTK7ECLH.js';
|
|
47
47
|
import '../chunk-6E6PKKAD.js';
|
|
48
48
|
import '../chunk-IFGTRL2I.js';
|
|
49
|
-
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-
|
|
49
|
+
import { projectAiAssetsRoots, loadFlow, loadAllFlowEntries, findFlowFileInRoots } from '../chunk-LBQ4BBX4.js';
|
|
50
50
|
import '../chunk-37FTLYFP.js';
|
|
51
51
|
import '../chunk-QZLWJETK.js';
|
|
52
52
|
import '../chunk-XUUYAS3Z.js';
|
|
53
53
|
import { nodeLabel, nodeSkillAsset, nodeIsInert, nodeIsOptional, nodeRunKind, flowSkillVersionPins } from '../chunk-NFGRW3L7.js';
|
|
54
54
|
import '../chunk-QCI6D7E4.js';
|
|
55
55
|
import '../chunk-DMLDYFDS.js';
|
|
56
|
-
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-
|
|
57
|
-
import { cloneOrInitGitRepo, ensureGitRepo, setManifestPublisher, syncManifestWithDisk, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, stampManifestPublisher, upsertManifestAsset, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-
|
|
58
|
-
import { parseManifestFile } from '../chunk-
|
|
59
|
-
import '../chunk-
|
|
56
|
+
import { AssetManager, MissingManifestError, parseRefTolerant, normalizeRepoUrl, FACTORY_SOURCE_URL } from '../chunk-D5HOETOB.js';
|
|
57
|
+
import { cloneOrInitGitRepo, trackOriginBranch, ensureGitRepo, setManifestPublisher, LIBRARY_OWNERSHIPS, syncManifestWithDisk, isGitRepo, assertManifestEditable, installLibraryAsset, missingRootAssets, assertValidLibraryName, stampManifestPublisher, upsertManifestAsset, getStoreManifestsDir, getDefaultValue, isSecretPlaceholder } from '../chunk-DFFD4BFG.js';
|
|
58
|
+
import { parseManifestFile, requiresSyntaxErrors, SEMVER_RE } from '../chunk-6VRJH4MR.js';
|
|
59
|
+
import '../chunk-FAP63KV7.js';
|
|
60
60
|
import '../chunk-R7FOF242.js';
|
|
61
61
|
import '../chunk-3TXEJN4W.js';
|
|
62
|
-
import { installTargetOf } from '../chunk-
|
|
62
|
+
import { installTargetOf, SCAFFOLD_KINDS } from '../chunk-74EEFB52.js';
|
|
63
63
|
import '../chunk-CGYEHQOX.js';
|
|
64
64
|
import '../chunk-KTBKW2FI.js';
|
|
65
65
|
import '../chunk-UQ6LFBPZ.js';
|
|
66
|
-
import '../chunk-
|
|
67
|
-
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent } from '../chunk-FRHE7FFB.js';
|
|
68
|
-
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-
|
|
66
|
+
import '../chunk-AVCUPPG6.js';
|
|
67
|
+
import { effectiveComposes, validatePreset, composeSlotDiagnostics, agentDeprecationDiagnostics, validateAgent, SLOT_ID_PATTERN } from '../chunk-FRHE7FFB.js';
|
|
68
|
+
import { resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, WorkspaceYamlEditor, resolveLibraryDir, checkAgentSkillConformance, globalInstallDir, GLOBAL_INSTALL_DIR_NAME, readLock, aiResourceRoots, workspaceProviderRegistryPath, userProviderRegistryPath, loadProviderRegistryFile } from '../chunk-OOLT6HGP.js';
|
|
69
69
|
import '../chunk-4GY63JU6.js';
|
|
70
|
-
import { factoryAssetRoots } from '../chunk-
|
|
71
|
-
import '../chunk-
|
|
70
|
+
import { factoryAssetRoots } from '../chunk-SWO25LTO.js';
|
|
71
|
+
import '../chunk-G67BOI2J.js';
|
|
72
72
|
import { DEFAULT_DRIVER_ID, DRIVER_DEFAULTS } from '../chunk-5BEFNLOR.js';
|
|
73
73
|
import { findKindDirs } from '../chunk-A2ULN3KX.js';
|
|
74
|
-
import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-
|
|
75
|
-
import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-
|
|
74
|
+
import { sourceCacheKey, getGlobalCacheDir, resolveAgentDir, AgentRefResolutionError, resolveAgentDefinitionDir, resolveSkWorkspaceConfig, matchPin, coerceVersion, loadSkWorkspaceConfig, normalizeAgentInstances, agentInstanceDiagnostics, storeManifestSlug, isWorkspaceConfigFilename } from '../chunk-LCU5U5IW.js';
|
|
75
|
+
import { globalCacheRoot, globalSkaileDir, userConfigPath } from '../chunk-L5VSIPQD.js';
|
|
76
76
|
import { SUPPORTED_DRIVER_TARGETS, driverTargetForDriver } from '../chunk-CPSIPIX7.js';
|
|
77
|
-
import {
|
|
77
|
+
import { SKAILE_MANIFEST_FILENAME, loadSkPublishManifest, decodeSkaileManifest, encodeSkaileManifest } from '../chunk-RVIZQ5XD.js';
|
|
78
78
|
import { pluginTitle } from '../chunk-RVRB27AN.js';
|
|
79
|
-
import { parseFrontmatter, scanDirectory } from '../chunk-
|
|
80
|
-
import { parseAssetRef, isValidAssetName, slugifyAssetName,
|
|
79
|
+
import { parseFrontmatter, scanDirectory } from '../chunk-TTPSDC2G.js';
|
|
80
|
+
import { parseAssetRef, isValidPublisher, PUBLISHER_HINT, isValidAssetName, ASSET_NAME_HINT, slugifyAssetName, parseAssetRefLoose, assetRefToStr } from '../chunk-O7VPNKYN.js';
|
|
81
81
|
import { portableSpawn, portableSpawnSync } from '../chunk-ICSCSM5D.js';
|
|
82
82
|
import { openSqlite } from '../chunk-JMKB7IB4.js';
|
|
83
83
|
import { parseModelRef, resolveEntryBaseUrl } from '../chunk-MJHSLODD.js';
|
|
84
84
|
import '../chunk-C3CAXQMA.js';
|
|
85
85
|
import '../chunk-BOFL7GIF.js';
|
|
86
86
|
import '../chunk-NSBPE2FW.js';
|
|
87
|
-
import * as
|
|
88
|
-
import
|
|
89
|
-
import * as
|
|
90
|
-
import
|
|
87
|
+
import * as fs9 from 'fs';
|
|
88
|
+
import fs9__default, { readFileSync, existsSync, mkdirSync, writeFileSync, lstatSync, rmSync, readdirSync, statSync } from 'fs';
|
|
89
|
+
import * as path23 from 'path';
|
|
90
|
+
import path23__default, { resolve, join } from 'path';
|
|
91
91
|
import { fileURLToPath } from 'url';
|
|
92
92
|
import { Help, Command, Option } from 'commander';
|
|
93
93
|
import { rcompare } from 'semver';
|
|
@@ -99,7 +99,7 @@ import * as readline from 'readline';
|
|
|
99
99
|
import { createInterface } from 'readline';
|
|
100
100
|
import fs6 from 'fs/promises';
|
|
101
101
|
import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
|
|
102
|
-
import { execSync, spawnSync } from 'child_process';
|
|
102
|
+
import { execSync, spawnSync, execFileSync } from 'child_process';
|
|
103
103
|
import * as readline2 from 'readline/promises';
|
|
104
104
|
import { createTRPCUntypedClient, httpLink, httpSubscriptionLink } from '@trpc/client';
|
|
105
105
|
|
|
@@ -176,7 +176,7 @@ async function runSearch(kind, query, opts) {
|
|
|
176
176
|
const showLocal = !opts.store;
|
|
177
177
|
const showStore = !opts.local;
|
|
178
178
|
const { resolveConfig } = await import('../library/index.js');
|
|
179
|
-
const airGapped = resolveConfig({ projectDir:
|
|
179
|
+
const airGapped = resolveConfig({ projectDir: path23__default.resolve(opts.projectDir) }).catalog.cache_ttl === 0;
|
|
180
180
|
if (showLocal) {
|
|
181
181
|
await searchLocal(query, kind, opts, showStore, airGapped);
|
|
182
182
|
}
|
|
@@ -185,10 +185,11 @@ async function runSearch(kind, query, opts) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
async function searchIndex(query, kind) {
|
|
188
|
-
const { openLibrary: openLibrary2 } = await import('../open-library-
|
|
188
|
+
const { openLibrary: openLibrary2 } = await import('../open-library-P3D337NH.js');
|
|
189
189
|
const library = await openLibrary2();
|
|
190
190
|
try {
|
|
191
191
|
const defs = await library.listAssetDefs(kind ? { kind } : {});
|
|
192
|
+
const libraryNames = new Map((await library.listSources()).map((l) => [l.id, l.name]));
|
|
192
193
|
let entries = defs.map(
|
|
193
194
|
(d) => ({
|
|
194
195
|
name: d.name,
|
|
@@ -202,7 +203,8 @@ async function searchIndex(query, kind) {
|
|
|
202
203
|
requires: [],
|
|
203
204
|
dependencies: [],
|
|
204
205
|
license: d.license,
|
|
205
|
-
category: d.category
|
|
206
|
+
category: d.category,
|
|
207
|
+
library: d.libraryId ? libraryNames.get(d.libraryId) : void 0
|
|
206
208
|
})
|
|
207
209
|
);
|
|
208
210
|
if (query) {
|
|
@@ -217,7 +219,7 @@ async function searchIndex(query, kind) {
|
|
|
217
219
|
}
|
|
218
220
|
}
|
|
219
221
|
async function searchFactory(projectDir, query, kind) {
|
|
220
|
-
const prefixes = factoryAssetRoots().map((r) => r.endsWith(
|
|
222
|
+
const prefixes = factoryAssetRoots().map((r) => r.endsWith(path23__default.sep) ? r : r + path23__default.sep);
|
|
221
223
|
const isFactoryPath = (p6) => prefixes.some((fp) => p6 === fp.slice(0, -1) || p6.startsWith(fp));
|
|
222
224
|
try {
|
|
223
225
|
const entries = await new AssetManager({ registry: getKindRegistry(), projectDir }).search(
|
|
@@ -237,11 +239,11 @@ function unionEntries(indexed, factory) {
|
|
|
237
239
|
return [...indexed, ...factory.filter((e) => !seen.has(entryDedupKey(e)))];
|
|
238
240
|
}
|
|
239
241
|
async function searchLocal(query, kind, opts, showStore, airGapped) {
|
|
240
|
-
const projectDir =
|
|
242
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
241
243
|
const factory = await searchFactory(projectDir, query, kind);
|
|
242
244
|
let entries = unionEntries(await searchIndex(query, kind), factory);
|
|
243
245
|
if (entries.length === 0 && !query && !kind && !airGapped) {
|
|
244
|
-
const { autoSyncForSearch } = await import('../source-
|
|
246
|
+
const { autoSyncForSearch } = await import('../source-FYVSFYEI.js');
|
|
245
247
|
if (await autoSyncForSearch(projectDir)) {
|
|
246
248
|
entries = unionEntries(await searchIndex(query, kind), factory);
|
|
247
249
|
}
|
|
@@ -264,40 +266,48 @@ var MIN_LOCAL_DESCRIPTION_WIDTH = 10;
|
|
|
264
266
|
function layoutLocalTable(rows, width, style = {}) {
|
|
265
267
|
const styleRef = style.ref ?? ((s) => s);
|
|
266
268
|
const styleVer = style.version ?? ((s) => s);
|
|
269
|
+
const styleLib = style.library ?? ((s) => s);
|
|
267
270
|
const gap = COLUMN_GAP.length;
|
|
268
271
|
const indent = 2;
|
|
269
272
|
const pad = " ".repeat(indent);
|
|
270
273
|
const nameW = Math.max(4, ...rows.map((r) => r.ref.length));
|
|
271
274
|
const verW = Math.max(0, ...rows.map((r) => r.version.length));
|
|
272
|
-
const
|
|
275
|
+
const libW = Math.max(0, ...rows.map((r) => (r.library ?? "").length));
|
|
276
|
+
const tailSpan = (verW > 0 ? gap + verW : 0) + (libW > 0 ? gap + libW : 0);
|
|
273
277
|
const refCell = (ref) => styleRef(ref) + " ".repeat(nameW - ref.length);
|
|
278
|
+
const tail = (r) => {
|
|
279
|
+
if (libW === 0) return r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : "";
|
|
280
|
+
const verCell = `${COLUMN_GAP}${styleVer(r.version)}${" ".repeat(verW - r.version.length)}`;
|
|
281
|
+
const ver = verW > 0 ? verCell : "";
|
|
282
|
+
return `${ver}${COLUMN_GAP}${r.library ? styleLib(r.library) : ""}`;
|
|
283
|
+
};
|
|
274
284
|
const lines = [];
|
|
275
|
-
const descW = width - (indent + nameW + gap +
|
|
285
|
+
const descW = width - (indent + nameW + gap + tailSpan);
|
|
276
286
|
if (descW >= MIN_LOCAL_DESCRIPTION_WIDTH) {
|
|
277
287
|
for (const r of rows) {
|
|
278
288
|
const desc = truncateText(r.description, descW);
|
|
279
|
-
const descCell =
|
|
280
|
-
lines.push(
|
|
281
|
-
`${pad}${refCell(r.ref)}${COLUMN_GAP}${descCell}${r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : ""}`
|
|
282
|
-
);
|
|
289
|
+
const descCell = tailSpan > 0 ? desc.padEnd(descW) : desc;
|
|
290
|
+
lines.push(`${pad}${refCell(r.ref)}${COLUMN_GAP}${descCell}${tail(r)}`);
|
|
283
291
|
}
|
|
284
|
-
return { ruleWidth: nameW + gap + descW +
|
|
292
|
+
return { ruleWidth: nameW + gap + descW + tailSpan, lines };
|
|
285
293
|
}
|
|
286
|
-
if (indent + nameW +
|
|
294
|
+
if (indent + nameW + tailSpan <= width) {
|
|
287
295
|
for (const r of rows) {
|
|
288
|
-
lines.push(
|
|
289
|
-
verW > 0 ? `${pad}${refCell(r.ref)}${r.version ? `${COLUMN_GAP}${styleVer(r.version)}` : ""}` : `${pad}${styleRef(r.ref)}`
|
|
290
|
-
);
|
|
296
|
+
lines.push(tailSpan > 0 ? `${pad}${refCell(r.ref)}${tail(r)}` : `${pad}${styleRef(r.ref)}`);
|
|
291
297
|
}
|
|
292
|
-
return { ruleWidth: nameW +
|
|
298
|
+
return { ruleWidth: nameW + tailSpan, lines };
|
|
293
299
|
}
|
|
294
300
|
const subPad = " ".repeat(indent + 2);
|
|
295
|
-
const subDescW = width - (indent + 2) -
|
|
301
|
+
const subDescW = width - (indent + 2) - tailSpan;
|
|
296
302
|
for (const r of rows) {
|
|
297
303
|
lines.push(`${pad}${styleRef(r.ref)}`);
|
|
298
304
|
const desc = subDescW >= MIN_LOCAL_DESCRIPTION_WIDTH ? truncateText(r.description, subDescW) : "";
|
|
299
|
-
const descCell = r.version && desc ? desc.padEnd(subDescW) : desc;
|
|
300
|
-
const parts = [
|
|
305
|
+
const descCell = (r.version || r.library) && desc ? desc.padEnd(subDescW) : desc;
|
|
306
|
+
const parts = [
|
|
307
|
+
descCell,
|
|
308
|
+
r.version ? styleVer(r.version) : "",
|
|
309
|
+
r.library ? styleLib(r.library) : ""
|
|
310
|
+
].filter((s) => s !== "");
|
|
301
311
|
if (parts.length > 0) lines.push(`${subPad}${parts.join(COLUMN_GAP)}`);
|
|
302
312
|
}
|
|
303
313
|
return { ruleWidth: Math.max(1, Math.min(nameW, width - indent)), lines };
|
|
@@ -313,10 +323,11 @@ function printLocalEntries(entries, width = terminalWidth()) {
|
|
|
313
323
|
items.map((e) => ({
|
|
314
324
|
ref: localEntryRef(e),
|
|
315
325
|
description: e.description,
|
|
316
|
-
version: e.version ? `v${e.version}` : ""
|
|
326
|
+
version: e.version ? `v${e.version}` : "",
|
|
327
|
+
library: e.library
|
|
317
328
|
})),
|
|
318
329
|
width,
|
|
319
|
-
{ ref: S.cmd, version: S.dim }
|
|
330
|
+
{ ref: S.cmd, version: S.dim, library: S.dim }
|
|
320
331
|
);
|
|
321
332
|
console.log();
|
|
322
333
|
console.log(
|
|
@@ -350,9 +361,9 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
350
361
|
logInfo("air-gapped (cache_ttl: 0) \u2014 local sources only");
|
|
351
362
|
return;
|
|
352
363
|
}
|
|
353
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
364
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-P3D337NH.js');
|
|
354
365
|
try {
|
|
355
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
366
|
+
const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
|
|
356
367
|
const assets = await remote.listAssets(kind ? { kind } : {});
|
|
357
368
|
const results = filterCatalogAssets(assets, query);
|
|
358
369
|
if (results.length > 0) {
|
|
@@ -363,7 +374,7 @@ async function searchStore(query, kind, opts, airGapped) {
|
|
|
363
374
|
logInfo("No results in store");
|
|
364
375
|
}
|
|
365
376
|
} catch (e) {
|
|
366
|
-
const local = e instanceof
|
|
377
|
+
const local = e instanceof LocalCatalogDisabledError2;
|
|
367
378
|
if (opts.store) {
|
|
368
379
|
logErr(
|
|
369
380
|
local ? "remote catalog disabled (catalog.url: local) \u2014 set catalog.url: https://skaile.store to search the store" : `Store search failed: ${e.message}`
|
|
@@ -470,7 +481,7 @@ function makeAddCommand() {
|
|
|
470
481
|
const warnings = deferredWarnings();
|
|
471
482
|
const am2 = new AssetManager({
|
|
472
483
|
registry: getKindRegistry(),
|
|
473
|
-
projectDir:
|
|
484
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
474
485
|
global: opts.global || harnesses !== void 0,
|
|
475
486
|
harnesses,
|
|
476
487
|
driverTarget: opts.target,
|
|
@@ -527,14 +538,15 @@ function makeRemoveCommand() {
|
|
|
527
538
|
const harnesses = parseHarnessFilter(opts.harness);
|
|
528
539
|
const am2 = new AssetManager({
|
|
529
540
|
registry: getKindRegistry(),
|
|
530
|
-
projectDir:
|
|
541
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
531
542
|
global: opts.global || harnesses !== void 0,
|
|
532
543
|
harnesses,
|
|
533
544
|
driverTarget: opts.target
|
|
534
545
|
});
|
|
535
546
|
const ok = am2.remove(ref);
|
|
536
547
|
if (!ok) {
|
|
537
|
-
logErr(`Not deployed: ${ref}`);
|
|
548
|
+
logErr(`Not deployed or declared: ${ref}`);
|
|
549
|
+
process.exitCode = 1;
|
|
538
550
|
return;
|
|
539
551
|
}
|
|
540
552
|
logOk(`Removed ${ref}`);
|
|
@@ -570,7 +582,7 @@ function makeListCommand() {
|
|
|
570
582
|
}
|
|
571
583
|
const am2 = new AssetManager({
|
|
572
584
|
registry: getKindRegistry(),
|
|
573
|
-
projectDir:
|
|
585
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
574
586
|
driverTarget: opts.target
|
|
575
587
|
});
|
|
576
588
|
let declared;
|
|
@@ -618,7 +630,7 @@ function makeListCommand() {
|
|
|
618
630
|
function runGlobalList(kind, opts, harnesses) {
|
|
619
631
|
const am2 = new AssetManager({
|
|
620
632
|
registry: getKindRegistry(),
|
|
621
|
-
projectDir:
|
|
633
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
622
634
|
global: true,
|
|
623
635
|
harnesses
|
|
624
636
|
});
|
|
@@ -691,7 +703,7 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
691
703
|
return { entry: match ?? deployed };
|
|
692
704
|
}
|
|
693
705
|
const lookup = opts.storeLookup ?? (async (filter) => {
|
|
694
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
706
|
+
const { resolveCatalogSource } = await import('../open-library-P3D337NH.js');
|
|
695
707
|
const { source, close } = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
696
708
|
try {
|
|
697
709
|
return await source.listAssets(filter);
|
|
@@ -707,9 +719,9 @@ async function resolveInfoEntry(am2, ref, opts) {
|
|
|
707
719
|
);
|
|
708
720
|
return { entry: hit ? catalogAssetToEntry(hit) : null };
|
|
709
721
|
} catch (err2) {
|
|
710
|
-
const { LocalCatalogDisabledError } = await import('../open-library-
|
|
722
|
+
const { LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-P3D337NH.js');
|
|
711
723
|
const storeNote = err2 instanceof Error ? err2.message : String(err2);
|
|
712
|
-
const disabled = err2 instanceof
|
|
724
|
+
const disabled = err2 instanceof LocalCatalogDisabledError2 || /catalog\.url/i.test(storeNote);
|
|
713
725
|
return { entry: null, storeNote, ...disabled ? { storeDisabled: true } : {} };
|
|
714
726
|
}
|
|
715
727
|
}
|
|
@@ -723,7 +735,7 @@ function infoNotFoundHint(ref, lookup) {
|
|
|
723
735
|
}
|
|
724
736
|
function makeInfoCommand() {
|
|
725
737
|
return new Command("info").description("Show asset metadata, deps, deploy status").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
726
|
-
const projectDir =
|
|
738
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
727
739
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir });
|
|
728
740
|
const lookup = await resolveInfoEntry(am2, ref, { projectDir });
|
|
729
741
|
const entry = lookup.entry;
|
|
@@ -756,10 +768,10 @@ function makeInfoCommand() {
|
|
|
756
768
|
}
|
|
757
769
|
function makeCreateCommand() {
|
|
758
770
|
return new Command("create").description("Scaffold a new asset").argument("<name>", "Asset name").addOption(
|
|
759
|
-
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices(
|
|
771
|
+
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...SCAFFOLD_KINDS])
|
|
760
772
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
761
773
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
762
|
-
const destDir = opts.dir ?
|
|
774
|
+
const destDir = opts.dir ? path23__default.resolve(opts.dir) : process.cwd();
|
|
763
775
|
const result = am2.create(name, opts.kind, destDir);
|
|
764
776
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
765
777
|
else {
|
|
@@ -772,21 +784,29 @@ function makeDoctorCommand() {
|
|
|
772
784
|
return new Command("doctor").description("Scan for missing dependency chains").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (name, opts) => {
|
|
773
785
|
const am2 = new AssetManager({
|
|
774
786
|
registry: getKindRegistry(),
|
|
775
|
-
projectDir:
|
|
787
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
776
788
|
});
|
|
777
789
|
const issues = await am2.doctor();
|
|
778
790
|
if (issues.length === 0) {
|
|
779
791
|
logOk("No missing dependencies.");
|
|
780
792
|
return;
|
|
781
793
|
}
|
|
782
|
-
const
|
|
783
|
-
const
|
|
794
|
+
const unresolved = issues.filter((i) => i.unresolved);
|
|
795
|
+
const missing = issues.filter((i) => !i.unresolved);
|
|
796
|
+
for (const i of unresolved) {
|
|
797
|
+
logErr(
|
|
798
|
+
`${i.assetKind}:${i.assetName}: locked, but no source or library provides it \u2014 run skaile install`
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
if (missing.length === 0) return;
|
|
802
|
+
const assetW = Math.max(5, ...missing.map((i) => `${i.assetKind}:${i.assetName}`.length));
|
|
803
|
+
const depW = Math.max(11, ...missing.map((i) => `${i.depKind}:${i.depName}`.length));
|
|
784
804
|
console.log();
|
|
785
805
|
console.log(
|
|
786
806
|
` ${S.dim("ASSET".padEnd(assetW))} ${S.dim("MISSING DEP".padEnd(depW))} ${S.dim("IN REPOS")}`
|
|
787
807
|
);
|
|
788
808
|
console.log(` ${S.rule(assetW + depW + 15)}`);
|
|
789
|
-
for (const i of
|
|
809
|
+
for (const i of missing) {
|
|
790
810
|
const asset = `${i.assetKind}:${i.assetName}`;
|
|
791
811
|
const dep = `${i.depKind}:${i.depName}`;
|
|
792
812
|
const status4 = i.inRepos ? S.warn("fixable") : S.err("not found");
|
|
@@ -795,12 +815,37 @@ function makeDoctorCommand() {
|
|
|
795
815
|
console.log();
|
|
796
816
|
});
|
|
797
817
|
}
|
|
798
|
-
|
|
818
|
+
function manifestRequiresProblems(dir) {
|
|
819
|
+
const file = path23.join(dir, "skaile.manifest.yaml");
|
|
820
|
+
let doc;
|
|
821
|
+
try {
|
|
822
|
+
doc = parse(fs9.readFileSync(file, "utf-8"));
|
|
823
|
+
} catch {
|
|
824
|
+
return [];
|
|
825
|
+
}
|
|
826
|
+
const assets = doc?.assets;
|
|
827
|
+
if (!Array.isArray(assets)) return [];
|
|
828
|
+
const problems = [];
|
|
829
|
+
for (const a of assets) {
|
|
830
|
+
if (!a || typeof a !== "object") continue;
|
|
831
|
+
const { kind, name, dependencies } = a;
|
|
832
|
+
if (!Array.isArray(dependencies)) continue;
|
|
833
|
+
const entries = dependencies.map((d) => typeof d === "string" ? d : String(d));
|
|
834
|
+
for (const message of requiresSyntaxErrors(entries)) {
|
|
835
|
+
problems.push({
|
|
836
|
+
asset: `${String(kind)}:${String(name)}`,
|
|
837
|
+
message: `ManifestRequiresError: ${message}`
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return problems;
|
|
842
|
+
}
|
|
843
|
+
async function indexLibrary(lib, index, opts = {}) {
|
|
799
844
|
const { LocalCatalogSource } = await import('../library/index.js');
|
|
800
845
|
const own = index ?? await openLibrary();
|
|
801
846
|
try {
|
|
802
847
|
const source = new LocalCatalogSource(own, lib.id, lib.path, getKindRegistry());
|
|
803
|
-
const res = await source.sync();
|
|
848
|
+
const res = await source.sync({ exclude: opts.exclude });
|
|
804
849
|
return {
|
|
805
850
|
assetsFound: res.assetsFound,
|
|
806
851
|
assetsUpdated: res.assetsUpdated,
|
|
@@ -823,31 +868,23 @@ function resolveLibraryPublisherDetailed(lib, opts, storeIdentity) {
|
|
|
823
868
|
return { publisher: "library", source: "library-name" };
|
|
824
869
|
}
|
|
825
870
|
}
|
|
826
|
-
function
|
|
827
|
-
|
|
871
|
+
function warnLibraryNameFallback(libName, resolved) {
|
|
872
|
+
if (resolved.source !== "library-name") return;
|
|
873
|
+
logWarn(
|
|
874
|
+
`No publisher given and not signed in \u2014 using the library name "${resolved.publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${libName} publisher=<name>\`.`
|
|
875
|
+
);
|
|
828
876
|
}
|
|
829
|
-
function
|
|
830
|
-
|
|
831
|
-
let markerFile;
|
|
832
|
-
for (const m of markers) {
|
|
833
|
-
if (fs11.existsSync(path25.join(assetDir, m))) {
|
|
834
|
-
markerFile = path25.join(assetDir, m);
|
|
835
|
-
break;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
877
|
+
function normalizeAssetFrontmatter(assetDir) {
|
|
878
|
+
let markerFile = ["SKILL.md", "AGENT.md", "CONTRACT.md"].map((m) => path23.join(assetDir, m)).find((f) => fs9.existsSync(f));
|
|
838
879
|
if (!markerFile) {
|
|
839
|
-
const promptMd =
|
|
840
|
-
if (promptMd) markerFile =
|
|
880
|
+
const promptMd = fs9.readdirSync(assetDir).find((f) => f.endsWith(".prompt.md"));
|
|
881
|
+
if (promptMd) markerFile = path23.join(assetDir, promptMd);
|
|
841
882
|
}
|
|
842
883
|
if (!markerFile) return;
|
|
843
884
|
try {
|
|
844
|
-
const { data, body } = parseFrontmatter(
|
|
845
|
-
const meta = data.metadata && typeof data.metadata === "object" && !Array.isArray(data.metadata) ? { ...data.metadata } : {};
|
|
846
|
-
if (meta.publisher != null) return;
|
|
847
|
-
meta.publisher = publisher;
|
|
848
|
-
data.metadata = meta;
|
|
885
|
+
const { data, body } = parseFrontmatter(fs9.readFileSync(markerFile, "utf8"));
|
|
849
886
|
const fm = stringify(data).trimEnd();
|
|
850
|
-
|
|
887
|
+
fs9.writeFileSync(markerFile, `---
|
|
851
888
|
${fm}
|
|
852
889
|
---
|
|
853
890
|
|
|
@@ -862,17 +899,13 @@ async function registerLibraryAsset(lib, index, input) {
|
|
|
862
899
|
{ publisher: input.publisher },
|
|
863
900
|
getStoreIdentity()
|
|
864
901
|
);
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
`No publisher given and not signed in \u2014 using the library name "${publisher}" as the publisher. Pass --publisher <name> or run \`skaile store login\`; change it later with \`skaile library set ${lib.name} publisher=<name>\`.`
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
stampAssetPublisher(input.assetDir, publisher);
|
|
902
|
+
warnLibraryNameFallback(lib.name, { publisher, source });
|
|
903
|
+
normalizeAssetFrontmatter(input.assetDir);
|
|
871
904
|
stampManifestPublisher(lib.path, publisher);
|
|
872
905
|
upsertManifestAsset(lib.path, {
|
|
873
906
|
kind: input.kind,
|
|
874
907
|
name: input.name,
|
|
875
|
-
root:
|
|
908
|
+
root: path23.relative(lib.path, input.assetDir) || input.name,
|
|
876
909
|
version: input.version,
|
|
877
910
|
publisher
|
|
878
911
|
});
|
|
@@ -882,19 +915,27 @@ async function registerLibraryAsset(lib, index, input) {
|
|
|
882
915
|
}
|
|
883
916
|
var LIBRARY_UPGRADE_DOCS = "https://github.com/skaile-ai/workspaces/blob/main/docs/sections/cli/commands/library.md#upgrading-a-4x-library";
|
|
884
917
|
var DOMAIN_REMOVED_HINT = `Domains were removed in 5.0 \u2014 delete DOMAIN.md files; group assets with .claude-plugin/marketplace.json. See ${LIBRARY_UPGRADE_DOCS}`;
|
|
918
|
+
function removedDomainOption() {
|
|
919
|
+
return new Option("--domain <domain>", "Removed in 5.0").hideHelp();
|
|
920
|
+
}
|
|
921
|
+
function rejectRemovedDomainOption(opts) {
|
|
922
|
+
if (opts.domain === void 0) return;
|
|
923
|
+
logErr(DOMAIN_REMOVED_HINT);
|
|
924
|
+
process.exit(1);
|
|
925
|
+
}
|
|
885
926
|
function countDomainFiles(root) {
|
|
886
927
|
let count = 0;
|
|
887
928
|
const walk = (dir) => {
|
|
888
929
|
let entries;
|
|
889
930
|
try {
|
|
890
|
-
entries =
|
|
931
|
+
entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
891
932
|
} catch {
|
|
892
933
|
return;
|
|
893
934
|
}
|
|
894
935
|
for (const entry of entries) {
|
|
895
936
|
if (entry.isDirectory()) {
|
|
896
937
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
897
|
-
walk(
|
|
938
|
+
walk(path23.join(dir, entry.name));
|
|
898
939
|
}
|
|
899
940
|
} else if (entry.name === "DOMAIN.md") {
|
|
900
941
|
count++;
|
|
@@ -919,21 +960,21 @@ function claudeSkillRoots() {
|
|
|
919
960
|
const roots = [];
|
|
920
961
|
const override = process.env.SKAILE_CLAUDE_SKILLS_DIR;
|
|
921
962
|
if (override) roots.push(override);
|
|
922
|
-
roots.push(
|
|
963
|
+
roots.push(path23.join(os.homedir(), ".claude", "skills"));
|
|
923
964
|
return roots;
|
|
924
965
|
}
|
|
925
966
|
function resolveImportSource(nameOrPath) {
|
|
926
|
-
const asPath =
|
|
927
|
-
if (
|
|
928
|
-
const dir =
|
|
929
|
-
const skillFile =
|
|
930
|
-
if (
|
|
967
|
+
const asPath = path23.resolve(nameOrPath);
|
|
968
|
+
if (fs9.existsSync(asPath)) {
|
|
969
|
+
const dir = fs9.statSync(asPath).isDirectory() ? asPath : path23.dirname(asPath);
|
|
970
|
+
const skillFile = path23.join(dir, "SKILL.md");
|
|
971
|
+
if (fs9.existsSync(skillFile)) return { dir, skillFile, via: "path" };
|
|
931
972
|
}
|
|
932
|
-
if (!nameOrPath.includes(
|
|
973
|
+
if (!nameOrPath.includes(path23.sep) && !nameOrPath.startsWith(".")) {
|
|
933
974
|
for (const root of claudeSkillRoots()) {
|
|
934
|
-
const dir =
|
|
935
|
-
const skillFile =
|
|
936
|
-
if (
|
|
975
|
+
const dir = path23.join(root, nameOrPath);
|
|
976
|
+
const skillFile = path23.join(dir, "SKILL.md");
|
|
977
|
+
if (fs9.existsSync(skillFile)) return { dir, skillFile, via: "claude-skills" };
|
|
937
978
|
}
|
|
938
979
|
}
|
|
939
980
|
return null;
|
|
@@ -989,15 +1030,16 @@ ${body}
|
|
|
989
1030
|
|
|
990
1031
|
// cli/src/commands/asset-cmd.ts
|
|
991
1032
|
async function resolveDefByRef(library, ref, opts) {
|
|
992
|
-
const inScope = (d) => !opts?.fromLibraryId || d.libraryId === opts.fromLibraryId;
|
|
993
|
-
const direct = await library.getAssetDef(ref);
|
|
994
|
-
if (direct && inScope(direct)) return direct;
|
|
995
1033
|
let parsed;
|
|
996
1034
|
try {
|
|
997
1035
|
parsed = parseAssetRef(ref);
|
|
998
|
-
} catch {
|
|
999
|
-
|
|
1036
|
+
} catch (err2) {
|
|
1037
|
+
logErr(
|
|
1038
|
+
`malformed asset ref '${ref}' \u2014 expected ${REF_HINT}: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
1039
|
+
);
|
|
1040
|
+
process.exit(1);
|
|
1000
1041
|
}
|
|
1042
|
+
const inScope = (d) => !opts?.fromLibraryId || d.libraryId === opts.fromLibraryId;
|
|
1001
1043
|
const wantPublisher = parsed.publisher?.replace(/^@/, "");
|
|
1002
1044
|
const defs = await library.listAssetDefs({ kind: parsed.kind });
|
|
1003
1045
|
const matches = defs.filter(
|
|
@@ -1008,7 +1050,8 @@ async function resolveDefByRef(library, ref, opts) {
|
|
|
1008
1050
|
return matches[0];
|
|
1009
1051
|
}
|
|
1010
1052
|
function withCanonicalRef(def) {
|
|
1011
|
-
|
|
1053
|
+
const { id: _storageId, ...rest } = def;
|
|
1054
|
+
return { ref: catalogAssetRef(def), ...rest };
|
|
1012
1055
|
}
|
|
1013
1056
|
function resolveLibraryOption(opts) {
|
|
1014
1057
|
if (opts.library && opts.to && opts.library !== opts.to) {
|
|
@@ -1021,11 +1064,12 @@ function resolveLibraryOption(opts) {
|
|
|
1021
1064
|
}
|
|
1022
1065
|
function makeAssetCommand() {
|
|
1023
1066
|
const cmd = new Command("asset").description("Author and install AI assets");
|
|
1024
|
-
cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--library <library>", "Target library (default: auto / personal)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option(
|
|
1067
|
+
cmd.command("import <name-or-path>").description("Import + skailify an existing coding-agent skill into a library").option("--library <library>", "Target library (default: auto / personal)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).addOption(removedDomainOption()).option("--version <semver>", "Version to stamp when the skill ships none").option("--stage <stage>", "Lifecycle stage to stamp (default: alpha)").option("--no-normalize", "Copy verbatim \u2014 skip frontmatter normalization").option(
|
|
1025
1068
|
"--publisher <name>",
|
|
1026
1069
|
"Publisher for the imported skill (default: the library's, else your store login)"
|
|
1027
1070
|
).option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
1028
1071
|
async (nameOrPath, opts) => {
|
|
1072
|
+
rejectRemovedDomainOption(opts);
|
|
1029
1073
|
const src = resolveImportSource(nameOrPath);
|
|
1030
1074
|
if (!src) {
|
|
1031
1075
|
logErr(
|
|
@@ -1055,24 +1099,24 @@ function makeAssetCommand() {
|
|
|
1055
1099
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
1056
1100
|
process.exit(1);
|
|
1057
1101
|
}
|
|
1058
|
-
const rawSkill =
|
|
1102
|
+
const rawSkill = fs9.readFileSync(src.skillFile, "utf8");
|
|
1059
1103
|
const norm = opts.normalize ? normalizeSkillContent(rawSkill, {
|
|
1060
|
-
fallbackName:
|
|
1104
|
+
fallbackName: path23.basename(src.dir),
|
|
1061
1105
|
version: opts.version,
|
|
1062
1106
|
stage: opts.stage
|
|
1063
|
-
}) : { content: rawSkill, name:
|
|
1107
|
+
}) : { content: rawSkill, name: path23.basename(src.dir), changed: false, notes: [] };
|
|
1064
1108
|
if (!opts.normalize && !isValidAssetName(norm.name)) {
|
|
1065
1109
|
logWarn(
|
|
1066
1110
|
`Name "${norm.name}" is not canonical (kebab-case); \`skaile validate\` will reject this manifest entry. Drop --no-normalize to slugify it.`
|
|
1067
1111
|
);
|
|
1068
1112
|
}
|
|
1069
|
-
const destDir =
|
|
1070
|
-
if (
|
|
1113
|
+
const destDir = path23.join(target.path, norm.name);
|
|
1114
|
+
if (fs9.existsSync(destDir)) {
|
|
1071
1115
|
logErr(`Destination already exists: ${destDir}`);
|
|
1072
1116
|
process.exit(1);
|
|
1073
1117
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1118
|
+
fs9.cpSync(src.dir, destDir, { recursive: true });
|
|
1119
|
+
fs9.writeFileSync(path23.join(destDir, "SKILL.md"), norm.content, "utf8");
|
|
1076
1120
|
for (const note of norm.notes) logInfo(` \u2022 ${note}`);
|
|
1077
1121
|
const fm = parseFrontmatter(norm.content).data;
|
|
1078
1122
|
for (const f of checkAgentSkillConformance(fm, { dirName: norm.name })) {
|
|
@@ -1105,13 +1149,14 @@ function makeAssetCommand() {
|
|
|
1105
1149
|
}
|
|
1106
1150
|
}
|
|
1107
1151
|
);
|
|
1108
|
-
cmd.command("migrate <path>").description("Move/copy/link a workspace asset into a library").option("--library <library>", "Target library (default: auto)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).option("--mode <mode>", "copy | move | link", "copy").option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
1152
|
+
cmd.command("migrate <path>").description("Move/copy/link a workspace asset into a library").option("--library <library>", "Target library (default: auto)").addOption(new Option("--to <library>", "Alias for --library").hideHelp()).addOption(removedDomainOption()).option("--mode <mode>", "copy | move | link", "copy").option("--commit", "Auto-commit in git-backed libraries", false).action(
|
|
1109
1153
|
async (srcPath, opts) => {
|
|
1154
|
+
rejectRemovedDomainOption(opts);
|
|
1110
1155
|
if (!["copy", "move", "link"].includes(opts.mode)) {
|
|
1111
1156
|
logErr(`Invalid --mode "${opts.mode}". Expected: copy | move | link.`);
|
|
1112
1157
|
process.exit(1);
|
|
1113
1158
|
}
|
|
1114
|
-
if (!
|
|
1159
|
+
if (!fs9.existsSync(srcPath)) {
|
|
1115
1160
|
logErr(`Source path does not exist: ${srcPath}`);
|
|
1116
1161
|
process.exit(1);
|
|
1117
1162
|
}
|
|
@@ -1137,23 +1182,23 @@ function makeAssetCommand() {
|
|
|
1137
1182
|
);
|
|
1138
1183
|
process.exit(1);
|
|
1139
1184
|
}
|
|
1140
|
-
const basename2 =
|
|
1185
|
+
const basename2 = path23.basename(srcPath);
|
|
1141
1186
|
const destDir = target.path;
|
|
1142
|
-
|
|
1143
|
-
const destPath =
|
|
1144
|
-
if (
|
|
1187
|
+
fs9.mkdirSync(destDir, { recursive: true });
|
|
1188
|
+
const destPath = path23.join(destDir, basename2);
|
|
1189
|
+
if (fs9.existsSync(destPath)) {
|
|
1145
1190
|
logErr(`Destination already exists: ${destPath}`);
|
|
1146
1191
|
process.exit(1);
|
|
1147
1192
|
}
|
|
1148
1193
|
switch (opts.mode) {
|
|
1149
1194
|
case "copy":
|
|
1150
|
-
|
|
1195
|
+
fs9.cpSync(srcPath, destPath, { recursive: true });
|
|
1151
1196
|
break;
|
|
1152
1197
|
case "move":
|
|
1153
|
-
|
|
1198
|
+
fs9.renameSync(srcPath, destPath);
|
|
1154
1199
|
break;
|
|
1155
1200
|
case "link":
|
|
1156
|
-
|
|
1201
|
+
fs9.symlinkSync(path23.resolve(srcPath), destPath);
|
|
1157
1202
|
break;
|
|
1158
1203
|
}
|
|
1159
1204
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -1283,14 +1328,14 @@ function makeAuthCommand() {
|
|
|
1283
1328
|
}
|
|
1284
1329
|
function collectCacheTargets(scope) {
|
|
1285
1330
|
const out = [];
|
|
1286
|
-
out.push(
|
|
1287
|
-
out.push(
|
|
1288
|
-
out.push(
|
|
1331
|
+
out.push(path23__default.join(scope.projectDir, ".skaile", "cache"));
|
|
1332
|
+
out.push(path23__default.join(scope.projectDir, ".skaile", "store-cache"));
|
|
1333
|
+
out.push(path23__default.join(scope.projectDir, ".skaile", "repos"));
|
|
1289
1334
|
if (scope.global) {
|
|
1290
1335
|
out.push(globalCacheRoot());
|
|
1291
1336
|
const home = globalSkaileDir();
|
|
1292
|
-
out.push(
|
|
1293
|
-
out.push(
|
|
1337
|
+
out.push(path23__default.join(home, "repos"));
|
|
1338
|
+
out.push(path23__default.join(home, "catalog-cache"));
|
|
1294
1339
|
}
|
|
1295
1340
|
return out;
|
|
1296
1341
|
}
|
|
@@ -1304,7 +1349,7 @@ function dirSize(target) {
|
|
|
1304
1349
|
function dirSizeOfDir(dir) {
|
|
1305
1350
|
let total = 0;
|
|
1306
1351
|
for (const ent of readdirSync(dir, { withFileTypes: true })) {
|
|
1307
|
-
const child =
|
|
1352
|
+
const child = path23__default.join(dir, ent.name);
|
|
1308
1353
|
if (ent.isSymbolicLink()) continue;
|
|
1309
1354
|
if (ent.isDirectory()) total += dirSizeOfDir(child);
|
|
1310
1355
|
else if (ent.isFile()) total += statSync(child).size;
|
|
@@ -1330,7 +1375,7 @@ function makeCacheCommand() {
|
|
|
1330
1375
|
const cmd = new Command("cache").description("Inspect and reclaim the re-derivable cache");
|
|
1331
1376
|
cmd.command("clean").description("Remove the project cache (.skaile/cache); --global also clears ~/.skaile/cache").option("--global", "Also clear the global cache (sources + catalog) and legacy dirs").option("--dry-run", "Show what would be removed without doing it").option("-y, --yes", "Skip confirmation prompt").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
1332
1377
|
const targets = collectCacheTargets({
|
|
1333
|
-
projectDir:
|
|
1378
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
1334
1379
|
global: opts.global
|
|
1335
1380
|
}).filter((t) => existsSync(t));
|
|
1336
1381
|
if (targets.length === 0) {
|
|
@@ -1360,12 +1405,12 @@ function makeCacheCommand() {
|
|
|
1360
1405
|
for (const r of removed) logOk(`Removed ${r}`);
|
|
1361
1406
|
});
|
|
1362
1407
|
cmd.command("dir").description("Print the resolved cache roots").option("--global", "Include the global cache root").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1363
|
-
console.log(
|
|
1408
|
+
console.log(path23__default.join(path23__default.resolve(opts.projectDir), ".skaile", "cache"));
|
|
1364
1409
|
if (opts.global) console.log(globalCacheRoot());
|
|
1365
1410
|
});
|
|
1366
1411
|
cmd.command("size").description("Show cache disk usage per directory").option("--global", "Include the global cache").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1367
1412
|
const targets = collectCacheTargets({
|
|
1368
|
-
projectDir:
|
|
1413
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
1369
1414
|
global: opts.global
|
|
1370
1415
|
});
|
|
1371
1416
|
console.log();
|
|
@@ -1381,7 +1426,7 @@ function makeCatalogCommand() {
|
|
|
1381
1426
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
1382
1427
|
catalog.command("test").description("Probe the configured catalog source and report status").option("--project-dir <path>", "Project directory (for project-level config overlay)").option("--url <url>", "Override the catalog URL for this probe").option("--force", "Probe the network even in air-gapped mode (cache_ttl: 0)").action(async (opts) => {
|
|
1383
1428
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
1384
|
-
const projectDir = opts.projectDir ?
|
|
1429
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
|
|
1385
1430
|
const cfg = resolveConfig({ projectDir });
|
|
1386
1431
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
1387
1432
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
@@ -1399,7 +1444,7 @@ function makeCatalogCommand() {
|
|
|
1399
1444
|
});
|
|
1400
1445
|
catalog.command("info").description("Print the resolved catalog configuration (url, framing, cacheTtlMs)").option("--project-dir <path>", "Project directory (for project-level config overlay)").action(async (opts) => {
|
|
1401
1446
|
const { resolveConfig } = await import('../library/index.js');
|
|
1402
|
-
const projectDir = opts.projectDir ?
|
|
1447
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : void 0;
|
|
1403
1448
|
const cfg = resolveConfig({ projectDir });
|
|
1404
1449
|
console.log(`url: ${cfg.catalog.url}`);
|
|
1405
1450
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -1408,7 +1453,7 @@ function makeCatalogCommand() {
|
|
|
1408
1453
|
return catalog;
|
|
1409
1454
|
}
|
|
1410
1455
|
async function runLocalCatalogTest(projectDir) {
|
|
1411
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
1456
|
+
const { resolveCatalogSource } = await import('../open-library-P3D337NH.js');
|
|
1412
1457
|
let resolved;
|
|
1413
1458
|
try {
|
|
1414
1459
|
resolved = await resolveCatalogSource({ projectDir });
|
|
@@ -1552,8 +1597,8 @@ async function scanLibraryFlowEntries() {
|
|
|
1552
1597
|
const indexPath = resolveIndexPath();
|
|
1553
1598
|
if (!existsSync(indexPath)) return entries;
|
|
1554
1599
|
const [{ authoringLibraries }, { getKindRegistry: getKindRegistry2 }] = await Promise.all([
|
|
1555
|
-
import('../open-library-
|
|
1556
|
-
import('../open-registry-
|
|
1600
|
+
import('../open-library-P3D337NH.js'),
|
|
1601
|
+
import('../open-registry-Z3P2X2AB.js')
|
|
1557
1602
|
]);
|
|
1558
1603
|
const index = new LocalIndex({ indexPath });
|
|
1559
1604
|
try {
|
|
@@ -1610,11 +1655,11 @@ function findSkills() {
|
|
|
1610
1655
|
return deduped;
|
|
1611
1656
|
}
|
|
1612
1657
|
function walkSkills(dir, out) {
|
|
1613
|
-
for (const entry of
|
|
1614
|
-
const full =
|
|
1658
|
+
for (const entry of fs9__default.readdirSync(dir, { withFileTypes: true })) {
|
|
1659
|
+
const full = path23__default.join(dir, entry.name);
|
|
1615
1660
|
if (entry.isDirectory()) {
|
|
1616
|
-
const skillMd =
|
|
1617
|
-
if (
|
|
1661
|
+
const skillMd = path23__default.join(full, "SKILL.md");
|
|
1662
|
+
if (fs9__default.existsSync(skillMd)) {
|
|
1618
1663
|
out.push({ name: entry.name, path: full, skillPath: skillMd });
|
|
1619
1664
|
} else {
|
|
1620
1665
|
walkSkills(full, out);
|
|
@@ -1635,10 +1680,10 @@ function resolveFlowIds() {
|
|
|
1635
1680
|
}
|
|
1636
1681
|
}
|
|
1637
1682
|
function resolveSessionIds(projectDir) {
|
|
1638
|
-
const sessionsDir =
|
|
1639
|
-
if (!
|
|
1683
|
+
const sessionsDir = path23__default.join(projectDir, ".skaile", "sessions");
|
|
1684
|
+
if (!fs9__default.existsSync(sessionsDir)) return [];
|
|
1640
1685
|
try {
|
|
1641
|
-
return
|
|
1686
|
+
return fs9__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
1642
1687
|
} catch {
|
|
1643
1688
|
return [];
|
|
1644
1689
|
}
|
|
@@ -1777,7 +1822,7 @@ function printResolvedPathsSection(config) {
|
|
|
1777
1822
|
console.log(` ${S.label("prompts:".padEnd(16))} ${config.promptsDir ?? paths.promptsDir}`);
|
|
1778
1823
|
}
|
|
1779
1824
|
async function showConfig(opts) {
|
|
1780
|
-
const projectDir = opts.projectDir ?
|
|
1825
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
|
|
1781
1826
|
let config;
|
|
1782
1827
|
let wsDefaults;
|
|
1783
1828
|
try {
|
|
@@ -1822,13 +1867,13 @@ function makeConfigCommand() {
|
|
|
1822
1867
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
1823
1868
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action((opts) => showConfig(opts));
|
|
1824
1869
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
1825
|
-
const projectDir = opts.projectDir ?
|
|
1870
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
|
|
1826
1871
|
const config = await resolveSettings(projectDir);
|
|
1827
1872
|
const value = config[key];
|
|
1828
1873
|
console.log(value ?? S.dim("(not set)"));
|
|
1829
1874
|
});
|
|
1830
1875
|
cmd.command("set <key> <value>").description("Set a personal config value (driver, model, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
1831
|
-
const projectDir = opts.projectDir ?
|
|
1876
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
|
|
1832
1877
|
if (key === "provider" || key === "cloud" || key === "cloudConfig") {
|
|
1833
1878
|
logErr(
|
|
1834
1879
|
`'${key}' is no longer a setting \u2014 an endpoint is an AI provider registry entry and a session selects one with a model reference.
|
|
@@ -2168,8 +2213,8 @@ function makeConnectorCommand() {
|
|
|
2168
2213
|
async (driver, opts) => {
|
|
2169
2214
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
2170
2215
|
const { scanDirectory: scanDirectory2, factoryAssetRoots: factoryAssetRoots2, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2171
|
-
const projectDir =
|
|
2172
|
-
const yamlPath =
|
|
2216
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2217
|
+
const yamlPath = path23__default.join(projectDir, "skaile.yaml");
|
|
2173
2218
|
if (!existsSync(yamlPath)) {
|
|
2174
2219
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
2175
2220
|
process.exit(1);
|
|
@@ -2229,8 +2274,8 @@ ${installResult.output}`);
|
|
|
2229
2274
|
);
|
|
2230
2275
|
cmd.command("remove <id>").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Remove a connector from skaile.yaml by its instance ID").action(async (id, opts) => {
|
|
2231
2276
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
2232
|
-
const projectDir =
|
|
2233
|
-
const yamlPath =
|
|
2277
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2278
|
+
const yamlPath = path23__default.join(projectDir, "skaile.yaml");
|
|
2234
2279
|
if (!existsSync(yamlPath)) {
|
|
2235
2280
|
logErr("No skaile.yaml found in current directory.");
|
|
2236
2281
|
process.exit(1);
|
|
@@ -2247,7 +2292,7 @@ ${installResult.output}`);
|
|
|
2247
2292
|
cmd.command("status [id]").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Connect and report health status for one or all connectors").action(async (id, opts) => {
|
|
2248
2293
|
const res = await import('../connectors/index.js');
|
|
2249
2294
|
res.registerBuiltinConnectors();
|
|
2250
|
-
const projectDir =
|
|
2295
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2251
2296
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
2252
2297
|
if (declarations.length === 0) {
|
|
2253
2298
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -2271,7 +2316,7 @@ ${installResult.output}`);
|
|
|
2271
2316
|
await manager.disconnectAll();
|
|
2272
2317
|
});
|
|
2273
2318
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
2274
|
-
const projectDir =
|
|
2319
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2275
2320
|
const manager = await connectConnectors(projectDir);
|
|
2276
2321
|
try {
|
|
2277
2322
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -2280,7 +2325,7 @@ ${installResult.output}`);
|
|
|
2280
2325
|
}
|
|
2281
2326
|
});
|
|
2282
2327
|
cmd.command("sync [id]").description("Re-sync a filesystem-face connector or all of them (git pull, S3 refresh, etc.)").option("--all", "Sync all connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2283
|
-
const projectDir =
|
|
2328
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2284
2329
|
const manager = await connectConnectors(projectDir);
|
|
2285
2330
|
try {
|
|
2286
2331
|
if (opts.all) {
|
|
@@ -2304,7 +2349,7 @@ ${installResult.output}`);
|
|
|
2304
2349
|
}
|
|
2305
2350
|
});
|
|
2306
2351
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
2307
|
-
const projectDir =
|
|
2352
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2308
2353
|
const manager = await connectConnectors(projectDir);
|
|
2309
2354
|
try {
|
|
2310
2355
|
if (!manager.has(id)) {
|
|
@@ -2319,7 +2364,7 @@ ${installResult.output}`);
|
|
|
2319
2364
|
}
|
|
2320
2365
|
});
|
|
2321
2366
|
cmd.command("read <id> <resource-path>").description("Read content from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2322
|
-
const projectDir =
|
|
2367
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2323
2368
|
const manager = await connectConnectors(projectDir);
|
|
2324
2369
|
try {
|
|
2325
2370
|
const content = await manager.read(id, resourcePath);
|
|
@@ -2329,7 +2374,7 @@ ${installResult.output}`);
|
|
|
2329
2374
|
}
|
|
2330
2375
|
});
|
|
2331
2376
|
cmd.command("write <id> <resource-path> <content>").description("Write content to a connector at a path").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, content, opts) => {
|
|
2332
|
-
const projectDir =
|
|
2377
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2333
2378
|
const manager = await connectConnectors(projectDir);
|
|
2334
2379
|
try {
|
|
2335
2380
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -2339,7 +2384,7 @@ ${installResult.output}`);
|
|
|
2339
2384
|
}
|
|
2340
2385
|
});
|
|
2341
2386
|
cmd.command("entries <id> [resource-path]").description("List entries in a connector (files, keys, rows, etc)").option("--project-dir <path>", "Workspace directory", process.cwd()).option("--recursive", "Include nested entries").option("--limit <n>", "Maximum entries to return", parsePositiveIntOption).action(async (id, resourcePath, opts) => {
|
|
2342
|
-
const projectDir =
|
|
2387
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2343
2388
|
const manager = await connectConnectors(projectDir);
|
|
2344
2389
|
try {
|
|
2345
2390
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -2352,7 +2397,7 @@ ${installResult.output}`);
|
|
|
2352
2397
|
}
|
|
2353
2398
|
});
|
|
2354
2399
|
cmd.command("search <id> <query>").description("Search within a connector for matching content").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, query, opts) => {
|
|
2355
|
-
const projectDir =
|
|
2400
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2356
2401
|
const manager = await connectConnectors(projectDir);
|
|
2357
2402
|
try {
|
|
2358
2403
|
const results = await manager.search(id, query);
|
|
@@ -2362,7 +2407,7 @@ ${installResult.output}`);
|
|
|
2362
2407
|
}
|
|
2363
2408
|
});
|
|
2364
2409
|
cmd.command("delete <id> <resource-path>").description("Delete an entry from a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, resourcePath, opts) => {
|
|
2365
|
-
const projectDir =
|
|
2410
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2366
2411
|
const manager = await connectConnectors(projectDir);
|
|
2367
2412
|
try {
|
|
2368
2413
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -2372,7 +2417,7 @@ ${installResult.output}`);
|
|
|
2372
2417
|
}
|
|
2373
2418
|
});
|
|
2374
2419
|
cmd.command("run <id> <op> [args...]").description("Run a custom adapter operation (e.g. git log, sqlite query)").option("--project-dir <path>", "Workspace directory", process.cwd()).allowUnknownOption().action(async (id, op, args, opts) => {
|
|
2375
|
-
const projectDir =
|
|
2420
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2376
2421
|
const manager = await connectConnectors(projectDir);
|
|
2377
2422
|
try {
|
|
2378
2423
|
if (!manager.has(id)) {
|
|
@@ -2481,7 +2526,7 @@ function envRecord() {
|
|
|
2481
2526
|
async function buildDeployContext(projectDir) {
|
|
2482
2527
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2483
2528
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2484
|
-
const workspaceId = config.name ??
|
|
2529
|
+
const workspaceId = config.name ?? path23__default.basename(projectDir);
|
|
2485
2530
|
let log;
|
|
2486
2531
|
try {
|
|
2487
2532
|
const { createLogger } = await import('../core/logging.js');
|
|
@@ -2513,13 +2558,13 @@ async function ensureTargetsRegistered(projectDir) {
|
|
|
2513
2558
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2514
2559
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
2515
2560
|
if (config.plugins && config.plugins.length > 0) {
|
|
2516
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
2561
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-WI4MZJLP.js');
|
|
2517
2562
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
2518
2563
|
for (const f of result.failed) logWarn(f.error);
|
|
2519
2564
|
}
|
|
2520
2565
|
}
|
|
2521
2566
|
async function runUp(opts) {
|
|
2522
|
-
const projectDir =
|
|
2567
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2523
2568
|
await ensureTargetsRegistered(projectDir);
|
|
2524
2569
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
2525
2570
|
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
@@ -2587,7 +2632,7 @@ async function restoreFromHandle(projectDir) {
|
|
|
2587
2632
|
return { target, handle, ctx };
|
|
2588
2633
|
}
|
|
2589
2634
|
async function runDown(opts) {
|
|
2590
|
-
const projectDir =
|
|
2635
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2591
2636
|
const restored = await restoreFromHandle(projectDir);
|
|
2592
2637
|
if (!restored) return;
|
|
2593
2638
|
await restored.handle.stop();
|
|
@@ -2596,7 +2641,7 @@ async function runDown(opts) {
|
|
|
2596
2641
|
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
2597
2642
|
}
|
|
2598
2643
|
async function runStatus(opts) {
|
|
2599
|
-
const projectDir =
|
|
2644
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2600
2645
|
const restored = await restoreFromHandle(projectDir);
|
|
2601
2646
|
if (!restored) return;
|
|
2602
2647
|
const health = await restored.handle.health();
|
|
@@ -2610,7 +2655,7 @@ async function runStatus(opts) {
|
|
|
2610
2655
|
console.log();
|
|
2611
2656
|
}
|
|
2612
2657
|
async function runLogs(opts) {
|
|
2613
|
-
const projectDir =
|
|
2658
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
2614
2659
|
const restored = await restoreFromHandle(projectDir);
|
|
2615
2660
|
if (!restored) return;
|
|
2616
2661
|
if (!restored.handle.logs) {
|
|
@@ -2636,7 +2681,7 @@ function makeDiffCommand() {
|
|
|
2636
2681
|
return new Command("diff").description("Show changes between deployed and source versions").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
2637
2682
|
const am2 = new AssetManager({
|
|
2638
2683
|
registry: getKindRegistry(),
|
|
2639
|
-
projectDir:
|
|
2684
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
2640
2685
|
});
|
|
2641
2686
|
const result = await am2.diff(ref);
|
|
2642
2687
|
switch (result.status) {
|
|
@@ -2659,7 +2704,7 @@ function makeDiffCommand() {
|
|
|
2659
2704
|
function makeFlowCommand() {
|
|
2660
2705
|
const cmd = new Command("flow").description("Manage flows");
|
|
2661
2706
|
cmd.command("list").description("List available flows").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2662
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2707
|
+
const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
|
|
2663
2708
|
if (flows.length === 0) {
|
|
2664
2709
|
logInfo("No flows found.");
|
|
2665
2710
|
return;
|
|
@@ -2674,7 +2719,7 @@ function makeFlowCommand() {
|
|
|
2674
2719
|
console.log();
|
|
2675
2720
|
});
|
|
2676
2721
|
cmd.command("show <id>").description("Show flow details and node graph").option("--project-dir <path>", "Project directory", process.cwd()).action(async (id, opts) => {
|
|
2677
|
-
const flows = await discoverFlowsWithLibraries(
|
|
2722
|
+
const flows = await discoverFlowsWithLibraries(path23__default.resolve(opts.projectDir));
|
|
2678
2723
|
const flow = flows.find((f) => f.id === id);
|
|
2679
2724
|
if (!flow) {
|
|
2680
2725
|
logErr(`Flow not found: ${id}`);
|
|
@@ -2708,7 +2753,7 @@ function makeHistoryCommand() {
|
|
|
2708
2753
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
2709
2754
|
const am2 = new AssetManager({
|
|
2710
2755
|
registry: getKindRegistry(),
|
|
2711
|
-
projectDir:
|
|
2756
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
2712
2757
|
});
|
|
2713
2758
|
const limit = parseInt(limitStr, 10) || 20;
|
|
2714
2759
|
const entries = am2.history(limit);
|
|
@@ -2731,7 +2776,7 @@ function makeHistoryCommand() {
|
|
|
2731
2776
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
2732
2777
|
const am2 = new AssetManager({
|
|
2733
2778
|
registry: getKindRegistry(),
|
|
2734
|
-
projectDir:
|
|
2779
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
2735
2780
|
});
|
|
2736
2781
|
am2.clearHistory();
|
|
2737
2782
|
logOk("History cleared.");
|
|
@@ -2745,7 +2790,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
2745
2790
|
env: {}
|
|
2746
2791
|
};
|
|
2747
2792
|
function pluginDir(projectDir) {
|
|
2748
|
-
return
|
|
2793
|
+
return path23__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2749
2794
|
}
|
|
2750
2795
|
async function readJsonStrict(p6) {
|
|
2751
2796
|
let raw;
|
|
@@ -2763,7 +2808,7 @@ async function readJsonStrict(p6) {
|
|
|
2763
2808
|
}
|
|
2764
2809
|
}
|
|
2765
2810
|
async function writeJson(p6, value) {
|
|
2766
|
-
await fs6.mkdir(
|
|
2811
|
+
await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
|
|
2767
2812
|
await fs6.writeFile(p6, `${JSON.stringify(value, null, 2)}
|
|
2768
2813
|
`);
|
|
2769
2814
|
}
|
|
@@ -2771,8 +2816,8 @@ async function copyDir(src, dest) {
|
|
|
2771
2816
|
await fs6.mkdir(dest, { recursive: true });
|
|
2772
2817
|
const entries = await fs6.readdir(src, { withFileTypes: true });
|
|
2773
2818
|
for (const entry of entries) {
|
|
2774
|
-
const srcPath =
|
|
2775
|
-
const destPath =
|
|
2819
|
+
const srcPath = path23__default.join(src, entry.name);
|
|
2820
|
+
const destPath = path23__default.join(dest, entry.name);
|
|
2776
2821
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2777
2822
|
else await fs6.copyFile(srcPath, destPath);
|
|
2778
2823
|
}
|
|
@@ -2781,14 +2826,14 @@ async function install(projectDir, opts) {
|
|
|
2781
2826
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2782
2827
|
}
|
|
2783
2828
|
async function installMcp(projectDir) {
|
|
2784
|
-
const mcpPath =
|
|
2829
|
+
const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
|
|
2785
2830
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2786
2831
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2787
2832
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2788
2833
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2789
2834
|
let warning;
|
|
2790
2835
|
if (previous && !matches) {
|
|
2791
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
2836
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path23__default.relative(projectDir, mcpPath)}`;
|
|
2792
2837
|
}
|
|
2793
2838
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2794
2839
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2797,15 +2842,15 @@ async function installMcp(projectDir) {
|
|
|
2797
2842
|
async function installFullPlugin(projectDir) {
|
|
2798
2843
|
const dir = pluginDir(projectDir);
|
|
2799
2844
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2800
|
-
const dest =
|
|
2801
|
-
await fs6.mkdir(
|
|
2845
|
+
const dest = path23__default.join(dir, rel);
|
|
2846
|
+
await fs6.mkdir(path23__default.dirname(dest), { recursive: true });
|
|
2802
2847
|
await fs6.writeFile(dest, content);
|
|
2803
2848
|
}
|
|
2804
|
-
const projectSkillsDir =
|
|
2849
|
+
const projectSkillsDir = path23__default.join(projectDir, ".skaile", "skills");
|
|
2805
2850
|
if (existsSync(projectSkillsDir)) {
|
|
2806
|
-
await copyDir(projectSkillsDir,
|
|
2851
|
+
await copyDir(projectSkillsDir, path23__default.join(dir, "skills"));
|
|
2807
2852
|
}
|
|
2808
|
-
const settingsPath =
|
|
2853
|
+
const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
|
|
2809
2854
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2810
2855
|
const plugins = settings.plugins ?? [];
|
|
2811
2856
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2813,8 +2858,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2813
2858
|
return { changed: true, method: "plugin" };
|
|
2814
2859
|
}
|
|
2815
2860
|
async function uninstall(projectDir) {
|
|
2816
|
-
const settingsPath =
|
|
2817
|
-
const mcpPath =
|
|
2861
|
+
const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
|
|
2862
|
+
const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
|
|
2818
2863
|
const dir = pluginDir(projectDir);
|
|
2819
2864
|
let changed = false;
|
|
2820
2865
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -2848,12 +2893,12 @@ async function uninstall(projectDir) {
|
|
|
2848
2893
|
async function detectInstall(projectDir) {
|
|
2849
2894
|
const dir = pluginDir(projectDir);
|
|
2850
2895
|
const settings = await readJsonStrict(
|
|
2851
|
-
|
|
2896
|
+
path23__default.join(projectDir, ".claude", "settings.json")
|
|
2852
2897
|
);
|
|
2853
|
-
if (existsSync(
|
|
2898
|
+
if (existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
2854
2899
|
return { method: "plugin", pluginPath: dir };
|
|
2855
2900
|
}
|
|
2856
|
-
const mcp = await readJsonStrict(
|
|
2901
|
+
const mcp = await readJsonStrict(path23__default.join(projectDir, ".claude", "mcp.json"));
|
|
2857
2902
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
2858
2903
|
return { method: "mcp" };
|
|
2859
2904
|
}
|
|
@@ -2862,7 +2907,7 @@ async function detectInstall(projectDir) {
|
|
|
2862
2907
|
async function enable(projectDir) {
|
|
2863
2908
|
const detected = await detectInstall(projectDir);
|
|
2864
2909
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2865
|
-
const settingsPath =
|
|
2910
|
+
const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
|
|
2866
2911
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2867
2912
|
if (detected.method === "plugin") {
|
|
2868
2913
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -2884,7 +2929,7 @@ async function enable(projectDir) {
|
|
|
2884
2929
|
async function disable(projectDir) {
|
|
2885
2930
|
const detected = await detectInstall(projectDir);
|
|
2886
2931
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
2887
|
-
const settingsPath =
|
|
2932
|
+
const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
|
|
2888
2933
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2889
2934
|
if (detected.method === "plugin") {
|
|
2890
2935
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -2904,12 +2949,12 @@ async function disable(projectDir) {
|
|
|
2904
2949
|
return { changed: true };
|
|
2905
2950
|
}
|
|
2906
2951
|
async function status(projectDir) {
|
|
2907
|
-
const settingsPath =
|
|
2908
|
-
const mcpPath =
|
|
2952
|
+
const settingsPath = path23__default.join(projectDir, ".claude", "settings.json");
|
|
2953
|
+
const mcpPath = path23__default.join(projectDir, ".claude", "mcp.json");
|
|
2909
2954
|
const dir = pluginDir(projectDir);
|
|
2910
2955
|
const settings = await readJsonStrict(settingsPath);
|
|
2911
2956
|
const mcp = await readJsonStrict(mcpPath);
|
|
2912
|
-
const pluginInstalled = !!(existsSync(
|
|
2957
|
+
const pluginInstalled = !!(existsSync(path23__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
2913
2958
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
2914
2959
|
if (!pluginInstalled && !mcpInstalled) {
|
|
2915
2960
|
return {
|
|
@@ -2927,7 +2972,7 @@ async function status(projectDir) {
|
|
|
2927
2972
|
installed: "yes",
|
|
2928
2973
|
enabled: disabled2 ? "no" : "yes",
|
|
2929
2974
|
method: "plugin",
|
|
2930
|
-
location:
|
|
2975
|
+
location: path23__default.relative(projectDir, dir)
|
|
2931
2976
|
};
|
|
2932
2977
|
}
|
|
2933
2978
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -2936,7 +2981,7 @@ async function status(projectDir) {
|
|
|
2936
2981
|
installed: "yes",
|
|
2937
2982
|
enabled: disabled ? "no" : "yes",
|
|
2938
2983
|
method: "mcp",
|
|
2939
|
-
location:
|
|
2984
|
+
location: path23__default.relative(projectDir, mcpPath)
|
|
2940
2985
|
};
|
|
2941
2986
|
}
|
|
2942
2987
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -2963,7 +3008,7 @@ async function readConfig(p6) {
|
|
|
2963
3008
|
}
|
|
2964
3009
|
}
|
|
2965
3010
|
async function writeConfig(p6, value) {
|
|
2966
|
-
await fs6.mkdir(
|
|
3011
|
+
await fs6.mkdir(path23__default.dirname(p6), { recursive: true });
|
|
2967
3012
|
const cleaned = {};
|
|
2968
3013
|
for (const [k, v] of Object.entries(value)) {
|
|
2969
3014
|
if (v === void 0) continue;
|
|
@@ -2972,7 +3017,7 @@ async function writeConfig(p6, value) {
|
|
|
2972
3017
|
await fs6.writeFile(p6, stringify$1(cleaned));
|
|
2973
3018
|
}
|
|
2974
3019
|
function configPath(projectDir) {
|
|
2975
|
-
return
|
|
3020
|
+
return path23__default.join(projectDir, ".codex", "config.toml");
|
|
2976
3021
|
}
|
|
2977
3022
|
async function install2(projectDir) {
|
|
2978
3023
|
const p6 = configPath(projectDir);
|
|
@@ -2983,7 +3028,7 @@ async function install2(projectDir) {
|
|
|
2983
3028
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
2984
3029
|
let warning;
|
|
2985
3030
|
if (previous && !matches) {
|
|
2986
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3031
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path23__default.relative(projectDir, p6)}`;
|
|
2987
3032
|
}
|
|
2988
3033
|
if (matches) return { changed: false, method: "toml" };
|
|
2989
3034
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3024,12 +3069,12 @@ async function status2(projectDir) {
|
|
|
3024
3069
|
installed: "yes",
|
|
3025
3070
|
enabled: "n/a",
|
|
3026
3071
|
method: "mcp",
|
|
3027
|
-
location:
|
|
3072
|
+
location: path23__default.relative(projectDir, p6)
|
|
3028
3073
|
};
|
|
3029
3074
|
}
|
|
3030
3075
|
async function install3(projectDir) {
|
|
3031
|
-
const extDir =
|
|
3032
|
-
const extPath =
|
|
3076
|
+
const extDir = path23__default.join(projectDir, ".omp", "extensions");
|
|
3077
|
+
const extPath = path23__default.join(extDir, "skaile.ts");
|
|
3033
3078
|
await fs6.mkdir(extDir, { recursive: true });
|
|
3034
3079
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3035
3080
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
@@ -3044,7 +3089,7 @@ async function install3(projectDir) {
|
|
|
3044
3089
|
return { changed: true, method: "generated" };
|
|
3045
3090
|
}
|
|
3046
3091
|
async function uninstall3(projectDir) {
|
|
3047
|
-
const extPath =
|
|
3092
|
+
const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3048
3093
|
try {
|
|
3049
3094
|
await fs6.unlink(extPath);
|
|
3050
3095
|
return { changed: true };
|
|
@@ -3053,14 +3098,14 @@ async function uninstall3(projectDir) {
|
|
|
3053
3098
|
}
|
|
3054
3099
|
}
|
|
3055
3100
|
async function status3(projectDir) {
|
|
3056
|
-
const extPath =
|
|
3101
|
+
const extPath = path23__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3057
3102
|
if (existsSync(extPath)) {
|
|
3058
3103
|
return {
|
|
3059
3104
|
harness: "omp",
|
|
3060
3105
|
installed: "yes",
|
|
3061
3106
|
enabled: "n/a",
|
|
3062
3107
|
method: "extension",
|
|
3063
|
-
location:
|
|
3108
|
+
location: path23__default.relative(projectDir, extPath)
|
|
3064
3109
|
};
|
|
3065
3110
|
}
|
|
3066
3111
|
return {
|
|
@@ -3123,7 +3168,7 @@ async function installCodex(projectDir) {
|
|
|
3123
3168
|
console.log(` ${S.dim("\u2192")} Restart Codex CLI to pick up the change.`);
|
|
3124
3169
|
}
|
|
3125
3170
|
async function runInstall(opts) {
|
|
3126
|
-
const projectDir =
|
|
3171
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
3127
3172
|
const targets = resolveDriver(opts.driver);
|
|
3128
3173
|
let exitCode = 0;
|
|
3129
3174
|
if (targets.includes("claude-code")) {
|
|
@@ -3157,7 +3202,7 @@ async function uninstallCodex(projectDir) {
|
|
|
3157
3202
|
else logInfo(`codex: not installed`);
|
|
3158
3203
|
}
|
|
3159
3204
|
async function runUninstall(opts) {
|
|
3160
|
-
const projectDir =
|
|
3205
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
3161
3206
|
const targets = resolveDriver(opts.driver);
|
|
3162
3207
|
let exitCode = 0;
|
|
3163
3208
|
if (targets.includes("claude-code")) {
|
|
@@ -3200,7 +3245,7 @@ async function toggleTarget(t, projectDir, action3) {
|
|
|
3200
3245
|
});
|
|
3201
3246
|
}
|
|
3202
3247
|
async function runToggle(opts, action3) {
|
|
3203
|
-
const projectDir =
|
|
3248
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
3204
3249
|
const requestedAll = opts.driver === "all";
|
|
3205
3250
|
const targets = resolveDriver(opts.driver);
|
|
3206
3251
|
const usageError = checkToggleSupported(targets, requestedAll, action3);
|
|
@@ -3212,7 +3257,7 @@ async function runToggle(opts, action3) {
|
|
|
3212
3257
|
return exitCode;
|
|
3213
3258
|
}
|
|
3214
3259
|
async function runStatus2(opts) {
|
|
3215
|
-
const projectDir =
|
|
3260
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
3216
3261
|
const targets = resolveDriver(opts.driver);
|
|
3217
3262
|
const rows = [];
|
|
3218
3263
|
let exitCode = 0;
|
|
@@ -3283,7 +3328,7 @@ async function runHook(event) {
|
|
|
3283
3328
|
await plugin.shutdown();
|
|
3284
3329
|
return;
|
|
3285
3330
|
}
|
|
3286
|
-
const store = new PluginStore(
|
|
3331
|
+
const store = new PluginStore(path23__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3287
3332
|
await store.load();
|
|
3288
3333
|
const status4 = store.get("connector:status");
|
|
3289
3334
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3347,6 +3392,25 @@ function exitOnSyncError(err2) {
|
|
|
3347
3392
|
logErr(err2 instanceof Error ? err2.message : String(err2));
|
|
3348
3393
|
process.exit(1);
|
|
3349
3394
|
}
|
|
3395
|
+
var UNFINISHED_GIT_ENTRIES = {
|
|
3396
|
+
MERGE_HEAD: "a merge in progress",
|
|
3397
|
+
REBASE_HEAD: "a rebase in progress",
|
|
3398
|
+
"rebase-merge": "a rebase in progress",
|
|
3399
|
+
"rebase-apply": "a rebase in progress",
|
|
3400
|
+
CHERRY_PICK_HEAD: "a cherry-pick in progress",
|
|
3401
|
+
REVERT_HEAD: "a revert in progress"
|
|
3402
|
+
};
|
|
3403
|
+
function unfinishedGitState(dir) {
|
|
3404
|
+
const unmerged = spawnSync("git", ["ls-files", "-u"], { cwd: dir, encoding: "utf-8" });
|
|
3405
|
+
if (unmerged.status !== 0) return "the git index could not be read";
|
|
3406
|
+
if (unmerged.stdout.trim() !== "") return "unmerged files";
|
|
3407
|
+
for (const [entry, state2] of Object.entries(UNFINISHED_GIT_ENTRIES)) {
|
|
3408
|
+
const p6 = spawnSync("git", ["rev-parse", "--git-path", entry], { cwd: dir, encoding: "utf-8" });
|
|
3409
|
+
if (p6.status !== 0) return "the git directory could not be read";
|
|
3410
|
+
if (fs9.existsSync(path23.resolve(dir, p6.stdout.trim()))) return state2;
|
|
3411
|
+
}
|
|
3412
|
+
return null;
|
|
3413
|
+
}
|
|
3350
3414
|
function assertManifestEditableOrExit(libraryPath) {
|
|
3351
3415
|
try {
|
|
3352
3416
|
assertManifestEditable(libraryPath);
|
|
@@ -3356,18 +3420,18 @@ function assertManifestEditableOrExit(libraryPath) {
|
|
|
3356
3420
|
}
|
|
3357
3421
|
async function assertLibraryPathFree(manager, dir, exceptId) {
|
|
3358
3422
|
const clash = (await manager.listLibraries()).find(
|
|
3359
|
-
(l) => l.id !== exceptId &&
|
|
3423
|
+
(l) => l.id !== exceptId && path23.resolve(l.path) === dir
|
|
3360
3424
|
);
|
|
3361
3425
|
if (clash) throw new Error(`${dir} is already registered as library "${clash.name}".`);
|
|
3362
3426
|
}
|
|
3363
3427
|
function canonicalDir(dir) {
|
|
3364
|
-
const abs =
|
|
3365
|
-
return
|
|
3428
|
+
const abs = path23.resolve(dir);
|
|
3429
|
+
return fs9.existsSync(abs) ? fs9.realpathSync(abs) : abs;
|
|
3366
3430
|
}
|
|
3367
3431
|
function refuseGlobalInstallFolder(name, dir) {
|
|
3368
3432
|
const reserved = globalInstallDir();
|
|
3369
|
-
const rel =
|
|
3370
|
-
const inside = rel === "" || !rel.startsWith("..") && !
|
|
3433
|
+
const rel = path23.relative(canonicalDir(reserved), canonicalDir(dir));
|
|
3434
|
+
const inside = rel === "" || !rel.startsWith("..") && !path23.isAbsolute(rel);
|
|
3371
3435
|
if (name === GLOBAL_INSTALL_DIR_NAME || inside) {
|
|
3372
3436
|
logErr(
|
|
3373
3437
|
`"${GLOBAL_INSTALL_DIR_NAME}" is reserved: ${reserved} holds assets from \`skaile install\`, not a library you author.`
|
|
@@ -3388,10 +3452,35 @@ function readOriginTracking(dir) {
|
|
|
3388
3452
|
}
|
|
3389
3453
|
function requireGitBackend(lib, verb) {
|
|
3390
3454
|
if (lib.backend !== "git") {
|
|
3391
|
-
logErr(
|
|
3455
|
+
logErr(
|
|
3456
|
+
`\`library ${verb}\` only applies to git-backed libraries. Run \`skaile library link ${lib.name} <url>\` to attach a remote first.`
|
|
3457
|
+
);
|
|
3392
3458
|
process.exit(1);
|
|
3393
3459
|
}
|
|
3394
3460
|
}
|
|
3461
|
+
function requireValidLibraryName(name) {
|
|
3462
|
+
try {
|
|
3463
|
+
assertValidLibraryName(name);
|
|
3464
|
+
} catch (err2) {
|
|
3465
|
+
exitOnSyncError(err2);
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
var LOCAL_OWNERSHIP_REASON = "ownership only governs sync with a git remote, and a local library is always owned by you.";
|
|
3469
|
+
function pruneEmptyLibraryParents(libPath) {
|
|
3470
|
+
const root = canonicalDir(resolveLibraryDir());
|
|
3471
|
+
let dir = path23.dirname(path23.resolve(libPath));
|
|
3472
|
+
for (; ; ) {
|
|
3473
|
+
const rel = path23.relative(root, canonicalDir(dir));
|
|
3474
|
+
if (rel === "" || rel.startsWith("..") || path23.isAbsolute(rel)) return;
|
|
3475
|
+
if (!fs9.existsSync(dir) || fs9.readdirSync(dir).length > 0) return;
|
|
3476
|
+
fs9.rmdirSync(dir);
|
|
3477
|
+
dir = path23.dirname(dir);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
async function warnIfNotGithubRemote(name, url) {
|
|
3481
|
+
const { isGithubRemote, notGithubRemoteMessage } = await import('../library-publish-FGXF5TJO.js');
|
|
3482
|
+
if (!isGithubRemote(url)) logWarn(notGithubRemoteMessage(name, url));
|
|
3483
|
+
}
|
|
3395
3484
|
function scaffoldLibraryFiles(dir, name) {
|
|
3396
3485
|
const readme = `# ${name}
|
|
3397
3486
|
|
|
@@ -3421,9 +3510,9 @@ by the same ref.
|
|
|
3421
3510
|
];
|
|
3422
3511
|
const written = [];
|
|
3423
3512
|
for (const [file, content] of files) {
|
|
3424
|
-
const target =
|
|
3425
|
-
if (
|
|
3426
|
-
|
|
3513
|
+
const target = path23.join(dir, file);
|
|
3514
|
+
if (fs9.existsSync(target)) continue;
|
|
3515
|
+
fs9.writeFileSync(target, content, "utf8");
|
|
3427
3516
|
written.push(file);
|
|
3428
3517
|
}
|
|
3429
3518
|
return written;
|
|
@@ -3486,22 +3575,23 @@ function makeLibraryCommand() {
|
|
|
3486
3575
|
});
|
|
3487
3576
|
cmd.command("init <name>").description("Create (or adopt) a library \u2014 default location ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--path <dir>", "Register the library at <dir> (created if missing) instead").option("--owner", "Mark as owner (the default)").option("--contributor", "Mark as contributor (needs --git or an existing git clone)").option("--reader", "Mark as reader (needs --git or an existing git clone)").action(
|
|
3488
3577
|
async (name, opts) => {
|
|
3578
|
+
requireValidLibraryName(name);
|
|
3489
3579
|
const flagged = ["owner", "contributor", "reader"].filter((o) => opts[o]);
|
|
3490
3580
|
if (flagged.length > 1) {
|
|
3491
3581
|
logErr("Pick one of --owner, --contributor, --reader.");
|
|
3492
3582
|
process.exit(1);
|
|
3493
3583
|
}
|
|
3494
3584
|
const ownership = flagged[0] ?? "owner";
|
|
3495
|
-
const libPath = opts.path ?
|
|
3585
|
+
const libPath = opts.path ? path23.resolve(opts.path) : path23.join(resolveLibraryDir(), name);
|
|
3496
3586
|
refuseGlobalInstallFolder(name, libPath);
|
|
3497
|
-
if (
|
|
3587
|
+
if (fs9.existsSync(libPath) && !fs9.statSync(libPath).isDirectory()) {
|
|
3498
3588
|
logErr(`${libPath} exists and is not a directory.`);
|
|
3499
3589
|
process.exit(1);
|
|
3500
3590
|
}
|
|
3501
3591
|
const adopted = opts.git ? null : readOriginTracking(libPath);
|
|
3502
3592
|
if (ownership !== "owner" && !opts.git && !adopted) {
|
|
3503
3593
|
logErr(
|
|
3504
|
-
`--${ownership} needs --git <url> or an existing git clone:
|
|
3594
|
+
`--${ownership} needs --git <url> or an existing git clone: ${LOCAL_OWNERSHIP_REASON}`
|
|
3505
3595
|
);
|
|
3506
3596
|
process.exit(1);
|
|
3507
3597
|
}
|
|
@@ -3522,15 +3612,17 @@ function makeLibraryCommand() {
|
|
|
3522
3612
|
`Could not clone ${opts.git}; initialised an empty repo with that origin instead. git said: ${reason}`
|
|
3523
3613
|
);
|
|
3524
3614
|
}
|
|
3615
|
+
await warnIfNotGithubRemote(name, opts.git);
|
|
3616
|
+
trackOriginBranch(libPath, branch);
|
|
3525
3617
|
backend = "git";
|
|
3526
3618
|
backendConfig = { url: opts.git, branch, authHint: "ssh" };
|
|
3527
3619
|
} else if (adopted) {
|
|
3528
3620
|
backend = "git";
|
|
3529
3621
|
backendConfig = { url: adopted.url, branch: adopted.branch, authHint: "ssh" };
|
|
3530
3622
|
} else {
|
|
3531
|
-
|
|
3623
|
+
fs9.mkdirSync(libPath, { recursive: true });
|
|
3532
3624
|
}
|
|
3533
|
-
const blank =
|
|
3625
|
+
const blank = fs9.readdirSync(libPath).every((entry) => entry === ".git");
|
|
3534
3626
|
const isDefault = !hasDefault && ownership !== "reader";
|
|
3535
3627
|
await manager.addLibrary({
|
|
3536
3628
|
name,
|
|
@@ -3557,6 +3649,13 @@ function makeLibraryCommand() {
|
|
|
3557
3649
|
}
|
|
3558
3650
|
if (!blank) {
|
|
3559
3651
|
const lib = await manager.requireLibrary(name);
|
|
3652
|
+
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3653
|
+
if (resolved.source === "manifest" && !isValidPublisher(resolved.publisher)) {
|
|
3654
|
+
logWarn(
|
|
3655
|
+
`${SKAILE_MANIFEST_FILENAME} declares publisher "${resolved.publisher}": ${PUBLISHER_HINT}. Fix it with \`skaile library set ${name} publisher=<name>\`.`
|
|
3656
|
+
);
|
|
3657
|
+
}
|
|
3658
|
+
warnLibraryNameFallback(name, resolved);
|
|
3560
3659
|
const res = await indexLibrary(lib, library);
|
|
3561
3660
|
for (const e of res.errors) logWarn(e);
|
|
3562
3661
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
@@ -3580,29 +3679,42 @@ function makeLibraryCommand() {
|
|
|
3580
3679
|
process.exit(1);
|
|
3581
3680
|
}
|
|
3582
3681
|
ensureGitRepo(lib.path, url, opts.branch);
|
|
3682
|
+
trackOriginBranch(lib.path, opts.branch, { fetch: true });
|
|
3583
3683
|
await manager.updateLibrary(name, {
|
|
3584
3684
|
backend: "git",
|
|
3585
3685
|
backendConfig: { url, branch: opts.branch, authHint: "ssh" }
|
|
3586
3686
|
});
|
|
3587
3687
|
logOk(`Library "${name}" linked to ${url}.`);
|
|
3688
|
+
await warnIfNotGithubRemote(name, url);
|
|
3588
3689
|
} catch (err2) {
|
|
3589
3690
|
exitOnSyncError(err2);
|
|
3590
3691
|
} finally {
|
|
3591
3692
|
close();
|
|
3592
3693
|
}
|
|
3593
3694
|
});
|
|
3594
|
-
cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(
|
|
3595
|
-
new Option("--kind <kind>", "Asset kind override").choices(getKindRegistry().getAllKinds())
|
|
3596
|
-
).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").option(
|
|
3695
|
+
cmd.command("create <kind> <name>").description("Scaffold a new asset inside the default (or named) library").addOption(new Option("--kind <kind>", "Asset kind override").choices([...SCAFFOLD_KINDS])).addOption(removedDomainOption()).option("--library <name>", "Target library (default: the default-marked one)").option("--dir <dir>", "Target directory inside the library (default: library root)").option("--publisher <name>", "Publisher for the new asset (default: the library's default)").option(
|
|
3597
3696
|
"--description <text>",
|
|
3598
3697
|
"Description for the asset's frontmatter \u2014 say what it does and when to use it (default: a TODO placeholder `skaile validate` rejects)"
|
|
3599
3698
|
).action(
|
|
3600
3699
|
async (kind, name, opts) => {
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3700
|
+
rejectRemovedDomainOption(opts);
|
|
3701
|
+
for (const k of [kind, opts.kind]) {
|
|
3702
|
+
if (k !== void 0 && !SCAFFOLD_KINDS.includes(k)) {
|
|
3703
|
+
logErr(`Cannot scaffold kind "${k}". Expected: ${SCAFFOLD_KINDS.join(", ")}.`);
|
|
3704
|
+
process.exit(1);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
if (!isValidAssetName(name)) {
|
|
3708
|
+
logErr(`Invalid asset name "${name}": ${ASSET_NAME_HINT}.`);
|
|
3604
3709
|
process.exit(1);
|
|
3605
3710
|
}
|
|
3711
|
+
if (opts.publisher !== void 0) {
|
|
3712
|
+
const bare = opts.publisher.trim().replace(/^@/, "");
|
|
3713
|
+
if (!isValidPublisher(bare)) {
|
|
3714
|
+
logErr(`Invalid publisher "${opts.publisher}": ${PUBLISHER_HINT}.`);
|
|
3715
|
+
process.exit(1);
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3606
3718
|
if (opts.description !== void 0) {
|
|
3607
3719
|
const len = opts.description.trim().length;
|
|
3608
3720
|
if (len === 0 || len > 1024) {
|
|
@@ -3616,7 +3728,13 @@ function makeLibraryCommand() {
|
|
|
3616
3728
|
assertManifestEditableOrExit(target.path);
|
|
3617
3729
|
const effectiveKind = opts.kind ?? kind;
|
|
3618
3730
|
const am2 = new AssetManager({ registry: getKindRegistry(), projectDir: process.cwd() });
|
|
3619
|
-
const
|
|
3731
|
+
const libRoot = path23.resolve(target.path);
|
|
3732
|
+
const destDir = opts.dir ? path23.resolve(libRoot, opts.dir) : libRoot;
|
|
3733
|
+
const relDest = path23.relative(libRoot, destDir);
|
|
3734
|
+
if (relDest === ".." || relDest.startsWith(`..${path23.sep}`) || path23.isAbsolute(relDest)) {
|
|
3735
|
+
logErr(`--dir "${opts.dir}" must stay inside the library (${libRoot}).`);
|
|
3736
|
+
process.exit(1);
|
|
3737
|
+
}
|
|
3620
3738
|
const res = am2.create(name, effectiveKind, destDir, { description: opts.description });
|
|
3621
3739
|
if (!res.ok) {
|
|
3622
3740
|
logErr(res.path);
|
|
@@ -3661,38 +3779,48 @@ function makeLibraryCommand() {
|
|
|
3661
3779
|
close();
|
|
3662
3780
|
}
|
|
3663
3781
|
});
|
|
3782
|
+
async function renameLibrary(manager, lib, newName) {
|
|
3783
|
+
requireValidLibraryName(newName);
|
|
3784
|
+
if (await manager.getLibrary(newName)) {
|
|
3785
|
+
logErr(`A library named "${newName}" is already registered.`);
|
|
3786
|
+
process.exit(1);
|
|
3787
|
+
}
|
|
3788
|
+
const newPath = path23.join(path23.dirname(lib.path), newName);
|
|
3789
|
+
refuseGlobalInstallFolder(newName, newPath);
|
|
3790
|
+
if (fs9.existsSync(newPath)) {
|
|
3791
|
+
logErr(`Target directory already exists: ${newPath}`);
|
|
3792
|
+
process.exit(1);
|
|
3793
|
+
}
|
|
3794
|
+
fs9.renameSync(lib.path, newPath);
|
|
3795
|
+
await manager.updateLibrary(lib.id, { name: newName, path: newPath });
|
|
3796
|
+
logOk(`Renamed ${lib.name} \u2192 ${newName}`);
|
|
3797
|
+
}
|
|
3664
3798
|
cmd.command("rename <old> <new>").description("Rename a library (also moves the directory)").action(async (oldName, newName) => {
|
|
3665
3799
|
const { manager, close } = await openLibraryManager();
|
|
3666
3800
|
try {
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
refuseGlobalInstallFolder(newName, newPath);
|
|
3671
|
-
if (fs11.existsSync(newPath)) {
|
|
3672
|
-
logErr(`Target directory already exists: ${newPath}`);
|
|
3673
|
-
process.exit(1);
|
|
3674
|
-
}
|
|
3675
|
-
fs11.renameSync(lib.path, newPath);
|
|
3676
|
-
await manager.updateLibrary(lib.id, { name: newName, path: newPath });
|
|
3677
|
-
logOk(`Renamed ${oldName} \u2192 ${newName}`);
|
|
3801
|
+
await renameLibrary(manager, await manager.requireLibrary(oldName), newName);
|
|
3802
|
+
} catch (err2) {
|
|
3803
|
+
exitOnSyncError(err2);
|
|
3678
3804
|
} finally {
|
|
3679
3805
|
close();
|
|
3680
3806
|
}
|
|
3681
3807
|
});
|
|
3682
3808
|
cmd.command("set <name> <field=value>").description(
|
|
3683
|
-
"Update a single library field (ownership, isDefault, path, publisher, backendConfig.<key>)"
|
|
3809
|
+
"Update a single library field (name, ownership, isDefault, path, publisher, backendConfig.<key>)"
|
|
3684
3810
|
).action(async (name, expr) => {
|
|
3685
3811
|
const [field, ...rest] = expr.split("=");
|
|
3812
|
+
if (field === "structure") {
|
|
3813
|
+
logErr(DOMAIN_REMOVED_HINT);
|
|
3814
|
+
process.exit(1);
|
|
3815
|
+
}
|
|
3686
3816
|
const value = rest.join("=");
|
|
3687
3817
|
const { manager, library, close } = await openLibraryManager();
|
|
3688
3818
|
try {
|
|
3689
3819
|
const lib = await manager.requireLibrary(name);
|
|
3690
3820
|
if (field === "publisher") {
|
|
3691
3821
|
const publisher = value.trim().replace(/^@/, "");
|
|
3692
|
-
if (
|
|
3693
|
-
logErr(
|
|
3694
|
-
`Invalid publisher "${value}": expected a bare name like "acme" (no @, /, # or spaces).`
|
|
3695
|
-
);
|
|
3822
|
+
if (!isValidPublisher(publisher)) {
|
|
3823
|
+
logErr(`Invalid publisher "${value}": ${PUBLISHER_HINT}.`);
|
|
3696
3824
|
process.exit(1);
|
|
3697
3825
|
}
|
|
3698
3826
|
if (lib.ownership === "reader") {
|
|
@@ -3709,11 +3837,42 @@ function makeLibraryCommand() {
|
|
|
3709
3837
|
return;
|
|
3710
3838
|
}
|
|
3711
3839
|
const patch = {};
|
|
3712
|
-
if (field === "
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3840
|
+
if (field === "name") {
|
|
3841
|
+
await renameLibrary(manager, lib, value);
|
|
3842
|
+
return;
|
|
3843
|
+
}
|
|
3844
|
+
if (field === "ownership") {
|
|
3845
|
+
if (!LIBRARY_OWNERSHIPS.includes(value)) {
|
|
3846
|
+
logErr(
|
|
3847
|
+
`Invalid ownership "${value}": expected one of ${LIBRARY_OWNERSHIPS.join(", ")}.`
|
|
3848
|
+
);
|
|
3849
|
+
process.exit(1);
|
|
3850
|
+
}
|
|
3851
|
+
if (value !== "owner" && lib.backend !== "git") {
|
|
3852
|
+
logErr(`ownership=${value} needs a git-backed library: ${LOCAL_OWNERSHIP_REASON}`);
|
|
3853
|
+
process.exit(1);
|
|
3854
|
+
}
|
|
3855
|
+
patch.ownership = value;
|
|
3856
|
+
} else if (field === "isDefault") {
|
|
3857
|
+
if (value !== "true" && value !== "false") {
|
|
3858
|
+
logErr(`Invalid isDefault "${value}": expected true or false.`);
|
|
3859
|
+
process.exit(1);
|
|
3860
|
+
}
|
|
3861
|
+
if (value === "true") {
|
|
3862
|
+
await manager.setDefault(lib.id);
|
|
3863
|
+
logOk(`Updated ${name}.isDefault`);
|
|
3864
|
+
return;
|
|
3865
|
+
}
|
|
3866
|
+
if (lib.isDefault) {
|
|
3867
|
+
logErr(
|
|
3868
|
+
`Library "${lib.name}" is the default; make another library the default with \`skaile library default <name>\` instead of unsetting it.`
|
|
3869
|
+
);
|
|
3870
|
+
process.exit(1);
|
|
3871
|
+
}
|
|
3872
|
+
patch.isDefault = false;
|
|
3873
|
+
} else if (field === "path") {
|
|
3874
|
+
const dir = path23.resolve(value);
|
|
3875
|
+
if (!fs9.existsSync(dir) || !fs9.statSync(dir).isDirectory()) {
|
|
3717
3876
|
logErr(`Directory does not exist: ${dir}. \`library set path=\` does not move files.`);
|
|
3718
3877
|
process.exit(1);
|
|
3719
3878
|
}
|
|
@@ -3722,6 +3881,10 @@ function makeLibraryCommand() {
|
|
|
3722
3881
|
patch.path = dir;
|
|
3723
3882
|
} else if (field.startsWith("backendConfig.")) {
|
|
3724
3883
|
const key = field.split(".")[1];
|
|
3884
|
+
if (key === "url" && lib.backend !== "git") {
|
|
3885
|
+
logErr("backendConfig.url only applies to git-backed libraries.");
|
|
3886
|
+
process.exit(1);
|
|
3887
|
+
}
|
|
3725
3888
|
if (key === "url" && lib.backend === "git") {
|
|
3726
3889
|
const branch = lib.backendConfig.branch ?? "main";
|
|
3727
3890
|
ensureGitRepo(lib.path, value, branch);
|
|
@@ -3743,6 +3906,10 @@ function makeLibraryCommand() {
|
|
|
3743
3906
|
}
|
|
3744
3907
|
});
|
|
3745
3908
|
cmd.command("remove <name>").description("Unregister a library (use --purge to also delete files)").option("--purge", "Also delete the library directory from disk", false).option("-y, --yes", "Skip confirmation", false).action(async (name, opts) => {
|
|
3909
|
+
if (!opts.yes && !process.stdin.isTTY) {
|
|
3910
|
+
logErr("library remove needs confirmation: pass -y");
|
|
3911
|
+
process.exit(1);
|
|
3912
|
+
}
|
|
3746
3913
|
const { manager, close } = await openLibraryManager();
|
|
3747
3914
|
try {
|
|
3748
3915
|
if (!opts.yes) {
|
|
@@ -3755,8 +3922,12 @@ function makeLibraryCommand() {
|
|
|
3755
3922
|
return;
|
|
3756
3923
|
}
|
|
3757
3924
|
}
|
|
3925
|
+
const lib = await manager.requireLibrary(name);
|
|
3758
3926
|
await manager.removeLibrary(name, { purge: opts.purge });
|
|
3927
|
+
if (opts.purge) pruneEmptyLibraryParents(lib.path);
|
|
3759
3928
|
logOk(`Removed ${name}.`);
|
|
3929
|
+
} catch (err2) {
|
|
3930
|
+
exitOnSyncError(err2);
|
|
3760
3931
|
} finally {
|
|
3761
3932
|
close();
|
|
3762
3933
|
}
|
|
@@ -3768,6 +3939,7 @@ function makeLibraryCommand() {
|
|
|
3768
3939
|
requireGitBackend(lib, "sync");
|
|
3769
3940
|
const drv = manager.driverFor(lib.backend);
|
|
3770
3941
|
const pull = await drv.pull(lib);
|
|
3942
|
+
if (pull.conflicts.length > 0) exitOnSyncError(new Error(pull.conflicts[0].reason));
|
|
3771
3943
|
logInfo(`Pulled: applied=${pull.applied}, conflicts=${pull.conflicts.length}`);
|
|
3772
3944
|
if (lib.ownership === "owner") {
|
|
3773
3945
|
const push = await drv.push(lib);
|
|
@@ -3786,9 +3958,12 @@ function makeLibraryCommand() {
|
|
|
3786
3958
|
try {
|
|
3787
3959
|
const lib = await manager.requireLibrary(name);
|
|
3788
3960
|
assertManifestEditableOrExit(lib.path);
|
|
3789
|
-
const
|
|
3961
|
+
const badRequires = manifestRequiresProblems(lib.path);
|
|
3962
|
+
const resolved = resolveLibraryPublisherDetailed(lib, {}, getStoreIdentity());
|
|
3963
|
+
warnLibraryNameFallback(name, resolved);
|
|
3964
|
+
const { removed, skipped } = await syncManifestWithDisk(
|
|
3790
3965
|
lib.path,
|
|
3791
|
-
|
|
3966
|
+
resolved.publisher,
|
|
3792
3967
|
getKindRegistry()
|
|
3793
3968
|
);
|
|
3794
3969
|
const manifest = loadSkPublishManifest(lib.path);
|
|
@@ -3796,13 +3971,35 @@ function makeLibraryCommand() {
|
|
|
3796
3971
|
const ref = manifest ? assetEntryRef(a, manifest) : `${a.kind}:${a.name}`;
|
|
3797
3972
|
logInfo(`Removed manifest entry ${ref} (root ${a.root} is gone)`);
|
|
3798
3973
|
}
|
|
3799
|
-
const
|
|
3974
|
+
for (const s of skipped.filter((x) => x.reason === "invalid-version")) {
|
|
3975
|
+
logWarn(
|
|
3976
|
+
`${s.kind}:${s.name} skipped: ${s.detail}. Set a valid \`metadata.version\` (e.g. 0.1.0) and re-run \`skaile library index ${name}\`.`
|
|
3977
|
+
);
|
|
3978
|
+
}
|
|
3979
|
+
const skippedKeys = new Set(skipped.map((s) => `${s.kind}:${s.name}`));
|
|
3980
|
+
const res = await indexLibrary(lib, library, {
|
|
3981
|
+
exclude: (a) => skippedKeys.has(`${a.kind}:${a.name}`)
|
|
3982
|
+
});
|
|
3800
3983
|
const unparsable = res.errors.filter((e) => e.includes("ManifestSchemaError:"));
|
|
3801
3984
|
for (const e of res.errors) (unparsable.includes(e) ? logErr : logWarn)(e);
|
|
3985
|
+
const syncUnparsable = skipped.filter(
|
|
3986
|
+
(s) => s.reason === "unparsable" && !unparsable.some((e) => e.includes(s.file))
|
|
3987
|
+
);
|
|
3988
|
+
for (const s of syncUnparsable) {
|
|
3989
|
+
logErr(`${s.kind}:${s.name} skipped: manifest file ${s.file} could not be parsed.`);
|
|
3990
|
+
}
|
|
3991
|
+
for (const p6 of badRequires) logErr(`${p6.asset}: ${p6.message}`);
|
|
3802
3992
|
logOk(`Indexed ${res.assetsUpdated} asset(s) from ${name}.`);
|
|
3803
3993
|
warnIgnoredDomainFiles(lib.path);
|
|
3804
|
-
|
|
3805
|
-
|
|
3994
|
+
const skippedUnparsable = unparsable.length + syncUnparsable.length;
|
|
3995
|
+
if (skippedUnparsable > 0) {
|
|
3996
|
+
logErr(`${skippedUnparsable} asset(s) skipped: manifest could not be parsed.`);
|
|
3997
|
+
process.exitCode = 1;
|
|
3998
|
+
}
|
|
3999
|
+
if (badRequires.length > 0) {
|
|
4000
|
+
logErr(
|
|
4001
|
+
`${badRequires.length} invalid requires entr${badRequires.length === 1 ? "y" : "ies"} ignored: use the \`kind:@<publisher>/name[#version]\` form.`
|
|
4002
|
+
);
|
|
3806
4003
|
process.exitCode = 1;
|
|
3807
4004
|
}
|
|
3808
4005
|
} finally {
|
|
@@ -3816,7 +4013,7 @@ function makeLibraryCommand() {
|
|
|
3816
4013
|
requireGitBackend(lib, "pull");
|
|
3817
4014
|
const res = await manager.driverFor(lib.backend).pull(lib);
|
|
3818
4015
|
if (res.conflicts.length > 0) {
|
|
3819
|
-
|
|
4016
|
+
exitOnSyncError(new Error(res.conflicts[0].reason));
|
|
3820
4017
|
} else {
|
|
3821
4018
|
logOk(`Pulled ${res.applied} change(s).`);
|
|
3822
4019
|
}
|
|
@@ -3862,6 +4059,13 @@ function makeLibraryCommand() {
|
|
|
3862
4059
|
);
|
|
3863
4060
|
process.exit(1);
|
|
3864
4061
|
}
|
|
4062
|
+
const unfinished = unfinishedGitState(lib.path);
|
|
4063
|
+
if (unfinished) {
|
|
4064
|
+
logErr(
|
|
4065
|
+
`library commit refused: ${unfinished} in ${lib.path}. Resolve the conflicts (\`skaile library git ${name} status\`), finish or abort the rebase/merge, then commit again.`
|
|
4066
|
+
);
|
|
4067
|
+
process.exit(1);
|
|
4068
|
+
}
|
|
3865
4069
|
const add = spawnSync("git", ["add", "-A"], { cwd: lib.path, stdio: "inherit" });
|
|
3866
4070
|
if (add.status !== 0) {
|
|
3867
4071
|
logErr(`git add failed in ${lib.path}.`);
|
|
@@ -3916,16 +4120,16 @@ function makeLibraryCommand() {
|
|
|
3916
4120
|
"With --create-repo: create the repo private (the store only accepts public repos)"
|
|
3917
4121
|
).option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; push nothing and call no store endpoint").action(
|
|
3918
4122
|
async (lib, opts) => {
|
|
3919
|
-
const { runLibraryPublish } = await import('../library-publish-
|
|
4123
|
+
const { runLibraryPublish } = await import('../library-publish-FGXF5TJO.js');
|
|
3920
4124
|
await withStoreErrorHandling(() => runLibraryPublish(lib, opts));
|
|
3921
4125
|
}
|
|
3922
4126
|
);
|
|
3923
4127
|
cmd.command("register <lib>").description("Register the library's manifest without pushing (bytes already on github)").option("--asset <ref>", "Publish only the single asset matching this ref/name").option("--ref <gitref>", "Git ref to ingest (default: the library branch or main)").option("--dry-run", "Print the plan; call no store endpoint").action(async (lib, opts) => {
|
|
3924
|
-
const { runLibraryRegister } = await import('../library-publish-
|
|
4128
|
+
const { runLibraryRegister } = await import('../library-publish-FGXF5TJO.js');
|
|
3925
4129
|
await withStoreErrorHandling(() => runLibraryRegister(lib, opts));
|
|
3926
4130
|
});
|
|
3927
4131
|
cmd.command("yank <lib>").description("Retract the library's published assets from the store").option("--asset <ref>", "Yank only the single asset matching this ref/name").action(async (lib, opts) => {
|
|
3928
|
-
const { runLibraryYank } = await import('../library-publish-
|
|
4132
|
+
const { runLibraryYank } = await import('../library-publish-FGXF5TJO.js');
|
|
3929
4133
|
await withStoreErrorHandling(() => runLibraryYank(lib, opts));
|
|
3930
4134
|
});
|
|
3931
4135
|
return cmd;
|
|
@@ -3976,9 +4180,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
3976
4180
|
} catch {
|
|
3977
4181
|
secretsStrategy = "unavailable";
|
|
3978
4182
|
}
|
|
3979
|
-
const resolvedProjectDir =
|
|
3980
|
-
const hasWorkspaceConfig = existsSync(
|
|
3981
|
-
const hasLockFile = existsSync(
|
|
4183
|
+
const resolvedProjectDir = path23.resolve(projectDir);
|
|
4184
|
+
const hasWorkspaceConfig = existsSync(path23.join(resolvedProjectDir, "skaile.yaml"));
|
|
4185
|
+
const hasLockFile = existsSync(path23.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
3982
4186
|
let assignments = [];
|
|
3983
4187
|
if (hasWorkspaceConfig) {
|
|
3984
4188
|
try {
|
|
@@ -4585,13 +4789,18 @@ function scheduleSoftDepPreview() {
|
|
|
4585
4789
|
}
|
|
4586
4790
|
async function loadAssets() {
|
|
4587
4791
|
softDepPreviewCache.clear();
|
|
4588
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
4792
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-K36CR52Q.js');
|
|
4589
4793
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
4590
4794
|
if (notes.length > 0) {
|
|
4591
4795
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
4592
4796
|
}
|
|
4593
4797
|
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
4594
|
-
|
|
4798
|
+
let lock = null;
|
|
4799
|
+
try {
|
|
4800
|
+
lock = readLock(path23__default.join(am.projectDir, "skaile.lock.yaml"));
|
|
4801
|
+
} catch {
|
|
4802
|
+
}
|
|
4803
|
+
const rows = buildAssetRows(entries, installed, lockedLibraryByIdentity(lock));
|
|
4595
4804
|
state.assetRows = rows;
|
|
4596
4805
|
reconcileCollapsedSets(rows);
|
|
4597
4806
|
rebuildVisible();
|
|
@@ -4605,7 +4814,7 @@ function rebuildSourceTree() {
|
|
|
4605
4814
|
rebuildVisibleSources();
|
|
4606
4815
|
}
|
|
4607
4816
|
function sourceOrgRepo(s) {
|
|
4608
|
-
const parts = s.path.split(
|
|
4817
|
+
const parts = s.path.split(path23__default.sep).filter(Boolean);
|
|
4609
4818
|
if (parts.length < 2) return null;
|
|
4610
4819
|
return { org: parts[parts.length - 2], repo: parts[parts.length - 1] };
|
|
4611
4820
|
}
|
|
@@ -4678,7 +4887,22 @@ function rebuildVisibleLibraries() {
|
|
|
4678
4887
|
);
|
|
4679
4888
|
clampCursor();
|
|
4680
4889
|
}
|
|
4681
|
-
function
|
|
4890
|
+
function lockedLibraryByIdentity(lock) {
|
|
4891
|
+
const out = /* @__PURE__ */ new Map();
|
|
4892
|
+
for (const [key, locked] of Object.entries(lock?.assets ?? {})) {
|
|
4893
|
+
if (!locked.library) continue;
|
|
4894
|
+
const ref = parseAssetRefLoose(key);
|
|
4895
|
+
if (ref?.publisher) out.set(`${ref.kind}:${ref.publisher}/${ref.name}`, locked.library.name);
|
|
4896
|
+
}
|
|
4897
|
+
return out;
|
|
4898
|
+
}
|
|
4899
|
+
function isRowInstalled(origin, group, entry, installed, lockedLibrary) {
|
|
4900
|
+
if (!installed.has(`${entry.kind}:${entry.name}`)) return false;
|
|
4901
|
+
const publisher = entry.publisher?.replace(/^@/, "");
|
|
4902
|
+
const locked = publisher ? lockedLibrary.get(`${entry.kind}:${publisher}/${entry.name}`) : void 0;
|
|
4903
|
+
return locked === void 0 || origin === "library" && group === locked;
|
|
4904
|
+
}
|
|
4905
|
+
function buildAssetRows(entries, installed, lockedLibrary = /* @__PURE__ */ new Map()) {
|
|
4682
4906
|
const byOrigin = /* @__PURE__ */ new Map();
|
|
4683
4907
|
for (const { origin, entry, group } of entries) {
|
|
4684
4908
|
const publisher = group || entry.publisher || "other";
|
|
@@ -4706,7 +4930,7 @@ function buildAssetRows(entries, installed) {
|
|
|
4706
4930
|
source: group,
|
|
4707
4931
|
org: entry.repo?.includes("/") ? entry.repo.slice(0, entry.repo.indexOf("/")) : void 0,
|
|
4708
4932
|
entry,
|
|
4709
|
-
installed:
|
|
4933
|
+
installed: isRowInstalled(origin, group, entry, installed, lockedLibrary),
|
|
4710
4934
|
plugin
|
|
4711
4935
|
});
|
|
4712
4936
|
}
|
|
@@ -4752,13 +4976,13 @@ function reconcileCollapsedSets(rows) {
|
|
|
4752
4976
|
async function loadSourcesAndLibraries() {
|
|
4753
4977
|
try {
|
|
4754
4978
|
const [{ openLibraryManager: openLibraryManager2 }, { getGlobalCacheDir: getGlobalCacheDir2, globalSkaileDir: globalSkaileDir2 }] = await Promise.all([
|
|
4755
|
-
import('../open-library-
|
|
4979
|
+
import('../open-library-P3D337NH.js'),
|
|
4756
4980
|
import('../core/index.js')
|
|
4757
4981
|
]);
|
|
4758
4982
|
const { manager, library, close } = await openLibraryManager2();
|
|
4759
4983
|
try {
|
|
4760
4984
|
const newRoot = getGlobalCacheDir2();
|
|
4761
|
-
const legacyRoot =
|
|
4985
|
+
const legacyRoot = path23__default.join(globalSkaileDir2(), "sources");
|
|
4762
4986
|
const isSourceRow = (l) => l.path.startsWith(newRoot) || l.path.startsWith(legacyRoot);
|
|
4763
4987
|
const libs = await manager.listLibraries();
|
|
4764
4988
|
const defs = await library.listAssetDefs();
|
|
@@ -5694,7 +5918,7 @@ async function run(projectDir) {
|
|
|
5694
5918
|
}
|
|
5695
5919
|
function makeManageCommand() {
|
|
5696
5920
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
5697
|
-
await run(
|
|
5921
|
+
await run(path23__default.resolve(opts.projectDir));
|
|
5698
5922
|
});
|
|
5699
5923
|
}
|
|
5700
5924
|
function makeMcpServerCommand() {
|
|
@@ -5747,10 +5971,10 @@ function walkFiles(root, match) {
|
|
|
5747
5971
|
return;
|
|
5748
5972
|
}
|
|
5749
5973
|
for (const entry of entries) {
|
|
5750
|
-
const full =
|
|
5974
|
+
const full = path23__default.join(dir, entry.name);
|
|
5751
5975
|
if (entry.isDirectory()) {
|
|
5752
5976
|
if (SKIPPED_DIRS.has(entry.name)) continue;
|
|
5753
|
-
if (entry.name === "cache" &&
|
|
5977
|
+
if (entry.name === "cache" && path23__default.basename(dir) === ".skaile") continue;
|
|
5754
5978
|
visit(full);
|
|
5755
5979
|
} else if (entry.isFile() && match(entry.name)) {
|
|
5756
5980
|
out.push(full);
|
|
@@ -5768,14 +5992,14 @@ function applyChanges2(changes) {
|
|
|
5768
5992
|
switch (change.type) {
|
|
5769
5993
|
case "write":
|
|
5770
5994
|
case "create":
|
|
5771
|
-
mkdirSync(
|
|
5995
|
+
mkdirSync(path23__default.dirname(change.path), { recursive: true });
|
|
5772
5996
|
writeFileSync(change.path, change.after, "utf-8");
|
|
5773
5997
|
break;
|
|
5774
5998
|
case "delete":
|
|
5775
5999
|
rmSync(change.path, { force: true });
|
|
5776
6000
|
break;
|
|
5777
6001
|
case "move":
|
|
5778
|
-
mkdirSync(
|
|
6002
|
+
mkdirSync(path23__default.dirname(change.to), { recursive: true });
|
|
5779
6003
|
writeFileSync(change.to, change.after, "utf-8");
|
|
5780
6004
|
rmSync(change.from, { force: true });
|
|
5781
6005
|
break;
|
|
@@ -5868,7 +6092,7 @@ function unifiedDiff(before, after, oldLabel, newLabel, context = 3) {
|
|
|
5868
6092
|
return `${out.join("\n")}
|
|
5869
6093
|
`;
|
|
5870
6094
|
}
|
|
5871
|
-
var posix = (p6) => p6.split(
|
|
6095
|
+
var posix = (p6) => p6.split(path23__default.sep).join("/");
|
|
5872
6096
|
function colorizeDiff(diff) {
|
|
5873
6097
|
return diff.split("\n").map((line) => {
|
|
5874
6098
|
if (line.startsWith("+++") || line.startsWith("---")) return S.bold(line);
|
|
@@ -5879,7 +6103,7 @@ function colorizeDiff(diff) {
|
|
|
5879
6103
|
}).join("\n");
|
|
5880
6104
|
}
|
|
5881
6105
|
function renderChange(change, base) {
|
|
5882
|
-
const rel = (p6) => posix(
|
|
6106
|
+
const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
|
|
5883
6107
|
switch (change.type) {
|
|
5884
6108
|
case "write":
|
|
5885
6109
|
return unifiedDiff(
|
|
@@ -5906,7 +6130,7 @@ ${diff}`;
|
|
|
5906
6130
|
}
|
|
5907
6131
|
}
|
|
5908
6132
|
function changeLabel(change, base) {
|
|
5909
|
-
const rel = (p6) => posix(
|
|
6133
|
+
const rel = (p6) => posix(path23__default.relative(base, p6) || path23__default.basename(p6));
|
|
5910
6134
|
switch (change.type) {
|
|
5911
6135
|
case "write":
|
|
5912
6136
|
return `modify ${rel(change.path)}`;
|
|
@@ -5966,10 +6190,10 @@ function loadAsset(projectDir, id, ref) {
|
|
|
5966
6190
|
)
|
|
5967
6191
|
};
|
|
5968
6192
|
}
|
|
5969
|
-
const manifestPath =
|
|
6193
|
+
const manifestPath = path23__default.join(dir, AGENT_MANIFEST_FILE);
|
|
5970
6194
|
let text;
|
|
5971
6195
|
try {
|
|
5972
|
-
text =
|
|
6196
|
+
text = fs9__default.readFileSync(manifestPath, "utf-8");
|
|
5973
6197
|
} catch {
|
|
5974
6198
|
return {
|
|
5975
6199
|
diagnostic: err(
|
|
@@ -6148,12 +6372,12 @@ function findManifestCandidates(rootPath) {
|
|
|
6148
6372
|
function walk(dir) {
|
|
6149
6373
|
let entries;
|
|
6150
6374
|
try {
|
|
6151
|
-
entries =
|
|
6375
|
+
entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
6152
6376
|
} catch {
|
|
6153
6377
|
return;
|
|
6154
6378
|
}
|
|
6155
6379
|
for (const entry of entries) {
|
|
6156
|
-
const fullPath =
|
|
6380
|
+
const fullPath = path23__default.join(dir, entry.name);
|
|
6157
6381
|
if (entry.isDirectory()) {
|
|
6158
6382
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
6159
6383
|
} else if (entry.isFile()) {
|
|
@@ -6189,10 +6413,10 @@ function checkManifestIdentity(kind, parsed) {
|
|
|
6189
6413
|
return null;
|
|
6190
6414
|
}
|
|
6191
6415
|
function parseManifestCandidate(c, absRoot) {
|
|
6192
|
-
const content =
|
|
6416
|
+
const content = fs9__default.readFileSync(c.filePath, "utf-8");
|
|
6193
6417
|
const res = parseManifestFile(c.filePath, content);
|
|
6194
6418
|
if (!res.ok) {
|
|
6195
|
-
logErr(`${
|
|
6419
|
+
logErr(`${path23__default.relative(absRoot, c.filePath)} [${c.kind}] \u2014 parse error: ${res.reason}`);
|
|
6196
6420
|
return { kind: "error" };
|
|
6197
6421
|
}
|
|
6198
6422
|
return {
|
|
@@ -6222,7 +6446,7 @@ function checkComposeKinds(parsed, registry) {
|
|
|
6222
6446
|
return diagnostics;
|
|
6223
6447
|
}
|
|
6224
6448
|
function validateManifestCandidate(c, parsed, body, absRoot, registry, strictConformance) {
|
|
6225
|
-
const relPath =
|
|
6449
|
+
const relPath = path23__default.relative(absRoot, c.filePath);
|
|
6226
6450
|
let errors = 0;
|
|
6227
6451
|
let warnings = 0;
|
|
6228
6452
|
const identityError = checkManifestIdentity(c.kind, parsed);
|
|
@@ -6230,9 +6454,15 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6230
6454
|
logErr(`${relPath} [${c.kind}] \u2014 ${identityError}`);
|
|
6231
6455
|
errors++;
|
|
6232
6456
|
}
|
|
6233
|
-
if (
|
|
6234
|
-
const
|
|
6235
|
-
|
|
6457
|
+
if (parsed && typeof parsed === "object") {
|
|
6458
|
+
const manifest = parsed;
|
|
6459
|
+
const version = declaredVersion(manifest);
|
|
6460
|
+
if (version !== void 0 && !isValidSemver(version)) {
|
|
6461
|
+
logErr(`${relPath} [${c.kind}] \u2014 version "${version}" is not valid semver`);
|
|
6462
|
+
errors++;
|
|
6463
|
+
}
|
|
6464
|
+
const dirName = path23__default.basename(path23__default.dirname(c.filePath));
|
|
6465
|
+
for (const f of checkAssetManifest(c.kind, manifest, body, dirName)) {
|
|
6236
6466
|
const line = `${relPath} [${f.tag}] \u2014 ${f.text}`;
|
|
6237
6467
|
if (f.conformance && strictConformance) {
|
|
6238
6468
|
logErr(line);
|
|
@@ -6243,7 +6473,7 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6243
6473
|
}
|
|
6244
6474
|
}
|
|
6245
6475
|
}
|
|
6246
|
-
if (c.kind === "agent" &&
|
|
6476
|
+
if (c.kind === "agent" && path23__default.basename(c.filePath) === "agent.yaml") {
|
|
6247
6477
|
for (const d of [
|
|
6248
6478
|
...checkComposeKinds(parsed, registry),
|
|
6249
6479
|
...composeSlotDiagnostics(parsed),
|
|
@@ -6274,8 +6504,8 @@ function validateManifestCandidate(c, parsed, body, absRoot, registry, strictCon
|
|
|
6274
6504
|
return { errors, warnings };
|
|
6275
6505
|
}
|
|
6276
6506
|
function validateManifests(rootPath, strictConformance) {
|
|
6277
|
-
const absRoot =
|
|
6278
|
-
if (!
|
|
6507
|
+
const absRoot = path23__default.resolve(rootPath);
|
|
6508
|
+
if (!fs9__default.existsSync(absRoot)) {
|
|
6279
6509
|
logErr(`Path does not exist: ${absRoot}`);
|
|
6280
6510
|
return { total: 0, errors: 1, warnings: 0 };
|
|
6281
6511
|
}
|
|
@@ -6307,12 +6537,12 @@ function findWorkspaceManifests(rootPath) {
|
|
|
6307
6537
|
function walk(dir) {
|
|
6308
6538
|
let entries;
|
|
6309
6539
|
try {
|
|
6310
|
-
entries =
|
|
6540
|
+
entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
6311
6541
|
} catch {
|
|
6312
6542
|
return;
|
|
6313
6543
|
}
|
|
6314
6544
|
for (const entry of entries) {
|
|
6315
|
-
const full =
|
|
6545
|
+
const full = path23__default.join(dir, entry.name);
|
|
6316
6546
|
if (entry.isDirectory()) {
|
|
6317
6547
|
if (!SKIP_DIRS.has(entry.name)) walk(full);
|
|
6318
6548
|
} else if (entry.isFile() && /(^|\.)skaile\.yaml$/.test(entry.name)) {
|
|
@@ -6375,14 +6605,14 @@ function validateWorkspaceAssets(parsed, relPath) {
|
|
|
6375
6605
|
return errors;
|
|
6376
6606
|
}
|
|
6377
6607
|
function validateWorkspaceManifests(rootPath) {
|
|
6378
|
-
const absRoot =
|
|
6608
|
+
const absRoot = path23__default.resolve(rootPath);
|
|
6379
6609
|
const files = findWorkspaceManifests(absRoot);
|
|
6380
6610
|
let errors = 0;
|
|
6381
6611
|
for (const file of files) {
|
|
6382
|
-
const relPath =
|
|
6612
|
+
const relPath = path23__default.relative(absRoot, file);
|
|
6383
6613
|
let parsed;
|
|
6384
6614
|
try {
|
|
6385
|
-
parsed = parse(
|
|
6615
|
+
parsed = parse(fs9__default.readFileSync(file, "utf-8")) ?? {};
|
|
6386
6616
|
} catch (e) {
|
|
6387
6617
|
logErr(`${relPath} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
6388
6618
|
errors++;
|
|
@@ -6390,7 +6620,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6390
6620
|
}
|
|
6391
6621
|
errors += validateWorkspaceRefs(collectWorkspaceRefFields(parsed), relPath);
|
|
6392
6622
|
errors += validateWorkspaceAssets(parsed, relPath);
|
|
6393
|
-
for (const d of checkAgentInstances(
|
|
6623
|
+
for (const d of checkAgentInstances(path23__default.dirname(file), parsed)) {
|
|
6394
6624
|
const line = `${relPath} [agents] \u2014 ${d.code}: ${d.path ? `${d.path}: ` : ""}${d.message}`;
|
|
6395
6625
|
if (d.severity === "error") {
|
|
6396
6626
|
logErr(line);
|
|
@@ -6403,7 +6633,7 @@ function validateWorkspaceManifests(rootPath) {
|
|
|
6403
6633
|
return { total: files.length, errors };
|
|
6404
6634
|
}
|
|
6405
6635
|
function validatePublishManifestRoots(rootPath) {
|
|
6406
|
-
const absRoot =
|
|
6636
|
+
const absRoot = path23__default.resolve(rootPath);
|
|
6407
6637
|
const manifest = loadSkPublishManifest(absRoot);
|
|
6408
6638
|
if (!manifest) return 0;
|
|
6409
6639
|
const missing = missingRootAssets(absRoot, manifest);
|
|
@@ -6414,99 +6644,128 @@ function validatePublishManifestRoots(rootPath) {
|
|
|
6414
6644
|
}
|
|
6415
6645
|
return missing.length;
|
|
6416
6646
|
}
|
|
6647
|
+
function validatePublishManifestRequires(rootPath) {
|
|
6648
|
+
const problems = manifestRequiresProblems(path23__default.resolve(rootPath));
|
|
6649
|
+
for (const p6 of problems) {
|
|
6650
|
+
logErr(
|
|
6651
|
+
`${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${p6.asset}: ${p6.message}. Use the \`kind:@<publisher>/name[#version]\` form.`
|
|
6652
|
+
);
|
|
6653
|
+
}
|
|
6654
|
+
return problems.length;
|
|
6655
|
+
}
|
|
6656
|
+
function validatePublishManifestVersions(rootPath) {
|
|
6657
|
+
const absRoot = path23__default.resolve(rootPath);
|
|
6658
|
+
const manifest = loadSkPublishManifest(absRoot);
|
|
6659
|
+
if (!manifest || manifest.source) return 0;
|
|
6660
|
+
let warnings = 0;
|
|
6661
|
+
for (const a of manifest.assets ?? []) {
|
|
6662
|
+
if (!a.root || a.source || !a.version) continue;
|
|
6663
|
+
const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
|
|
6664
|
+
if (!file) continue;
|
|
6665
|
+
const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
|
|
6666
|
+
if (!res.ok) continue;
|
|
6667
|
+
const fileVersion = declaredVersion(res.data);
|
|
6668
|
+
if (fileVersion === void 0 || fileVersion === a.version) continue;
|
|
6669
|
+
logWarn(
|
|
6670
|
+
`${SKAILE_MANIFEST_FILENAME} [assets] \u2014 ${assetEntryRef(a, manifest)}: manifest version ${a.version} differs from ${toPosix(path23__default.relative(absRoot, file))} (${fileVersion}). The file is the source of truth: bump the version there, then run \`skaile library index <library>\`.`
|
|
6671
|
+
);
|
|
6672
|
+
warnings++;
|
|
6673
|
+
}
|
|
6674
|
+
return warnings;
|
|
6675
|
+
}
|
|
6676
|
+
function validatePublishManifestPublishers(rootPath) {
|
|
6677
|
+
const absRoot = path23__default.resolve(rootPath);
|
|
6678
|
+
const manifest = loadSkPublishManifest(absRoot);
|
|
6679
|
+
if (!manifest || manifest.source) return 0;
|
|
6680
|
+
const bare = (p6) => p6.trim().replace(/^@/, "");
|
|
6681
|
+
let warnings = 0;
|
|
6682
|
+
for (const a of manifest.assets ?? []) {
|
|
6683
|
+
const resolved = a.publisher ?? manifest.publisher;
|
|
6684
|
+
if (!a.root || a.source || !resolved) continue;
|
|
6685
|
+
const file = findAssetManifestFile(path23__default.join(absRoot, a.root), a.kind, a.name);
|
|
6686
|
+
if (!file) continue;
|
|
6687
|
+
const res = parseManifestFile(file, fs9__default.readFileSync(file, "utf-8"));
|
|
6688
|
+
if (!res.ok) continue;
|
|
6689
|
+
const meta = res.data.metadata;
|
|
6690
|
+
const declared = meta !== null && typeof meta === "object" ? meta.publisher : null;
|
|
6691
|
+
if (typeof declared !== "string" || bare(declared) === bare(resolved)) continue;
|
|
6692
|
+
logWarn(
|
|
6693
|
+
`${toPosix(path23__default.relative(absRoot, file))} [publisher] \u2014 metadata.publisher "${bare(declared)}" differs from the manifest publisher "${bare(resolved)}" for ${assetEntryRef(a, manifest)}. The manifest wins and the file value is ignored: delete \`metadata.publisher\` from the file, or set the publisher in ${SKAILE_MANIFEST_FILENAME}.`
|
|
6694
|
+
);
|
|
6695
|
+
warnings++;
|
|
6696
|
+
}
|
|
6697
|
+
return warnings;
|
|
6698
|
+
}
|
|
6417
6699
|
var EXCLUDED_PATHS = ["skaileup-shared/", "external/", "docs/"];
|
|
6418
6700
|
function toPosix(p6) {
|
|
6419
|
-
return p6.split(
|
|
6701
|
+
return p6.split(path23__default.sep).join("/");
|
|
6420
6702
|
}
|
|
6421
6703
|
function isExcludedPath(relPath) {
|
|
6422
6704
|
const rel = toPosix(relPath);
|
|
6423
6705
|
return EXCLUDED_PATHS.some((prefix) => rel.startsWith(prefix));
|
|
6424
6706
|
}
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
const
|
|
6436
|
-
|
|
6437
|
-
}
|
|
6438
|
-
function collectFlowVersions(dir, out) {
|
|
6439
|
-
for (const f of fs11__default.readdirSync(dir)) {
|
|
6440
|
-
if (!f.endsWith(".flow.yaml")) continue;
|
|
6441
|
-
const fp = path25__default.join(dir, f);
|
|
6442
|
-
const content = fs11__default.readFileSync(fp, "utf-8");
|
|
6443
|
-
const parsed = parse(content);
|
|
6444
|
-
out.push({
|
|
6445
|
-
kind: "flow",
|
|
6446
|
-
name: parsed?.id ?? f.replace(".flow.yaml", ""),
|
|
6447
|
-
version: parsed?.version ?? "",
|
|
6448
|
-
filePath: fp
|
|
6449
|
-
});
|
|
6450
|
-
}
|
|
6451
|
-
}
|
|
6452
|
-
function collectPromptVersions(dir, out) {
|
|
6453
|
-
for (const f of fs11__default.readdirSync(dir)) {
|
|
6454
|
-
if (!f.endsWith(".prompt.md")) continue;
|
|
6455
|
-
const fp = path25__default.join(dir, f);
|
|
6456
|
-
const content = fs11__default.readFileSync(fp, "utf-8");
|
|
6707
|
+
var VERSIONED_KINDS = {
|
|
6708
|
+
skill: true,
|
|
6709
|
+
agent: true,
|
|
6710
|
+
flow: true,
|
|
6711
|
+
prompt: true
|
|
6712
|
+
};
|
|
6713
|
+
function readAssetVersion(c) {
|
|
6714
|
+
const kind = c.kind;
|
|
6715
|
+
const fileName = path23__default.basename(c.filePath);
|
|
6716
|
+
const dirName = path23__default.basename(path23__default.dirname(c.filePath));
|
|
6717
|
+
const content = fs9__default.readFileSync(c.filePath, "utf-8");
|
|
6718
|
+
if (c.filePath.endsWith(".md")) {
|
|
6457
6719
|
const fm = parseSkillFrontmatter(content);
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6720
|
+
const stem = fileName.replace(/\.prompt\.md$/, "");
|
|
6721
|
+
return {
|
|
6722
|
+
kind,
|
|
6723
|
+
name: fm?.name ?? (kind === "prompt" ? stem : dirName),
|
|
6461
6724
|
version: fm?.metadata?.version ?? "",
|
|
6462
|
-
filePath:
|
|
6463
|
-
}
|
|
6725
|
+
filePath: c.filePath
|
|
6726
|
+
};
|
|
6464
6727
|
}
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
const full = path25__default.join(dir, entry.name);
|
|
6470
|
-
const skillMd = path25__default.join(full, "SKILL.md");
|
|
6471
|
-
if (fs11__default.existsSync(skillMd)) {
|
|
6472
|
-
const content = fs11__default.readFileSync(skillMd, "utf-8");
|
|
6473
|
-
const fm = parseSkillFrontmatter(content);
|
|
6474
|
-
out.push({
|
|
6475
|
-
kind: "skill",
|
|
6476
|
-
name: fm?.name ?? entry.name,
|
|
6477
|
-
version: fm?.metadata?.version ?? "",
|
|
6478
|
-
filePath: skillMd
|
|
6479
|
-
});
|
|
6480
|
-
} else {
|
|
6481
|
-
collectSkillVersions(full, out);
|
|
6482
|
-
}
|
|
6728
|
+
let parsed = null;
|
|
6729
|
+
try {
|
|
6730
|
+
parsed = parse(content);
|
|
6731
|
+
} catch {
|
|
6483
6732
|
}
|
|
6733
|
+
if (kind === "flow") {
|
|
6734
|
+
return {
|
|
6735
|
+
kind,
|
|
6736
|
+
name: String(parsed?.id ?? fileName.replace(".flow.yaml", "")),
|
|
6737
|
+
version: String(parsed?.version ?? ""),
|
|
6738
|
+
filePath: c.filePath
|
|
6739
|
+
};
|
|
6740
|
+
}
|
|
6741
|
+
return {
|
|
6742
|
+
kind,
|
|
6743
|
+
name: String(parsed?.name ?? dirName),
|
|
6744
|
+
version: String(parsed?.version ?? ""),
|
|
6745
|
+
filePath: c.filePath
|
|
6746
|
+
};
|
|
6484
6747
|
}
|
|
6485
|
-
function
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
if (!
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
kind: "agent",
|
|
6494
|
-
name: parsed?.name ?? entry.name,
|
|
6495
|
-
version: parsed?.version ?? "",
|
|
6496
|
-
filePath: agentYaml
|
|
6497
|
-
});
|
|
6748
|
+
function collectAssetVersions(root) {
|
|
6749
|
+
if (!fs9__default.existsSync(root)) return [];
|
|
6750
|
+
const assets = [];
|
|
6751
|
+
for (const c of findManifestCandidates(root)) {
|
|
6752
|
+
if (!VERSIONED_KINDS[c.kind]) continue;
|
|
6753
|
+
if (c.filePath.endsWith(".flow.json")) continue;
|
|
6754
|
+
if (isExcludedPath(path23__default.relative(root, c.filePath))) continue;
|
|
6755
|
+
assets.push(readAssetVersion(c));
|
|
6498
6756
|
}
|
|
6757
|
+
return assets;
|
|
6499
6758
|
}
|
|
6500
|
-
function assetLocation(a) {
|
|
6501
|
-
return toPosix(
|
|
6759
|
+
function assetLocation(a, root) {
|
|
6760
|
+
return toPosix(path23__default.relative(root, a.filePath));
|
|
6502
6761
|
}
|
|
6503
6762
|
function findChangelogUnit(assetRelPath, root) {
|
|
6504
|
-
let dir =
|
|
6763
|
+
let dir = path23__default.posix.dirname(toPosix(assetRelPath));
|
|
6505
6764
|
for (; ; ) {
|
|
6506
6765
|
const candidate = dir === "." ? "CHANGELOG.md" : `${dir}/CHANGELOG.md`;
|
|
6507
|
-
if (
|
|
6766
|
+
if (fs9__default.existsSync(path23__default.join(root, candidate))) return candidate;
|
|
6508
6767
|
if (dir === ".") return null;
|
|
6509
|
-
dir =
|
|
6768
|
+
dir = path23__default.posix.dirname(dir);
|
|
6510
6769
|
}
|
|
6511
6770
|
}
|
|
6512
6771
|
function checkChangelogUnits(modifiedFiles, root) {
|
|
@@ -6525,7 +6784,7 @@ function checkChangelogUnits(modifiedFiles, root) {
|
|
|
6525
6784
|
return { updated, stale, orphans };
|
|
6526
6785
|
}
|
|
6527
6786
|
function isValidSemver(v) {
|
|
6528
|
-
return
|
|
6787
|
+
return SEMVER_RE.test(v);
|
|
6529
6788
|
}
|
|
6530
6789
|
function extractVersionFromContent(filePath, content) {
|
|
6531
6790
|
if (filePath.endsWith(".yaml")) {
|
|
@@ -6537,51 +6796,37 @@ function extractVersionFromContent(filePath, content) {
|
|
|
6537
6796
|
const parsed = parse(fmMatch[1]);
|
|
6538
6797
|
return parsed?.metadata?.version ?? parsed?.version ?? null;
|
|
6539
6798
|
}
|
|
6540
|
-
function
|
|
6541
|
-
try {
|
|
6542
|
-
const diffOutput = execSync("git diff --name-only HEAD", {
|
|
6543
|
-
cwd: AI_RESOURCES,
|
|
6544
|
-
encoding: "utf-8"
|
|
6545
|
-
});
|
|
6546
|
-
const changedFiles = new Set(
|
|
6547
|
-
diffOutput.trim().split("\n").filter(Boolean).map((f) => path25__default.resolve(AI_RESOURCES, f))
|
|
6548
|
-
);
|
|
6549
|
-
return assets.filter((a) => changedFiles.has(a.filePath));
|
|
6550
|
-
} catch {
|
|
6551
|
-
logErr("Failed to run git diff \u2014 are you in a git repository?");
|
|
6552
|
-
process.exit(1);
|
|
6553
|
-
}
|
|
6554
|
-
}
|
|
6555
|
-
function checkAssetVersions(assets) {
|
|
6799
|
+
function checkAssetVersions(assets, root) {
|
|
6556
6800
|
let errors = 0;
|
|
6557
|
-
|
|
6801
|
+
const warnings = 0;
|
|
6558
6802
|
for (const a of assets) {
|
|
6559
6803
|
if (!a.version) {
|
|
6560
|
-
logErr(`${a.kind}:${a.name} (${assetLocation(a)}) \u2014 missing version`);
|
|
6804
|
+
logErr(`${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 missing version`);
|
|
6561
6805
|
errors++;
|
|
6562
6806
|
} else if (!isValidSemver(a.version)) {
|
|
6563
|
-
|
|
6564
|
-
`${a.kind}:${a.name} (${assetLocation(a)}) \u2014 version "${a.version}" is not valid semver`
|
|
6807
|
+
logErr(
|
|
6808
|
+
`${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 version "${a.version}" is not valid semver`
|
|
6565
6809
|
);
|
|
6566
|
-
|
|
6810
|
+
errors++;
|
|
6567
6811
|
}
|
|
6568
6812
|
}
|
|
6569
6813
|
return { errors, warnings };
|
|
6570
6814
|
}
|
|
6571
|
-
function checkVersionBumps(assets) {
|
|
6815
|
+
function checkVersionBumps(assets, root) {
|
|
6572
6816
|
let warnings = 0;
|
|
6573
6817
|
for (const a of assets) {
|
|
6574
6818
|
if (!a.version) continue;
|
|
6575
|
-
const relPath =
|
|
6819
|
+
const relPath = toPosix(path23__default.relative(root, a.filePath));
|
|
6576
6820
|
try {
|
|
6577
|
-
const headContent =
|
|
6578
|
-
cwd:
|
|
6579
|
-
encoding: "utf-8"
|
|
6821
|
+
const headContent = execFileSync("git", ["show", `HEAD:./${relPath}`], {
|
|
6822
|
+
cwd: root,
|
|
6823
|
+
encoding: "utf-8",
|
|
6824
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
6580
6825
|
});
|
|
6581
6826
|
const headVersion = extractVersionFromContent(a.filePath, headContent);
|
|
6582
6827
|
if (headVersion && headVersion === a.version) {
|
|
6583
6828
|
logWarn(
|
|
6584
|
-
`${a.kind}:${a.name} (${assetLocation(a)}) \u2014 file changed but version not bumped (${a.version})`
|
|
6829
|
+
`${a.kind}:${a.name} (${assetLocation(a, root)}) \u2014 file changed but version not bumped (${a.version})`
|
|
6585
6830
|
);
|
|
6586
6831
|
warnings++;
|
|
6587
6832
|
}
|
|
@@ -6590,7 +6835,7 @@ function checkVersionBumps(assets) {
|
|
|
6590
6835
|
}
|
|
6591
6836
|
return warnings;
|
|
6592
6837
|
}
|
|
6593
|
-
function checkFlowVersionPins(assets) {
|
|
6838
|
+
function checkFlowVersionPins(assets, root) {
|
|
6594
6839
|
const flows = assets.filter((a) => a.kind === "flow");
|
|
6595
6840
|
const skillVersionMap = /* @__PURE__ */ new Map();
|
|
6596
6841
|
for (const a of assets.filter((a2) => a2.kind === "skill")) {
|
|
@@ -6604,7 +6849,7 @@ function checkFlowVersionPins(assets) {
|
|
|
6604
6849
|
pins = flowSkillVersionPins(loadFlow(f.filePath));
|
|
6605
6850
|
} catch (err2) {
|
|
6606
6851
|
logWarn(
|
|
6607
|
-
`flow:${f.name} (${
|
|
6852
|
+
`flow:${f.name} (${path23__default.relative(root, f.filePath)}) \u2014 could not be read: ${err2 instanceof Error ? err2.message : err2}`
|
|
6608
6853
|
);
|
|
6609
6854
|
warnings++;
|
|
6610
6855
|
continue;
|
|
@@ -6620,18 +6865,63 @@ function checkFlowVersionPins(assets) {
|
|
|
6620
6865
|
}
|
|
6621
6866
|
return { errors, warnings };
|
|
6622
6867
|
}
|
|
6623
|
-
function
|
|
6624
|
-
|
|
6868
|
+
function resolveCheckRoot(pathArg) {
|
|
6869
|
+
if (pathArg) {
|
|
6870
|
+
const abs = path23__default.resolve(pathArg);
|
|
6871
|
+
if (!fs9__default.existsSync(abs)) {
|
|
6872
|
+
logErr(`Path does not exist: ${abs}`);
|
|
6873
|
+
return null;
|
|
6874
|
+
}
|
|
6875
|
+
return abs;
|
|
6876
|
+
}
|
|
6877
|
+
for (let dir = process.cwd(); ; dir = path23__default.dirname(dir)) {
|
|
6878
|
+
if (fs9__default.existsSync(path23__default.join(dir, SKAILE_MANIFEST_FILENAME))) return dir;
|
|
6879
|
+
if (path23__default.dirname(dir) === dir) return AI_RESOURCES;
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
function changedFiles(root, ref) {
|
|
6883
|
+
try {
|
|
6884
|
+
const out = execFileSync(
|
|
6885
|
+
"git",
|
|
6886
|
+
["diff", "--name-only", "--relative", "--end-of-options", ref],
|
|
6887
|
+
{
|
|
6888
|
+
cwd: root,
|
|
6889
|
+
encoding: "utf-8",
|
|
6890
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
6891
|
+
}
|
|
6892
|
+
);
|
|
6893
|
+
return out.trim().split("\n").filter(Boolean);
|
|
6894
|
+
} catch (err2) {
|
|
6895
|
+
const stderr = err2 instanceof Error && "stderr" in err2 ? String(err2.stderr).trim() : "";
|
|
6896
|
+
const reason = (stderr || (err2 instanceof Error ? err2.message : String(err2))).split("\n")[0];
|
|
6897
|
+
logErr(`git diff failed in ${root}: ${reason}`);
|
|
6898
|
+
return null;
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
function runVersionsCheck(pathArg, opts) {
|
|
6902
|
+
const root = resolveCheckRoot(pathArg);
|
|
6903
|
+
if (root === null) {
|
|
6904
|
+
process.exit(1);
|
|
6905
|
+
return;
|
|
6906
|
+
}
|
|
6907
|
+
let assets = collectAssetVersions(root);
|
|
6625
6908
|
if (opts.changedOnly) {
|
|
6626
|
-
|
|
6909
|
+
const changed = changedFiles(root, "HEAD");
|
|
6910
|
+
if (changed === null) {
|
|
6911
|
+
process.exit(1);
|
|
6912
|
+
return;
|
|
6913
|
+
}
|
|
6914
|
+
const changedAbs = new Set(changed.map((f) => path23__default.resolve(root, f)));
|
|
6915
|
+
assets = assets.filter((a) => changedAbs.has(a.filePath));
|
|
6627
6916
|
}
|
|
6628
|
-
|
|
6917
|
+
logInfo(`Checking versions in ${root}`);
|
|
6918
|
+
const versionCheck = checkAssetVersions(assets, root);
|
|
6629
6919
|
let errors = versionCheck.errors;
|
|
6630
6920
|
let warnings = versionCheck.warnings;
|
|
6631
6921
|
if (opts.changedOnly) {
|
|
6632
|
-
warnings += checkVersionBumps(assets);
|
|
6922
|
+
warnings += checkVersionBumps(assets, root);
|
|
6633
6923
|
}
|
|
6634
|
-
const pinCheck = checkFlowVersionPins(assets);
|
|
6924
|
+
const pinCheck = checkFlowVersionPins(assets, root);
|
|
6635
6925
|
errors += pinCheck.errors;
|
|
6636
6926
|
warnings += pinCheck.warnings;
|
|
6637
6927
|
console.log();
|
|
@@ -6654,7 +6944,7 @@ function makeValidateCommand() {
|
|
|
6654
6944
|
"--strict-conformance",
|
|
6655
6945
|
"Treat Agent Skills (agentskills.io) standard findings as errors"
|
|
6656
6946
|
).action((targetPath, opts) => {
|
|
6657
|
-
const absPath =
|
|
6947
|
+
const absPath = path23__default.resolve(targetPath);
|
|
6658
6948
|
logInfo(`Validating manifests in ${absPath}`);
|
|
6659
6949
|
const { total, errors, warnings } = validateManifests(
|
|
6660
6950
|
absPath,
|
|
@@ -6662,11 +6952,15 @@ function makeValidateCommand() {
|
|
|
6662
6952
|
);
|
|
6663
6953
|
const ws = validateWorkspaceManifests(absPath);
|
|
6664
6954
|
const rootErrors = validatePublishManifestRoots(absPath);
|
|
6665
|
-
const
|
|
6955
|
+
const requiresErrors = validatePublishManifestRequires(absPath);
|
|
6956
|
+
const versionWarnings = validatePublishManifestVersions(absPath);
|
|
6957
|
+
const publisherWarnings = validatePublishManifestPublishers(absPath);
|
|
6958
|
+
const totalErrors = errors + ws.errors + rootErrors + requiresErrors;
|
|
6666
6959
|
console.log();
|
|
6667
6960
|
warnIgnoredDomainFiles(absPath);
|
|
6668
6961
|
logInfo(`Scanned ${total} asset manifest(s) and ${ws.total} skaile.yaml file(s)`);
|
|
6669
|
-
|
|
6962
|
+
const totalWarnings = warnings + versionWarnings + publisherWarnings;
|
|
6963
|
+
if (totalWarnings > 0) logWarn(`${totalWarnings} warning(s)`);
|
|
6670
6964
|
if (totalErrors === 0) {
|
|
6671
6965
|
logOk("All manifests valid");
|
|
6672
6966
|
} else {
|
|
@@ -6674,23 +6968,24 @@ function makeValidateCommand() {
|
|
|
6674
6968
|
process.exit(1);
|
|
6675
6969
|
}
|
|
6676
6970
|
});
|
|
6677
|
-
cmd.command("versions").description("Check version fields and flow version pins").option("--changed-only", "Only check assets modified since last commit").option("--strict", "Exit 1 on warnings (for CI)").
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
});
|
|
6687
|
-
} catch {
|
|
6688
|
-
logErr("Failed to run git diff \u2014 are you in a git repository?");
|
|
6971
|
+
cmd.command("versions").description("Check version fields and flow version pins").argument("[path]", "Library or asset directory (default: the current library)").option("--changed-only", "Only check assets modified since last commit").option("--strict", "Exit 1 on warnings (for CI)").addOption(removedDomainOption()).action(
|
|
6972
|
+
(pathArg, opts) => {
|
|
6973
|
+
rejectRemovedDomainOption(opts);
|
|
6974
|
+
runVersionsCheck(pathArg, opts);
|
|
6975
|
+
}
|
|
6976
|
+
);
|
|
6977
|
+
cmd.command("changelog").description("Check that modified assets have an updated nearest CHANGELOG.md").argument("[path]", "Library or asset directory (default: the current library)").option("--base <ref>", "Git base ref for diff", "HEAD").action((pathArg, opts) => {
|
|
6978
|
+
const root = resolveCheckRoot(pathArg);
|
|
6979
|
+
if (root === null) {
|
|
6689
6980
|
process.exit(1);
|
|
6690
6981
|
return;
|
|
6691
6982
|
}
|
|
6692
|
-
const modifiedFiles =
|
|
6693
|
-
|
|
6983
|
+
const modifiedFiles = changedFiles(root, opts.base);
|
|
6984
|
+
if (modifiedFiles === null) {
|
|
6985
|
+
process.exit(1);
|
|
6986
|
+
return;
|
|
6987
|
+
}
|
|
6988
|
+
const { updated, stale, orphans } = checkChangelogUnits(modifiedFiles, root);
|
|
6694
6989
|
if (updated.length + stale.length + orphans.length === 0) {
|
|
6695
6990
|
logOk("No modified assets found");
|
|
6696
6991
|
return;
|
|
@@ -6734,7 +7029,7 @@ function itemFromRef(raw, defaultKind, ctx) {
|
|
|
6734
7029
|
return { kind: prefixed[1], ref: value };
|
|
6735
7030
|
}
|
|
6736
7031
|
if (PATH_LIKE.test(value)) return { kind: defaultKind, ref: value };
|
|
6737
|
-
if (defaultKind === "skill" && !value.includes("/") && existsSync(
|
|
7032
|
+
if (defaultKind === "skill" && !value.includes("/") && existsSync(path23__default.join(ctx.agentDir, "skills", value, "SKILL.md"))) {
|
|
6738
7033
|
return { kind: "skill", ref: `./skills/${value}` };
|
|
6739
7034
|
}
|
|
6740
7035
|
return { kind: defaultKind, ref: `${defaultKind}:${value}` };
|
|
@@ -6770,6 +7065,9 @@ function itemsFromEntry(field, entry, ctx) {
|
|
|
6770
7065
|
function slugTail(ref) {
|
|
6771
7066
|
return ref.replace(/#.*$/, "").split(/[/:]/).filter(Boolean).pop() ?? ref;
|
|
6772
7067
|
}
|
|
7068
|
+
function aliasSlug(name) {
|
|
7069
|
+
return name.normalize("NFKD").replace(/\p{M}/gu, "").trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
7070
|
+
}
|
|
6773
7071
|
function defaultKindFor(field) {
|
|
6774
7072
|
switch (field) {
|
|
6775
7073
|
case "persona":
|
|
@@ -6867,7 +7165,7 @@ function migrateAgentYaml(source, options) {
|
|
|
6867
7165
|
manual.push("metadata.soul: not a string; left unchanged");
|
|
6868
7166
|
continue;
|
|
6869
7167
|
}
|
|
6870
|
-
if (
|
|
7168
|
+
if (path23__default.posix.basename(soul.replace(/\\/g, "/")).toLowerCase() === "soul.md") {
|
|
6871
7169
|
notes.push("metadata.soul \u2192 dropped (SOUL.md is a convention file)");
|
|
6872
7170
|
} else {
|
|
6873
7171
|
derived.push({ kind: "persona", ref: soul });
|
|
@@ -6933,11 +7231,40 @@ function migrateAgentYaml(source, options) {
|
|
|
6933
7231
|
const seen = new Set(existing.map((i) => `${String(i.kind)}\0${String(i.ref)}`));
|
|
6934
7232
|
const fresh = [];
|
|
6935
7233
|
for (const item of derived) {
|
|
6936
|
-
const
|
|
6937
|
-
if (seen.has(
|
|
6938
|
-
seen.add(
|
|
7234
|
+
const key2 = `${item.kind}\0${item.ref}`;
|
|
7235
|
+
if (seen.has(key2)) continue;
|
|
7236
|
+
seen.add(key2);
|
|
6939
7237
|
fresh.push(item);
|
|
6940
7238
|
}
|
|
7239
|
+
const key = (kind, alias) => `${kind}\0${alias}`;
|
|
7240
|
+
const usedAs = /* @__PURE__ */ new Set([
|
|
7241
|
+
...existing.map(
|
|
7242
|
+
(i) => key(String(i.kind), typeof i.as === "string" ? i.as : aliasSlug(slugTail(String(i.ref))))
|
|
7243
|
+
),
|
|
7244
|
+
...fresh.filter((i) => i.as === void 0).map((i) => key(i.kind, aliasSlug(slugTail(i.ref))))
|
|
7245
|
+
]);
|
|
7246
|
+
for (const item of fresh) {
|
|
7247
|
+
if (item.as === void 0) continue;
|
|
7248
|
+
const original = item.as;
|
|
7249
|
+
const slug = aliasSlug(original);
|
|
7250
|
+
if (!SLOT_ID_PATTERN.test(slug)) {
|
|
7251
|
+
delete item.as;
|
|
7252
|
+
manual.push(
|
|
7253
|
+
`composes ${item.kind} ${item.ref}: name "${original}" cannot be made a valid \`as\` alias ([a-z][a-z0-9_-]*); \`as\` omitted, set one by hand`
|
|
7254
|
+
);
|
|
7255
|
+
} else if (usedAs.has(key(item.kind, slug))) {
|
|
7256
|
+
delete item.as;
|
|
7257
|
+
manual.push(
|
|
7258
|
+
`composes ${item.kind} ${item.ref}: name "${original}" \u2192 "${slug}" collides with another \`as\` in this agent; \`as\` omitted, set a unique one by hand`
|
|
7259
|
+
);
|
|
7260
|
+
} else {
|
|
7261
|
+
usedAs.add(key(item.kind, slug));
|
|
7262
|
+
item.as = slug;
|
|
7263
|
+
if (slug !== original) {
|
|
7264
|
+
notes.push(`composes ${item.kind} ${item.ref}: as "${original}" \u2192 "${slug}"`);
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
}
|
|
6941
7268
|
let changed = false;
|
|
6942
7269
|
const flowItem = (item) => {
|
|
6943
7270
|
const obj = { kind: item.kind, ref: item.ref };
|
|
@@ -6968,10 +7295,10 @@ function migrateAgentYaml(source, options) {
|
|
|
6968
7295
|
let carriedComment;
|
|
6969
7296
|
let carriedSpace = false;
|
|
6970
7297
|
if (anchor >= 0) {
|
|
6971
|
-
const
|
|
6972
|
-
if (isScalar(
|
|
6973
|
-
carriedComment =
|
|
6974
|
-
carriedSpace =
|
|
7298
|
+
const key2 = root.items[anchor].key;
|
|
7299
|
+
if (isScalar(key2)) {
|
|
7300
|
+
carriedComment = key2.commentBefore ?? void 0;
|
|
7301
|
+
carriedSpace = key2.spaceBefore === true;
|
|
6975
7302
|
}
|
|
6976
7303
|
}
|
|
6977
7304
|
if (fresh.length > 0 || removedTop.length > 0 || removedMeta.length > 0) {
|
|
@@ -7009,11 +7336,11 @@ function migrateAgentYaml(source, options) {
|
|
|
7009
7336
|
const metaNode = root.get("metadata", true);
|
|
7010
7337
|
if (isMap(metaNode)) {
|
|
7011
7338
|
for (const field of removedMeta) removeKey(metaNode, field);
|
|
7012
|
-
for (const [
|
|
7339
|
+
for (const [key2, values] of Object.entries(proseNotes)) {
|
|
7013
7340
|
if (values.length === 0) continue;
|
|
7014
|
-
const current = metaNode.get(
|
|
7341
|
+
const current = metaNode.get(key2);
|
|
7015
7342
|
const merged = Array.isArray(current) ? [...current, ...values] : values;
|
|
7016
|
-
metaNode.set(
|
|
7343
|
+
metaNode.set(key2, doc.createNode(merged));
|
|
7017
7344
|
}
|
|
7018
7345
|
if (metaNode.items.length === 0 && removedMeta.length > 0) removeKey(root, "metadata");
|
|
7019
7346
|
}
|
|
@@ -7072,7 +7399,7 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7072
7399
|
if (!isMap(agentNode)) return void 0;
|
|
7073
7400
|
const subNode = agentNode.get("subagents", true);
|
|
7074
7401
|
if (!isMap(subNode)) return void 0;
|
|
7075
|
-
const dir =
|
|
7402
|
+
const dir = path23__default.dirname(skaileYamlPath);
|
|
7076
7403
|
const notes = [];
|
|
7077
7404
|
const manual = [];
|
|
7078
7405
|
const changes = [];
|
|
@@ -7090,10 +7417,10 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7090
7417
|
continue;
|
|
7091
7418
|
}
|
|
7092
7419
|
const id = instanceId(name);
|
|
7093
|
-
const assetDir =
|
|
7420
|
+
const assetDir = path23__default.join(dir, ".skaile", "agents", id);
|
|
7094
7421
|
if (takenIds.has(id) || existsSync(assetDir)) {
|
|
7095
7422
|
manual.push(
|
|
7096
|
-
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${
|
|
7423
|
+
`agent.subagents.${name}: ${takenIds.has(id) ? `agents.${id} already exists` : `${path23__default.relative(dir, assetDir)} already exists`}; left in place`
|
|
7097
7424
|
);
|
|
7098
7425
|
continue;
|
|
7099
7426
|
}
|
|
@@ -7117,13 +7444,13 @@ function migrateSubagents(skaileYamlPath, source) {
|
|
|
7117
7444
|
manifest.tools = { ...allowed ? { allowed } : {}, ...denied ? { denied } : {} };
|
|
7118
7445
|
}
|
|
7119
7446
|
const text = stringify(manifest, { lineWidth: 0 });
|
|
7120
|
-
const manifestPath =
|
|
7447
|
+
const manifestPath = path23__default.join(assetDir, "agent.yaml");
|
|
7121
7448
|
changes.push({ type: "create", path: manifestPath, after: text });
|
|
7122
7449
|
assetManifests.push({ file: manifestPath, text });
|
|
7123
7450
|
if (typeof spec.prompt === "string" && spec.prompt.trim() !== "") {
|
|
7124
7451
|
changes.push({
|
|
7125
7452
|
type: "create",
|
|
7126
|
-
path:
|
|
7453
|
+
path: path23__default.join(assetDir, "SOUL.md"),
|
|
7127
7454
|
after: `${spec.prompt.replace(/\s+$/, "")}
|
|
7128
7455
|
`
|
|
7129
7456
|
});
|
|
@@ -7182,7 +7509,7 @@ function validateMigratedAgent(text, registry) {
|
|
|
7182
7509
|
function collectAgentFiles(paths) {
|
|
7183
7510
|
const files = /* @__PURE__ */ new Set();
|
|
7184
7511
|
for (const input of paths) {
|
|
7185
|
-
const abs =
|
|
7512
|
+
const abs = path23__default.resolve(input);
|
|
7186
7513
|
if (!existsSync(abs)) continue;
|
|
7187
7514
|
if (statSync(abs).isDirectory()) {
|
|
7188
7515
|
for (const f of walkFiles(abs, (b) => b === "agent.yaml" || b === "skaile.yaml"))
|
|
@@ -7199,7 +7526,7 @@ function planAgentMigration(options) {
|
|
|
7199
7526
|
const reports = [];
|
|
7200
7527
|
for (const file of collectAgentFiles(options.paths)) {
|
|
7201
7528
|
const source = readText(file);
|
|
7202
|
-
const base =
|
|
7529
|
+
const base = path23__default.basename(file);
|
|
7203
7530
|
if (base === "skaile.yaml") {
|
|
7204
7531
|
const result = migrateSubagents(file, source);
|
|
7205
7532
|
if (!result) continue;
|
|
@@ -7207,7 +7534,7 @@ function planAgentMigration(options) {
|
|
|
7207
7534
|
for (const asset of result.assetManifests) {
|
|
7208
7535
|
const v = validateMigratedAgent(asset.text, options.registry);
|
|
7209
7536
|
validation2.errors.push(
|
|
7210
|
-
...v.errors.map((e) => `${
|
|
7537
|
+
...v.errors.map((e) => `${path23__default.basename(path23__default.dirname(asset.file))}: ${e}`)
|
|
7211
7538
|
);
|
|
7212
7539
|
validation2.warnings.push(...v.warnings);
|
|
7213
7540
|
}
|
|
@@ -7235,7 +7562,7 @@ function planAgentMigration(options) {
|
|
|
7235
7562
|
});
|
|
7236
7563
|
continue;
|
|
7237
7564
|
}
|
|
7238
|
-
migration = migrateAgentYaml(source, { agentDir:
|
|
7565
|
+
migration = migrateAgentYaml(source, { agentDir: path23__default.dirname(file), knownKinds });
|
|
7239
7566
|
} catch (error) {
|
|
7240
7567
|
reports.push({
|
|
7241
7568
|
file,
|
|
@@ -7264,7 +7591,7 @@ function planAgentMigration(options) {
|
|
|
7264
7591
|
}
|
|
7265
7592
|
var DEFAULT_PUBLISHER = "skaile-ai";
|
|
7266
7593
|
var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
7267
|
-
var posix2 = (p6) => p6.split(
|
|
7594
|
+
var posix2 = (p6) => p6.split(path23__default.sep).join("/");
|
|
7268
7595
|
var MOVED_KINDS = { persona: "PERSONA.md", ruleset: "RULESET.md" };
|
|
7269
7596
|
var KIND_MANIFEST_FILES = /* @__PURE__ */ new Set(["PERSONA.md", "RULESET.md", "SKILL.md"]);
|
|
7270
7597
|
function readFrontmatterType(text) {
|
|
@@ -7295,14 +7622,14 @@ function planMarkdownMoves(root, knownKinds, manual, unknownTypes) {
|
|
|
7295
7622
|
if (!text.startsWith("---")) continue;
|
|
7296
7623
|
const found = readFrontmatterType(text);
|
|
7297
7624
|
if (!found) continue;
|
|
7298
|
-
const base =
|
|
7299
|
-
const inAgentParts = file.split(
|
|
7625
|
+
const base = path23__default.basename(file);
|
|
7626
|
+
const inAgentParts = file.split(path23__default.sep).includes("_agent-parts");
|
|
7300
7627
|
const targetName = MOVED_KINDS[found.type];
|
|
7301
7628
|
if (targetName !== void 0 && !KIND_MANIFEST_FILES.has(base)) {
|
|
7302
|
-
const to =
|
|
7629
|
+
const to = path23__default.join(path23__default.dirname(file), base.replace(/\.md$/i, ""), targetName);
|
|
7303
7630
|
if (existsSync(to) || targets.has(to)) {
|
|
7304
7631
|
manual.push(
|
|
7305
|
-
`${posix2(
|
|
7632
|
+
`${posix2(path23__default.relative(root, file))}: ${posix2(path23__default.relative(root, to))} already exists; not moved`
|
|
7306
7633
|
);
|
|
7307
7634
|
continue;
|
|
7308
7635
|
}
|
|
@@ -7323,13 +7650,13 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7323
7650
|
const changes = [];
|
|
7324
7651
|
for (const file of walkFiles(root, (b) => b === "agent.yaml")) {
|
|
7325
7652
|
const source = readText(file);
|
|
7326
|
-
const agentDir =
|
|
7653
|
+
const agentDir = path23__default.dirname(file);
|
|
7327
7654
|
let hits = 0;
|
|
7328
7655
|
const refRewrite = (_kind, ref) => {
|
|
7329
|
-
const moved = byOldPath.get(
|
|
7656
|
+
const moved = byOldPath.get(path23__default.resolve(agentDir, ref));
|
|
7330
7657
|
if (moved === void 0) return ref;
|
|
7331
7658
|
hits++;
|
|
7332
|
-
const rel = posix2(
|
|
7659
|
+
const rel = posix2(path23__default.relative(agentDir, moved));
|
|
7333
7660
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
7334
7661
|
};
|
|
7335
7662
|
let output;
|
|
@@ -7346,7 +7673,7 @@ function planAgentRefRewrites(root, moves, knownKinds, notes) {
|
|
|
7346
7673
|
if (hits === 0 || output === source) continue;
|
|
7347
7674
|
changes.push({ type: "write", path: file, before: source, after: output });
|
|
7348
7675
|
notes.push(
|
|
7349
|
-
`${posix2(
|
|
7676
|
+
`${posix2(path23__default.relative(root, file))}: persona/ruleset refs \u2192 composes items at the new paths`
|
|
7350
7677
|
);
|
|
7351
7678
|
}
|
|
7352
7679
|
return changes;
|
|
@@ -7371,14 +7698,14 @@ function presetText(name, description, refs, publisher) {
|
|
|
7371
7698
|
}
|
|
7372
7699
|
function skillDirs(dir) {
|
|
7373
7700
|
try {
|
|
7374
|
-
return readdirSync(
|
|
7701
|
+
return readdirSync(path23__default.join(dir, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync(path23__default.join(dir, "skills", e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
7375
7702
|
} catch {
|
|
7376
7703
|
return [];
|
|
7377
7704
|
}
|
|
7378
7705
|
}
|
|
7379
7706
|
function repoPublisher(root) {
|
|
7380
7707
|
for (const name of ["skaile.manifest.yaml", "skaile.yaml"]) {
|
|
7381
|
-
const file =
|
|
7708
|
+
const file = path23__default.join(root, name);
|
|
7382
7709
|
if (!existsSync(file)) continue;
|
|
7383
7710
|
try {
|
|
7384
7711
|
const parsed = parse(readText(file));
|
|
@@ -7394,9 +7721,9 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7394
7721
|
const changes = [];
|
|
7395
7722
|
const presets = [];
|
|
7396
7723
|
const handled = /* @__PURE__ */ new Set();
|
|
7397
|
-
const rel = (p6) => posix2(
|
|
7724
|
+
const rel = (p6) => posix2(path23__default.relative(root, p6));
|
|
7398
7725
|
const convert = (name, bundleFile, dir) => {
|
|
7399
|
-
const target =
|
|
7726
|
+
const target = path23__default.join(dir, `${name}.preset.yaml`);
|
|
7400
7727
|
if (existsSync(target)) {
|
|
7401
7728
|
manual.push(`${rel(target)} already exists; bundle ${name} not converted`);
|
|
7402
7729
|
return;
|
|
@@ -7422,7 +7749,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7422
7749
|
}
|
|
7423
7750
|
if (refs.length === 0) {
|
|
7424
7751
|
manual.push(
|
|
7425
|
-
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(
|
|
7752
|
+
`bundle ${name}: no dependencies found${bundleFile ? ` in ${rel(bundleFile)}` : ` and no skills under ${rel(path23__default.join(dir, "skills"))}`}; no preset generated`
|
|
7426
7753
|
);
|
|
7427
7754
|
return;
|
|
7428
7755
|
}
|
|
@@ -7444,18 +7771,18 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7444
7771
|
const assets = Array.isArray(raw.assets) ? raw.assets : [];
|
|
7445
7772
|
for (const entry of assets) {
|
|
7446
7773
|
if (!isRecord(entry) || entry.kind !== "bundle" || typeof entry.name !== "string") continue;
|
|
7447
|
-
const baseDir =
|
|
7448
|
-
const entryRoot = typeof entry.root === "string" ?
|
|
7774
|
+
const baseDir = path23__default.dirname(file);
|
|
7775
|
+
const entryRoot = typeof entry.root === "string" ? path23__default.join(baseDir, entry.root) : baseDir;
|
|
7449
7776
|
const files = Array.isArray(entry.files) ? entry.files : [];
|
|
7450
7777
|
const bundleName = files.find(
|
|
7451
7778
|
(f) => typeof f === "string" && f.endsWith(".bundle.yaml")
|
|
7452
7779
|
);
|
|
7453
|
-
convert(entry.name, bundleName ?
|
|
7780
|
+
convert(entry.name, bundleName ? path23__default.join(entryRoot, bundleName) : void 0, entryRoot);
|
|
7454
7781
|
}
|
|
7455
7782
|
}
|
|
7456
7783
|
for (const bundleFile of walkFiles(root, (b) => b.endsWith(".bundle.yaml"))) {
|
|
7457
7784
|
if (handled.has(bundleFile)) continue;
|
|
7458
|
-
const base =
|
|
7785
|
+
const base = path23__default.basename(bundleFile);
|
|
7459
7786
|
let name = base.replace(/\.bundle\.yaml$/, "");
|
|
7460
7787
|
try {
|
|
7461
7788
|
const parsed = parse(readText(bundleFile));
|
|
@@ -7464,7 +7791,7 @@ function planBundles(root, skaileYamls, publisher, notes, manual) {
|
|
|
7464
7791
|
} catch {
|
|
7465
7792
|
}
|
|
7466
7793
|
if (presets.some((p6) => p6.bundleFile === bundleFile)) continue;
|
|
7467
|
-
convert(name, bundleFile,
|
|
7794
|
+
convert(name, bundleFile, path23__default.dirname(bundleFile));
|
|
7468
7795
|
}
|
|
7469
7796
|
return changes;
|
|
7470
7797
|
}
|
|
@@ -7474,8 +7801,8 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7474
7801
|
if (doc.errors.length > 0 || !isMap(doc.contents)) return [];
|
|
7475
7802
|
const map = doc.contents;
|
|
7476
7803
|
const raw = doc.toJS();
|
|
7477
|
-
const dir =
|
|
7478
|
-
const rel = (p6) => posix2(
|
|
7804
|
+
const dir = path23__default.dirname(file);
|
|
7805
|
+
const rel = (p6) => posix2(path23__default.relative(root, p6));
|
|
7479
7806
|
const changes = [];
|
|
7480
7807
|
let changed = false;
|
|
7481
7808
|
const deps = map.get("dependencies", true);
|
|
@@ -7492,7 +7819,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7492
7819
|
const hasPublication = PUBLICATION_KEYS.some((k) => raw[k] !== void 0);
|
|
7493
7820
|
let remove = false;
|
|
7494
7821
|
if (hasPublication) {
|
|
7495
|
-
const manifestPath =
|
|
7822
|
+
const manifestPath = path23__default.join(dir, "skaile.manifest.yaml");
|
|
7496
7823
|
if (existsSync(manifestPath)) {
|
|
7497
7824
|
manual.push(
|
|
7498
7825
|
`${rel(file)}: publisher/version/assets left in place \u2014 ${rel(manifestPath)} already exists; merge by hand`
|
|
@@ -7549,7 +7876,7 @@ function planSkaileYaml(root, file, source, notes, manual) {
|
|
|
7549
7876
|
return changes;
|
|
7550
7877
|
}
|
|
7551
7878
|
function planAssetMigration(options) {
|
|
7552
|
-
const root =
|
|
7879
|
+
const root = path23__default.resolve(options.root);
|
|
7553
7880
|
const knownKinds = new Set(options.registry.getAllKinds());
|
|
7554
7881
|
const notes = [];
|
|
7555
7882
|
const manual = [];
|
|
@@ -7557,7 +7884,7 @@ function planAssetMigration(options) {
|
|
|
7557
7884
|
const { moves, changes: moveChanges } = planMarkdownMoves(root, knownKinds, manual, unknownTypes);
|
|
7558
7885
|
for (const move of moves) {
|
|
7559
7886
|
notes.push(
|
|
7560
|
-
`${posix2(
|
|
7887
|
+
`${posix2(path23__default.relative(root, move.from))} \u2192 ${posix2(path23__default.relative(root, move.to))} (${move.kind})`
|
|
7561
7888
|
);
|
|
7562
7889
|
}
|
|
7563
7890
|
const agentChanges = planAgentRefRewrites(root, moves, knownKinds, notes);
|
|
@@ -7569,7 +7896,7 @@ function planAssetMigration(options) {
|
|
|
7569
7896
|
const raw = parse(source);
|
|
7570
7897
|
if (isRecord(raw)) skaileYamls.push({ file, source, raw });
|
|
7571
7898
|
} catch {
|
|
7572
|
-
manual.push(`${posix2(
|
|
7899
|
+
manual.push(`${posix2(path23__default.relative(root, file))}: invalid YAML; skipped`);
|
|
7573
7900
|
}
|
|
7574
7901
|
}
|
|
7575
7902
|
const publisher = repoPublisher(root);
|
|
@@ -7723,7 +8050,7 @@ function workspaceConfigFiles(dir) {
|
|
|
7723
8050
|
} catch {
|
|
7724
8051
|
return [];
|
|
7725
8052
|
}
|
|
7726
|
-
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) =>
|
|
8053
|
+
return names.filter((name) => isWorkspaceConfigFilename(name)).sort().map((name) => path23__default.join(dir, name));
|
|
7727
8054
|
}
|
|
7728
8055
|
function readAgentConfigBlock(raw) {
|
|
7729
8056
|
const key = AGENT_CONFIG_KEYS.find((candidate) => raw[candidate] !== void 0);
|
|
@@ -7735,7 +8062,7 @@ function readAgentConfigBlock(raw) {
|
|
|
7735
8062
|
return flat ? { key, profiles: { default: profiles }, flat } : { key, profiles, flat };
|
|
7736
8063
|
}
|
|
7737
8064
|
function planProviderMigration(options) {
|
|
7738
|
-
const projectDir =
|
|
8065
|
+
const projectDir = path23__default.resolve(options.projectDir);
|
|
7739
8066
|
const registryPath = options.workspace ? workspaceProviderRegistryPath(projectDir) : userProviderRegistryPath();
|
|
7740
8067
|
const plan = {
|
|
7741
8068
|
registryPath,
|
|
@@ -7751,7 +8078,7 @@ function planProviderMigration(options) {
|
|
|
7751
8078
|
raw = parseDocument(readFileSync(file, "utf-8")).toJS() ?? {};
|
|
7752
8079
|
} catch (error) {
|
|
7753
8080
|
plan.warnings.push(
|
|
7754
|
-
`${
|
|
8081
|
+
`${path23__default.basename(file)}: not valid YAML (${error instanceof Error ? error.message : String(error)}) \u2014 skipped`
|
|
7755
8082
|
);
|
|
7756
8083
|
continue;
|
|
7757
8084
|
}
|
|
@@ -7800,7 +8127,7 @@ function planProviderMigration(options) {
|
|
|
7800
8127
|
});
|
|
7801
8128
|
if (!model) {
|
|
7802
8129
|
plan.warnings.push(
|
|
7803
|
-
`${
|
|
8130
|
+
`${path23__default.basename(file)}: profile '${profile}' had no model: \u2014 it now resolves against registry order. Pin it with 'model: ${providerId}/<modelId>'.`
|
|
7804
8131
|
);
|
|
7805
8132
|
}
|
|
7806
8133
|
touched = true;
|
|
@@ -7867,7 +8194,7 @@ function printPlan(plan) {
|
|
|
7867
8194
|
for (const entry of plan.entries) {
|
|
7868
8195
|
const base = entry.entry.base_url ?? S.dim("(transport-derived)");
|
|
7869
8196
|
console.log(
|
|
7870
|
-
` ${S.label(`${
|
|
8197
|
+
` ${S.label(`${path23__default.basename(entry.file)} ${entry.profile}`)} provider: ${entry.legacy.provider}, cloud: ${entry.legacy.cloud}`
|
|
7871
8198
|
);
|
|
7872
8199
|
console.log(` \u2192 providers.yml ${S.bold(entry.providerId)} ${base}`);
|
|
7873
8200
|
console.log(
|
|
@@ -7883,7 +8210,7 @@ function printPlan(plan) {
|
|
|
7883
8210
|
console.log();
|
|
7884
8211
|
}
|
|
7885
8212
|
async function runMigrateProviders(opts) {
|
|
7886
|
-
const projectDir = opts.projectDir ?
|
|
8213
|
+
const projectDir = opts.projectDir ? path23__default.resolve(opts.projectDir) : process.cwd();
|
|
7887
8214
|
const plan = planProviderMigration({ projectDir, workspace: opts.workspace });
|
|
7888
8215
|
for (const warning of plan.warnings) logWarn(warning);
|
|
7889
8216
|
if (plan.entries.length === 0 && Object.keys(plan.providers).length === 0) {
|
|
@@ -8014,7 +8341,7 @@ async function runMigrateAgents(paths, opts) {
|
|
|
8014
8341
|
let failures = 0;
|
|
8015
8342
|
let manualCount = 0;
|
|
8016
8343
|
for (const report of plan.reports) {
|
|
8017
|
-
const rel =
|
|
8344
|
+
const rel = path23__default.relative(base, report.file) || report.file;
|
|
8018
8345
|
for (const note of report.notes) console.log(` ${S.label(rel)} ${note}`);
|
|
8019
8346
|
for (const note of report.manual) {
|
|
8020
8347
|
manualCount++;
|
|
@@ -8041,14 +8368,14 @@ async function runMigrateAssets(root, opts) {
|
|
|
8041
8368
|
const write = resolveMode(opts);
|
|
8042
8369
|
const base = process.cwd();
|
|
8043
8370
|
const plan = planAssetMigration({
|
|
8044
|
-
root:
|
|
8371
|
+
root: path23__default.resolve(root ?? base),
|
|
8045
8372
|
registry: getKindRegistry()
|
|
8046
8373
|
});
|
|
8047
8374
|
for (const note of plan.notes) console.log(` ${note}`);
|
|
8048
8375
|
for (const note of plan.manual) logWarn(note);
|
|
8049
8376
|
for (const { file, type } of plan.unknownTypes) {
|
|
8050
8377
|
logWarn(
|
|
8051
|
-
`${
|
|
8378
|
+
`${path23__default.relative(base, file) || file}: frontmatter type "${type}" is not a registered asset kind (reported, not rewritten)`
|
|
8052
8379
|
);
|
|
8053
8380
|
}
|
|
8054
8381
|
printChanges(plan.changes, base);
|
|
@@ -8071,8 +8398,8 @@ function makeNpxCommand() {
|
|
|
8071
8398
|
skills.command("add <url>").description(
|
|
8072
8399
|
"Clone a repo, register it in the project's skaile.yaml sources[], and install a skill from it"
|
|
8073
8400
|
).requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).option("--global", "Deploy globally").action(async (url, opts) => {
|
|
8074
|
-
const projectDir =
|
|
8075
|
-
const projYaml =
|
|
8401
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8402
|
+
const projYaml = path23__default.join(projectDir, "skaile.yaml");
|
|
8076
8403
|
if (!existsSync(projYaml)) {
|
|
8077
8404
|
logErr(`No skaile.yaml in ${projectDir} \u2014 run \`skaile init\` first.`);
|
|
8078
8405
|
process.exit(1);
|
|
@@ -8085,11 +8412,11 @@ function makeNpxCommand() {
|
|
|
8085
8412
|
}
|
|
8086
8413
|
const spinner = createSpinner();
|
|
8087
8414
|
const key = sourceCacheKey(url);
|
|
8088
|
-
const clonePath =
|
|
8415
|
+
const clonePath = path23__default.join(getGlobalCacheDir(), key);
|
|
8089
8416
|
spinner.start(`Cloning ${url}`);
|
|
8090
8417
|
try {
|
|
8091
8418
|
if (!existsSync(clonePath)) {
|
|
8092
|
-
mkdirSync(
|
|
8419
|
+
mkdirSync(path23__default.dirname(clonePath), { recursive: true });
|
|
8093
8420
|
execSync(`git clone ${url} ${clonePath}`, { stdio: "ignore" });
|
|
8094
8421
|
}
|
|
8095
8422
|
spinner.stop(`Cloned to ${key}`);
|
|
@@ -8144,7 +8471,7 @@ function makeNpxCommand() {
|
|
|
8144
8471
|
return npx;
|
|
8145
8472
|
}
|
|
8146
8473
|
function resolvePublisher(clonePath, url) {
|
|
8147
|
-
const manifestPath =
|
|
8474
|
+
const manifestPath = path23__default.join(clonePath, SKAILE_MANIFEST_FILENAME);
|
|
8148
8475
|
if (existsSync(manifestPath)) {
|
|
8149
8476
|
try {
|
|
8150
8477
|
const { manifest } = decodeSkaileManifest(readFileSync(manifestPath, "utf8"));
|
|
@@ -8157,12 +8484,12 @@ function resolvePublisher(clonePath, url) {
|
|
|
8157
8484
|
return url.match(/github\.com[/:]([^/]+)\/[^/]+/)?.[1];
|
|
8158
8485
|
}
|
|
8159
8486
|
function resolveSkillName(clonePath, requested) {
|
|
8160
|
-
const skillsDir =
|
|
8161
|
-
if (existsSync(
|
|
8487
|
+
const skillsDir = path23__default.join(clonePath, "skills");
|
|
8488
|
+
if (existsSync(path23__default.join(skillsDir, requested, "SKILL.md"))) return requested;
|
|
8162
8489
|
if (!existsSync(skillsDir)) return requested;
|
|
8163
8490
|
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
8164
8491
|
if (!entry.isDirectory()) continue;
|
|
8165
|
-
const md =
|
|
8492
|
+
const md = path23__default.join(skillsDir, entry.name, "SKILL.md");
|
|
8166
8493
|
if (!existsSync(md)) continue;
|
|
8167
8494
|
try {
|
|
8168
8495
|
const { data } = parseFrontmatter(readFileSync(md, "utf8"));
|
|
@@ -8193,7 +8520,7 @@ function makeOutdatedCommand() {
|
|
|
8193
8520
|
).action(async (filter, opts) => {
|
|
8194
8521
|
const am2 = new AssetManager({
|
|
8195
8522
|
registry: getKindRegistry(),
|
|
8196
|
-
projectDir:
|
|
8523
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
8197
8524
|
driverTarget: opts.target
|
|
8198
8525
|
});
|
|
8199
8526
|
const entries = await am2.outdated();
|
|
@@ -8211,7 +8538,7 @@ function makeOutdatedCommand() {
|
|
|
8211
8538
|
console.log(S.heading(" Outdated Assets"));
|
|
8212
8539
|
console.log(` ${S.rule(refW + 34)}`);
|
|
8213
8540
|
for (const e of filtered) {
|
|
8214
|
-
const status4 = e.problem !== void 0 ? e.problem : e.library !== void 0 ? `${e.currentVersion} \u2192 ${e.latestVersion} ${S.dim(`(library ${e.library})`)}` : `${e.behind} commit(s) behind`;
|
|
8541
|
+
const status4 = e.problem !== void 0 ? e.problem : e.contentChanged ? `${e.currentVersion} content changed since lock ${S.dim(`(library ${e.library})`)}` : e.library !== void 0 ? `${e.currentVersion} \u2192 ${e.latestVersion} ${S.dim(`(library ${e.library})`)}` : `${e.behind} commit(s) behind`;
|
|
8215
8542
|
console.log(
|
|
8216
8543
|
` ${colorRef(outdatedRef(e))}${" ".repeat(refW - outdatedRef(e).length)} ${e.problem !== void 0 ? pc5.red(status4) : pc5.yellow(status4)}`
|
|
8217
8544
|
);
|
|
@@ -8230,7 +8557,7 @@ function makePatchCommand() {
|
|
|
8230
8557
|
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8231
8558
|
const am2 = new AssetManager({
|
|
8232
8559
|
registry: getKindRegistry(),
|
|
8233
|
-
projectDir:
|
|
8560
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
8234
8561
|
});
|
|
8235
8562
|
try {
|
|
8236
8563
|
const dest = await am2.patch(ref);
|
|
@@ -8244,7 +8571,7 @@ function makePatchCommand() {
|
|
|
8244
8571
|
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8245
8572
|
const am2 = new AssetManager({
|
|
8246
8573
|
registry: getKindRegistry(),
|
|
8247
|
-
projectDir:
|
|
8574
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
8248
8575
|
});
|
|
8249
8576
|
try {
|
|
8250
8577
|
const patchFile = await am2.patchCommit(ref);
|
|
@@ -8258,7 +8585,7 @@ function makePatchCommand() {
|
|
|
8258
8585
|
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
8259
8586
|
const am2 = new AssetManager({
|
|
8260
8587
|
registry: getKindRegistry(),
|
|
8261
|
-
projectDir:
|
|
8588
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
8262
8589
|
});
|
|
8263
8590
|
try {
|
|
8264
8591
|
await am2.patchSubmit(ref);
|
|
@@ -8274,7 +8601,7 @@ function makePatchCommand() {
|
|
|
8274
8601
|
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
8275
8602
|
const am2 = new AssetManager({
|
|
8276
8603
|
registry: getKindRegistry(),
|
|
8277
|
-
projectDir:
|
|
8604
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
8278
8605
|
});
|
|
8279
8606
|
am2.patchRemove(ref);
|
|
8280
8607
|
logOk(`Patch removed for ${ref}`);
|
|
@@ -8293,7 +8620,7 @@ function action2(fn) {
|
|
|
8293
8620
|
};
|
|
8294
8621
|
}
|
|
8295
8622
|
async function reconcileAndReport(projectDir, plugins) {
|
|
8296
|
-
const { reconcilePlugins } = await import('../plugin-store-
|
|
8623
|
+
const { reconcilePlugins } = await import('../plugin-store-WI4MZJLP.js');
|
|
8297
8624
|
if (plugins.length === 0) {
|
|
8298
8625
|
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
8299
8626
|
return;
|
|
@@ -8307,10 +8634,10 @@ async function reconcileAndReport(projectDir, plugins) {
|
|
|
8307
8634
|
}
|
|
8308
8635
|
}
|
|
8309
8636
|
async function runInstall2(spec, opts) {
|
|
8310
|
-
const projectDir =
|
|
8637
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8311
8638
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8312
|
-
const { specName } = await import('../plugin-store-
|
|
8313
|
-
const yamlPath =
|
|
8639
|
+
const { specName } = await import('../plugin-store-WI4MZJLP.js');
|
|
8640
|
+
const yamlPath = path23__default.join(projectDir, "skaile.yaml");
|
|
8314
8641
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8315
8642
|
const replaced = editor.addPlugin(spec, specName);
|
|
8316
8643
|
editor.save();
|
|
@@ -8319,10 +8646,10 @@ async function runInstall2(spec, opts) {
|
|
|
8319
8646
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8320
8647
|
}
|
|
8321
8648
|
async function runRemove(name, opts) {
|
|
8322
|
-
const projectDir =
|
|
8649
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8323
8650
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
8324
|
-
const { specName } = await import('../plugin-store-
|
|
8325
|
-
const yamlPath =
|
|
8651
|
+
const { specName } = await import('../plugin-store-WI4MZJLP.js');
|
|
8652
|
+
const yamlPath = path23__default.join(projectDir, "skaile.yaml");
|
|
8326
8653
|
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
8327
8654
|
const removed = editor.removePlugin(name, specName);
|
|
8328
8655
|
if (!removed) {
|
|
@@ -8334,7 +8661,7 @@ async function runRemove(name, opts) {
|
|
|
8334
8661
|
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
8335
8662
|
}
|
|
8336
8663
|
async function runList(opts) {
|
|
8337
|
-
const projectDir =
|
|
8664
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8338
8665
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
8339
8666
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
8340
8667
|
const declared = config.plugins ?? [];
|
|
@@ -8349,7 +8676,7 @@ async function runList(opts) {
|
|
|
8349
8676
|
const registry = createPluginRegistry();
|
|
8350
8677
|
if (declared.length > 0) {
|
|
8351
8678
|
try {
|
|
8352
|
-
const { loadPlugins } = await import('../plugin-store-
|
|
8679
|
+
const { loadPlugins } = await import('../plugin-store-WI4MZJLP.js');
|
|
8353
8680
|
const result = await loadPlugins(projectDir, declared, registry);
|
|
8354
8681
|
for (const f of result.failed) logWarn(f.error);
|
|
8355
8682
|
} catch (err2) {
|
|
@@ -8524,7 +8851,7 @@ function neededSources(config, lock) {
|
|
|
8524
8851
|
}
|
|
8525
8852
|
function sourcesWithSidecar(sources) {
|
|
8526
8853
|
const dir = getStoreManifestsDir();
|
|
8527
|
-
return sources.filter((s) => existsSync(
|
|
8854
|
+
return sources.filter((s) => existsSync(path23.join(dir, `${storeManifestSlug(s.url)}.yaml`))).map((s) => s.url);
|
|
8528
8855
|
}
|
|
8529
8856
|
function compact(obj) {
|
|
8530
8857
|
const out = {};
|
|
@@ -8640,7 +8967,7 @@ function makePresetCommand() {
|
|
|
8640
8967
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
8641
8968
|
const presetName = name ?? "my-preset";
|
|
8642
8969
|
const filename = `${presetName}.preset.yaml`;
|
|
8643
|
-
const outPath =
|
|
8970
|
+
const outPath = path23__default.join(path23__default.resolve(opts.dir), filename);
|
|
8644
8971
|
if (existsSync(outPath)) {
|
|
8645
8972
|
logErr(`File already exists: ${outPath}`);
|
|
8646
8973
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -8673,7 +9000,7 @@ function makePresetCommand() {
|
|
|
8673
9000
|
return cmd;
|
|
8674
9001
|
}
|
|
8675
9002
|
async function runPresetExport(name, opts) {
|
|
8676
|
-
const projectDir =
|
|
9003
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8677
9004
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
8678
9005
|
if (!file) {
|
|
8679
9006
|
logErr(`No skaile.yaml found in ${projectDir}`);
|
|
@@ -8683,7 +9010,7 @@ async function runPresetExport(name, opts) {
|
|
|
8683
9010
|
const presetName = name ?? file.config.name ?? "my-preset";
|
|
8684
9011
|
let lock = null;
|
|
8685
9012
|
try {
|
|
8686
|
-
lock = readLock(
|
|
9013
|
+
lock = readLock(path23__default.join(projectDir, "skaile.lock.yaml"));
|
|
8687
9014
|
} catch {
|
|
8688
9015
|
lock = null;
|
|
8689
9016
|
}
|
|
@@ -8724,7 +9051,7 @@ async function runPresetExport(name, opts) {
|
|
|
8724
9051
|
const contents = header ? `${header}
|
|
8725
9052
|
${body}` : body;
|
|
8726
9053
|
if (opts.out && opts.dir !== process.cwd()) logWarn("--dir is ignored when --out is set.");
|
|
8727
|
-
const outPath = opts.out ?
|
|
9054
|
+
const outPath = opts.out ? path23__default.resolve(opts.out) : path23__default.join(path23__default.resolve(opts.dir), `${presetName}.preset.yaml`);
|
|
8728
9055
|
if (existsSync(outPath) && !opts.force) {
|
|
8729
9056
|
logErr(`File already exists: ${outPath}`);
|
|
8730
9057
|
logInfo("Pass --force to overwrite, or choose a different --out/--dir.");
|
|
@@ -8736,7 +9063,7 @@ ${body}` : body;
|
|
|
8736
9063
|
logErr(`Failed to write ${outPath}: ${e.message}`);
|
|
8737
9064
|
process.exit(1);
|
|
8738
9065
|
}
|
|
8739
|
-
logOk(`Exported ${S.brand(
|
|
9066
|
+
logOk(`Exported ${S.brand(path23__default.basename(outPath))}`);
|
|
8740
9067
|
logInfo(`Path: ${outPath}`);
|
|
8741
9068
|
if (unresolved.length > 0) {
|
|
8742
9069
|
console.error(S.err("This file is NOT safe to share."));
|
|
@@ -8777,13 +9104,13 @@ function collectInput(value, acc) {
|
|
|
8777
9104
|
return acc;
|
|
8778
9105
|
}
|
|
8779
9106
|
async function runPresetApply(filePath, opts) {
|
|
8780
|
-
const projectDir =
|
|
9107
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
8781
9108
|
const file = loadSkWorkspaceConfig(projectDir);
|
|
8782
9109
|
if (!file) {
|
|
8783
9110
|
logErr("No skaile.yaml \u2014 run `skaile init` first");
|
|
8784
9111
|
process.exit(1);
|
|
8785
9112
|
}
|
|
8786
|
-
const resolved =
|
|
9113
|
+
const resolved = path23__default.resolve(filePath);
|
|
8787
9114
|
if (!existsSync(resolved)) {
|
|
8788
9115
|
logErr(`File not found: ${resolved}`);
|
|
8789
9116
|
process.exit(1);
|
|
@@ -8962,7 +9289,7 @@ async function runPresetInstall(projectDir) {
|
|
|
8962
9289
|
logInfo("Installing new dependencies\u2026");
|
|
8963
9290
|
const result = await am2.install({});
|
|
8964
9291
|
for (const d of result.deployed) logOk(d);
|
|
8965
|
-
for (const m of result.missing) logErr(`Missing: ${m}`);
|
|
9292
|
+
for (const m of result.missing) logErr(`Missing: ${m}${result.missingHints?.[m] ?? ""}`);
|
|
8966
9293
|
await reportInstalledSoftDeps(am2);
|
|
8967
9294
|
} catch (err2) {
|
|
8968
9295
|
logErr(`Install failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
@@ -8999,7 +9326,7 @@ async function reportNestedPresetRefs(preset) {
|
|
|
8999
9326
|
}
|
|
9000
9327
|
async function checkPresetCycles(preset, resolved) {
|
|
9001
9328
|
const { detectCycles } = await import('../discovery/index.js');
|
|
9002
|
-
const presetRef =
|
|
9329
|
+
const presetRef = path23__default.basename(resolved, ".preset.yaml");
|
|
9003
9330
|
const edges = [];
|
|
9004
9331
|
for (const item of preset.items) {
|
|
9005
9332
|
if (item.ref) {
|
|
@@ -9051,7 +9378,7 @@ function printPresetSummary(preset, placeholderCount, hasWarnings) {
|
|
|
9051
9378
|
}
|
|
9052
9379
|
}
|
|
9053
9380
|
async function runPresetValidate(filePath) {
|
|
9054
|
-
const resolved =
|
|
9381
|
+
const resolved = path23__default.resolve(filePath);
|
|
9055
9382
|
const preset = await loadPresetForValidation(resolved);
|
|
9056
9383
|
await reportNestedPresetRefs(preset);
|
|
9057
9384
|
await checkPresetCycles(preset, resolved);
|
|
@@ -9101,11 +9428,11 @@ items:
|
|
|
9101
9428
|
}
|
|
9102
9429
|
function makeRebuildCommand() {
|
|
9103
9430
|
return new Command("rebuild").description("Re-snapshot inline-snapshot composition items and bump prompt version").argument("[agent]", "Agent name or path (defaults to current project agent)").option("--project-dir <dir>", "Project directory", process.cwd()).action(async (agentArg, opts) => {
|
|
9104
|
-
const projectDir =
|
|
9431
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
9105
9432
|
let agentDir;
|
|
9106
9433
|
if (agentArg) {
|
|
9107
9434
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
9108
|
-
agentDir =
|
|
9435
|
+
agentDir = path23__default.resolve(projectDir, agentArg);
|
|
9109
9436
|
} else {
|
|
9110
9437
|
let resolved;
|
|
9111
9438
|
try {
|
|
@@ -9114,7 +9441,7 @@ function makeRebuildCommand() {
|
|
|
9114
9441
|
if (!(err2 instanceof AgentRefResolutionError)) throw err2;
|
|
9115
9442
|
logWarn(`${err2.message} \u2014 using "${agentArg}"`);
|
|
9116
9443
|
}
|
|
9117
|
-
agentDir = resolved ??
|
|
9444
|
+
agentDir = resolved ?? path23__default.resolve(projectDir, agentArg);
|
|
9118
9445
|
}
|
|
9119
9446
|
} else {
|
|
9120
9447
|
let resolved;
|
|
@@ -9184,9 +9511,9 @@ Try a different harness with \`--driver claude-sdk\`.`;
|
|
|
9184
9511
|
// cli/src/commands/run.ts
|
|
9185
9512
|
function resolveSingleShotAgentDir(projectDir, agentDefinition) {
|
|
9186
9513
|
if (!agentDefinition) return resolveAgentDir(projectDir);
|
|
9187
|
-
const asPath = agentDefinition.endsWith("agent.yaml") ?
|
|
9514
|
+
const asPath = agentDefinition.endsWith("agent.yaml") ? path23__default.dirname(path23__default.resolve(projectDir, agentDefinition)) : agentDefinition;
|
|
9188
9515
|
const dir = resolveAgentDefinitionDir(projectDir, asPath);
|
|
9189
|
-
if (!dir || !
|
|
9516
|
+
if (!dir || !fs9__default.existsSync(path23__default.join(dir, "agent.yaml"))) {
|
|
9190
9517
|
throw new Error(
|
|
9191
9518
|
`--agent-definition "${agentDefinition}" does not resolve to an agent directory with agent.yaml${dir ? ` (looked in ${dir})` : ""}`
|
|
9192
9519
|
);
|
|
@@ -9285,7 +9612,7 @@ function makeRunCommand() {
|
|
|
9285
9612
|
"--agent-definition <ref|path>",
|
|
9286
9613
|
"Agent asset for this one invocation (agent:@pub/name, ai-assets://\u2026, or a directory with agent.yaml); single-shot prompts only"
|
|
9287
9614
|
).option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
9288
|
-
const projectDir =
|
|
9615
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
9289
9616
|
const cliDriver = opts.driver;
|
|
9290
9617
|
const dryRun = opts.dryRun ?? false;
|
|
9291
9618
|
const agentDefinition = opts.agentDefinition?.trim() || void 0;
|
|
@@ -9404,7 +9731,7 @@ function makeRunCommand() {
|
|
|
9404
9731
|
}
|
|
9405
9732
|
function makeResumeCommand() {
|
|
9406
9733
|
const cmd = new Command("resume").description("Resume current session").option("--project-dir <path>", "Project directory", process.cwd()).option("--session <run-id>", "Target session by runId").option("--dry-run", "Print plan without executing").action(async (opts) => {
|
|
9407
|
-
const projectDir =
|
|
9734
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
9408
9735
|
const sessionId = opts.session;
|
|
9409
9736
|
const dryRun = opts.dryRun ?? false;
|
|
9410
9737
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -9431,7 +9758,7 @@ function makeResumeCommand() {
|
|
|
9431
9758
|
}
|
|
9432
9759
|
function makeStatusCommand() {
|
|
9433
9760
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9434
|
-
const projectDir =
|
|
9761
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
9435
9762
|
const session = await loadSession(projectDir);
|
|
9436
9763
|
if (!session) {
|
|
9437
9764
|
logInfo("No active session.");
|
|
@@ -9456,7 +9783,7 @@ function makeStatusCommand() {
|
|
|
9456
9783
|
}
|
|
9457
9784
|
function makeClearCommand() {
|
|
9458
9785
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
9459
|
-
const projectDir =
|
|
9786
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
9460
9787
|
await clearSession(projectDir);
|
|
9461
9788
|
logOk("Session cleared.");
|
|
9462
9789
|
});
|
|
@@ -9466,7 +9793,7 @@ function makeReplCommand() {
|
|
|
9466
9793
|
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
9467
9794
|
const { startRepl } = await import('../tui/index.js');
|
|
9468
9795
|
const os2 = await import('os');
|
|
9469
|
-
const userCwd =
|
|
9796
|
+
const userCwd = path23__default.resolve(opts.projectDir ?? process.cwd());
|
|
9470
9797
|
const workspaceRoot = findWorkspaceRoot(userCwd);
|
|
9471
9798
|
let projectDir;
|
|
9472
9799
|
let agentCwd;
|
|
@@ -9488,13 +9815,13 @@ function makeReplCommand() {
|
|
|
9488
9815
|
p4.cancel("Cancelled.");
|
|
9489
9816
|
process.exit(0);
|
|
9490
9817
|
}
|
|
9491
|
-
const tmpDir =
|
|
9818
|
+
const tmpDir = fs9__default.mkdtempSync(path23__default.join(os2.tmpdir(), "skaile-repl-"));
|
|
9492
9819
|
projectDir = tmpDir;
|
|
9493
9820
|
agentCwd = userCwd;
|
|
9494
9821
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
9495
9822
|
if (!driverOverride) {
|
|
9496
|
-
const claudeDir =
|
|
9497
|
-
if (
|
|
9823
|
+
const claudeDir = path23__default.join(os2.homedir(), ".claude");
|
|
9824
|
+
if (fs9__default.existsSync(claudeDir)) {
|
|
9498
9825
|
driverOverride = "claude-sdk";
|
|
9499
9826
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} harness`);
|
|
9500
9827
|
} else {
|
|
@@ -9566,12 +9893,12 @@ function makeServeCommand() {
|
|
|
9566
9893
|
);
|
|
9567
9894
|
}
|
|
9568
9895
|
async function ensurePluginsLoadedForServe(projectDir) {
|
|
9569
|
-
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-
|
|
9896
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-KC5O7CML.js');
|
|
9570
9897
|
try {
|
|
9571
9898
|
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
9572
9899
|
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
9573
9900
|
if (!config.plugins || config.plugins.length === 0) return;
|
|
9574
|
-
const { ensurePluginsLoaded } = await import('../plugin-store-
|
|
9901
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-WI4MZJLP.js');
|
|
9575
9902
|
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
9576
9903
|
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
9577
9904
|
if (result.loaded.length > 0) {
|
|
@@ -9585,14 +9912,14 @@ async function ensurePluginsLoadedForServe(projectDir) {
|
|
|
9585
9912
|
}
|
|
9586
9913
|
}
|
|
9587
9914
|
async function runCompileTest(opts) {
|
|
9588
|
-
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-
|
|
9915
|
+
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-KC5O7CML.js');
|
|
9589
9916
|
const { tmpdir } = await import('os');
|
|
9590
9917
|
const { dirname: dirname3, join: join7, resolve: resolve5 } = await import('path');
|
|
9591
9918
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
9592
9919
|
const { unlinkSync, existsSync: existsSync18 } = await import('fs');
|
|
9593
9920
|
const { spawn } = await import('child_process');
|
|
9594
9921
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
9595
|
-
const { MONOREPO_ROOT } = await import('../paths-
|
|
9922
|
+
const { MONOREPO_ROOT } = await import('../paths-JKEKXM52.js');
|
|
9596
9923
|
if (MONOREPO_ROOT === null) {
|
|
9597
9924
|
logErr2("--compile-test is only available inside the skaile-dev workspace.");
|
|
9598
9925
|
logInfo2("Run it from a checkout of skaile-ai/skaile-dev (the monorepo shell).");
|
|
@@ -10075,7 +10402,7 @@ function resolveMode2(opts) {
|
|
|
10075
10402
|
if (opts.forceLocal && opts.forceRemote) {
|
|
10076
10403
|
throw new Error("Cannot use both --local and --remote");
|
|
10077
10404
|
}
|
|
10078
|
-
const startDir =
|
|
10405
|
+
const startDir = path23__default.resolve(opts.projectDir ?? process.cwd());
|
|
10079
10406
|
const localDb = findLogsDb(startDir);
|
|
10080
10407
|
if (opts.forceLocal) {
|
|
10081
10408
|
if (!localDb) {
|
|
@@ -10108,14 +10435,14 @@ function resolveMode2(opts) {
|
|
|
10108
10435
|
function findLogsDb(startDir) {
|
|
10109
10436
|
let dir = startDir;
|
|
10110
10437
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
10111
|
-
const candidate =
|
|
10438
|
+
const candidate = path23__default.join(dir, ".skaile", "logs.db");
|
|
10112
10439
|
if (existsSync(candidate)) {
|
|
10113
10440
|
try {
|
|
10114
10441
|
if (statSync(candidate).isFile()) return candidate;
|
|
10115
10442
|
} catch {
|
|
10116
10443
|
}
|
|
10117
10444
|
}
|
|
10118
|
-
const parent =
|
|
10445
|
+
const parent = path23__default.dirname(dir);
|
|
10119
10446
|
if (parent === dir) return void 0;
|
|
10120
10447
|
dir = parent;
|
|
10121
10448
|
}
|
|
@@ -10290,7 +10617,7 @@ function parsePositiveInt(value, flag) {
|
|
|
10290
10617
|
function makeSessionCommand() {
|
|
10291
10618
|
const cmd = new Command("session").description("Manage sessions");
|
|
10292
10619
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10293
|
-
const projectDir =
|
|
10620
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
10294
10621
|
const sessions = await listSessions(projectDir);
|
|
10295
10622
|
const current = await loadSession(projectDir);
|
|
10296
10623
|
if (sessions.length === 0) {
|
|
@@ -10318,7 +10645,7 @@ function makeSessionCommand() {
|
|
|
10318
10645
|
console.log();
|
|
10319
10646
|
});
|
|
10320
10647
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10321
|
-
const projectDir =
|
|
10648
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
10322
10649
|
const session = await loadSessionById(projectDir, runId);
|
|
10323
10650
|
if (!session) {
|
|
10324
10651
|
logErr(`Session not found: ${runId}`);
|
|
@@ -10327,12 +10654,12 @@ function makeSessionCommand() {
|
|
|
10327
10654
|
console.log(JSON.stringify(session, null, 2));
|
|
10328
10655
|
});
|
|
10329
10656
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10330
|
-
const projectDir =
|
|
10657
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
10331
10658
|
await setCurrentSession(projectDir, runId);
|
|
10332
10659
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
10333
10660
|
});
|
|
10334
10661
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
10335
|
-
const projectDir =
|
|
10662
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
10336
10663
|
await deleteSession(projectDir, runId);
|
|
10337
10664
|
logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
|
|
10338
10665
|
});
|
|
@@ -10386,12 +10713,12 @@ function showOverview(am2) {
|
|
|
10386
10713
|
}
|
|
10387
10714
|
async function showAsset(am2, kind, name) {
|
|
10388
10715
|
const entry = await am2.info(`${kind}:${name}`);
|
|
10389
|
-
if (entry?.source &&
|
|
10716
|
+
if (entry?.source && fs9__default.existsSync(entry.source)) {
|
|
10390
10717
|
console.log();
|
|
10391
10718
|
console.log(` ${kindColor(entry.kind)} ${S.heading(entry.name)}`);
|
|
10392
10719
|
console.log(` ${S.rule(40)}`);
|
|
10393
10720
|
console.log();
|
|
10394
|
-
console.log(
|
|
10721
|
+
console.log(fs9__default.readFileSync(entry.source, "utf-8"));
|
|
10395
10722
|
return;
|
|
10396
10723
|
}
|
|
10397
10724
|
logErr(`Asset not found: ${kind}:${name}`);
|
|
@@ -10401,7 +10728,7 @@ function makeShowCommand() {
|
|
|
10401
10728
|
return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, preset, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", `Agent framework (${TARGET_DEFAULT_HINT})`).action(async (kind, name, opts) => {
|
|
10402
10729
|
const am2 = new AssetManager({
|
|
10403
10730
|
registry: getKindRegistry(),
|
|
10404
|
-
projectDir:
|
|
10731
|
+
projectDir: path23__default.resolve(opts.projectDir),
|
|
10405
10732
|
driverTarget: opts.target
|
|
10406
10733
|
});
|
|
10407
10734
|
if (!kind) {
|
|
@@ -10464,14 +10791,14 @@ function makeStoreCommand() {
|
|
|
10464
10791
|
});
|
|
10465
10792
|
store.command("mode <auto|local|remote>").description("Set the catalog resolution mode (not yet wired)").action((_mode) => {
|
|
10466
10793
|
logErr(
|
|
10467
|
-
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${
|
|
10794
|
+
`\`skaile store mode\` is scaffolded but not yet wired. Store config lives at ${path23__default.join(globalSkaileDir(), "store", "config.yaml")}.`
|
|
10468
10795
|
);
|
|
10469
10796
|
process.exit(2);
|
|
10470
10797
|
});
|
|
10471
10798
|
store.command("search <query>").description("Search the AI Asset Store catalog by name, description, or publisher").option("--kind <kind>", "Filter by asset kind (skill, agent, prompt, flow, \u2026)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (query, opts) => {
|
|
10472
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
10799
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-P3D337NH.js');
|
|
10473
10800
|
try {
|
|
10474
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
10801
|
+
const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
|
|
10475
10802
|
const assets = await remote.listAssets(opts.kind ? { kind: opts.kind } : {});
|
|
10476
10803
|
const results = filterCatalogAssets(assets, query);
|
|
10477
10804
|
if (results.length === 0) {
|
|
@@ -10486,7 +10813,7 @@ function makeStoreCommand() {
|
|
|
10486
10813
|
`
|
|
10487
10814
|
);
|
|
10488
10815
|
} catch (e) {
|
|
10489
|
-
if (e instanceof
|
|
10816
|
+
if (e instanceof LocalCatalogDisabledError2) {
|
|
10490
10817
|
logErr(
|
|
10491
10818
|
`Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
|
|
10492
10819
|
);
|
|
@@ -10497,10 +10824,10 @@ function makeStoreCommand() {
|
|
|
10497
10824
|
}
|
|
10498
10825
|
});
|
|
10499
10826
|
store.command("show <ref>").description("Show a store asset's details + provenance (source, files, integrity)").option("-C, --project-dir <dir>", "Project directory (catalog config overlay)", process.cwd()).action(async (ref, opts) => {
|
|
10500
|
-
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError } = await import('../open-library-
|
|
10501
|
-
const { supportsInstallManifest } = await import('../project-
|
|
10827
|
+
const { openCatalogSource: openCatalogSource2, LocalCatalogDisabledError: LocalCatalogDisabledError2 } = await import('../open-library-P3D337NH.js');
|
|
10828
|
+
const { supportsInstallManifest } = await import('../project-WFUDVYNN.js');
|
|
10502
10829
|
try {
|
|
10503
|
-
const remote = await openCatalogSource2({ projectDir:
|
|
10830
|
+
const remote = await openCatalogSource2({ projectDir: path23__default.resolve(opts.projectDir) });
|
|
10504
10831
|
const asset = await remote.resolve(ref);
|
|
10505
10832
|
if (!asset) {
|
|
10506
10833
|
logErr(`Not found in store: ${ref} (try a full ref, e.g. skill:@publisher/name#version)`);
|
|
@@ -10548,7 +10875,7 @@ function makeStoreCommand() {
|
|
|
10548
10875
|
console.log(` ${S.dim(`Install: skaile add ${canonical}`)}`);
|
|
10549
10876
|
console.log();
|
|
10550
10877
|
} catch (e) {
|
|
10551
|
-
if (e instanceof
|
|
10878
|
+
if (e instanceof LocalCatalogDisabledError2) {
|
|
10552
10879
|
logErr(
|
|
10553
10880
|
`Remote catalog disabled (catalog.url: local). Set \`catalog.url: https://skaile.store\` in ${userConfigPath()}.`
|
|
10554
10881
|
);
|
|
@@ -10624,7 +10951,7 @@ function makeTreeCommand() {
|
|
|
10624
10951
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
10625
10952
|
const am2 = new AssetManager({
|
|
10626
10953
|
registry: getKindRegistry(),
|
|
10627
|
-
projectDir:
|
|
10954
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
10628
10955
|
});
|
|
10629
10956
|
const root = am2.tree();
|
|
10630
10957
|
if (root.children.length === 0) {
|
|
@@ -10651,20 +10978,24 @@ function makeUpdateCommand() {
|
|
|
10651
10978
|
const catalogSpinner = createSpinner();
|
|
10652
10979
|
catalogSpinner.start("Refreshing catalog cache");
|
|
10653
10980
|
try {
|
|
10654
|
-
const remote = await openCatalogSource({ projectDir:
|
|
10981
|
+
const remote = await openCatalogSource({ projectDir: path23__default.resolve(opts.projectDir) });
|
|
10655
10982
|
const result2 = await remote.refresh();
|
|
10656
10983
|
catalogSpinner.stop(
|
|
10657
10984
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
10658
10985
|
);
|
|
10659
10986
|
logInfo(`Source: ${remote.baseUrl}`);
|
|
10660
10987
|
} catch (err2) {
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10988
|
+
if (err2 instanceof LocalCatalogDisabledError) {
|
|
10989
|
+
catalogSpinner.stop("Catalog refresh skipped (catalog.url: local)");
|
|
10990
|
+
} else {
|
|
10991
|
+
catalogSpinner.stop("Catalog refresh failed");
|
|
10992
|
+
logErr(`Catalog refresh failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
10993
|
+
logInfo("Continuing with asset re-deploy. Run `skaile catalog test` to debug.");
|
|
10994
|
+
}
|
|
10664
10995
|
}
|
|
10665
10996
|
}
|
|
10666
10997
|
if (opts.catalogOnly) return;
|
|
10667
|
-
const projectDir =
|
|
10998
|
+
const projectDir = path23__default.resolve(opts.projectDir);
|
|
10668
10999
|
if (await shouldSyncSources(opts)) {
|
|
10669
11000
|
const syncSpinner = createSpinner();
|
|
10670
11001
|
syncSpinner.start("Syncing sources");
|
|
@@ -10808,7 +11139,7 @@ function makeWhyCommand() {
|
|
|
10808
11139
|
return new Command("why").description("Show why an asset is installed (dependency chain)").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).action(async (ref, opts) => {
|
|
10809
11140
|
const am2 = new AssetManager({
|
|
10810
11141
|
registry: getKindRegistry(),
|
|
10811
|
-
projectDir:
|
|
11142
|
+
projectDir: path23__default.resolve(opts.projectDir)
|
|
10812
11143
|
});
|
|
10813
11144
|
const chain = am2.why(ref);
|
|
10814
11145
|
if (chain.length === 0) {
|
|
@@ -10843,10 +11174,19 @@ function makeWhyCommand() {
|
|
|
10843
11174
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
10844
11175
|
var pkg = JSON.parse(
|
|
10845
11176
|
readFileSync(
|
|
10846
|
-
|
|
11177
|
+
path23__default.resolve(path23__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
10847
11178
|
"utf-8"
|
|
10848
11179
|
)
|
|
10849
11180
|
);
|
|
11181
|
+
for (const key of [
|
|
11182
|
+
"SKAILE_HOME",
|
|
11183
|
+
"SKAILE_INDEX_PATH",
|
|
11184
|
+
"SKAILE_LIBRARIES_DIR",
|
|
11185
|
+
"SKAILE_CACHE_DIR"
|
|
11186
|
+
]) {
|
|
11187
|
+
const value = process.env[key];
|
|
11188
|
+
if (value) process.env[key] = path23__default.resolve(value);
|
|
11189
|
+
}
|
|
10850
11190
|
var program = new Command("skaile").description("AI asset manager").version(pkg.version, "-v, --version", "Show the skaile CLI version").enablePositionalOptions().configureHelp({
|
|
10851
11191
|
formatHelp(cmd, helper) {
|
|
10852
11192
|
if (cmd.name() !== "skaile") return _defaultFormatHelp.call(helper, cmd, helper);
|
|
@@ -10906,7 +11246,7 @@ Execution:
|
|
|
10906
11246
|
debug tools|connectors|mcp|config|state Inspect running container state
|
|
10907
11247
|
connect <url> Interactive WebSocket REPL
|
|
10908
11248
|
logs [--follow] [--filter] Tail skaile container logs
|
|
10909
|
-
session list|show|switch|
|
|
11249
|
+
session list|show|switch|delete Session management
|
|
10910
11250
|
status Current session state
|
|
10911
11251
|
clear Unset current session
|
|
10912
11252
|
|
|
@@ -10974,31 +11314,31 @@ async function runInit(projectDir, opts) {
|
|
|
10974
11314
|
process.exitCode = 1;
|
|
10975
11315
|
return;
|
|
10976
11316
|
}
|
|
10977
|
-
const resolved =
|
|
10978
|
-
const projectName =
|
|
11317
|
+
const resolved = path23__default.resolve(projectDir ?? ".");
|
|
11318
|
+
const projectName = path23__default.basename(resolved);
|
|
10979
11319
|
const created = [];
|
|
10980
11320
|
const { existsSync: existsSync18 } = await import('fs');
|
|
10981
11321
|
if (!existsSync18(resolved)) {
|
|
10982
11322
|
mkdirSync5(resolved, { recursive: true });
|
|
10983
11323
|
created.push(".");
|
|
10984
11324
|
}
|
|
10985
|
-
const skaileDir =
|
|
11325
|
+
const skaileDir = path23__default.join(resolved, ".skaile");
|
|
10986
11326
|
if (!existsSync18(skaileDir)) {
|
|
10987
|
-
mkdirSync5(
|
|
11327
|
+
mkdirSync5(path23__default.join(skaileDir, "sessions"), { recursive: true });
|
|
10988
11328
|
created.push(".skaile/");
|
|
10989
11329
|
}
|
|
10990
|
-
const settingsPath =
|
|
11330
|
+
const settingsPath = path23__default.join(skaileDir, "settings.json");
|
|
10991
11331
|
if (!existsSync18(settingsPath)) {
|
|
10992
11332
|
writeFileSync7(settingsPath, "{}\n");
|
|
10993
11333
|
created.push(".skaile/settings.json");
|
|
10994
11334
|
}
|
|
10995
|
-
const wsConfigPath =
|
|
11335
|
+
const wsConfigPath = path23__default.join(resolved, "skaile.yaml");
|
|
10996
11336
|
if (!existsSync18(wsConfigPath)) {
|
|
10997
11337
|
writeFileSync7(wsConfigPath, stringify2(buildInitWorkspaceConfig(projectName, harness)));
|
|
10998
11338
|
created.push("skaile.yaml");
|
|
10999
11339
|
}
|
|
11000
11340
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[harness].local))) {
|
|
11001
|
-
const full =
|
|
11341
|
+
const full = path23__default.join(resolved, dir);
|
|
11002
11342
|
if (!existsSync18(full)) {
|
|
11003
11343
|
mkdirSync5(full, { recursive: true });
|
|
11004
11344
|
created.push(`${dir}/`);
|
|
@@ -11028,9 +11368,9 @@ function buildInitWorkspaceConfig(projectName, harness) {
|
|
|
11028
11368
|
};
|
|
11029
11369
|
}
|
|
11030
11370
|
async function initGitScaffold(resolved, created) {
|
|
11031
|
-
const { execSync:
|
|
11371
|
+
const { execSync: execSync2 } = await import('child_process');
|
|
11032
11372
|
const { existsSync: existsSync18, readFileSync: readFileSync10, writeFileSync: writeFileSync7 } = await import('fs');
|
|
11033
|
-
const gitignorePath =
|
|
11373
|
+
const gitignorePath = path23__default.join(resolved, ".gitignore");
|
|
11034
11374
|
const entries = [
|
|
11035
11375
|
"node_modules/",
|
|
11036
11376
|
".skaile/sessions/",
|
|
@@ -11056,9 +11396,9 @@ async function initGitScaffold(resolved, created) {
|
|
|
11056
11396
|
`);
|
|
11057
11397
|
if (!existing) created.push(".gitignore");
|
|
11058
11398
|
}
|
|
11059
|
-
if (!existsSync18(
|
|
11399
|
+
if (!existsSync18(path23__default.join(resolved, ".git"))) {
|
|
11060
11400
|
try {
|
|
11061
|
-
|
|
11401
|
+
execSync2("git init", { cwd: resolved, stdio: "pipe" });
|
|
11062
11402
|
created.push(".git/");
|
|
11063
11403
|
} catch (err2) {
|
|
11064
11404
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
@@ -11086,7 +11426,7 @@ async function bootstrapUserConfig() {
|
|
|
11086
11426
|
}
|
|
11087
11427
|
async function hydrateInitSources(resolved, created) {
|
|
11088
11428
|
try {
|
|
11089
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
11429
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-277VI7R3.js');
|
|
11090
11430
|
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
11091
11431
|
for (const n of hydrate.cloned) created.push(`~/.skaile/cache/sources/${n}/`);
|
|
11092
11432
|
if (hydrate.failed.length > 0) {
|
|
@@ -11102,7 +11442,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11102
11442
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
11103
11443
|
console.log();
|
|
11104
11444
|
console.log(S.heading(" Next steps:"));
|
|
11105
|
-
const isCurrentDir = resolved ===
|
|
11445
|
+
const isCurrentDir = resolved === path23__default.resolve(".");
|
|
11106
11446
|
let step = 1;
|
|
11107
11447
|
if (!isCurrentDir) {
|
|
11108
11448
|
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
@@ -11126,7 +11466,7 @@ function printInitSummary(resolved, projectDir, created) {
|
|
|
11126
11466
|
console.log();
|
|
11127
11467
|
}
|
|
11128
11468
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
11129
|
-
const { cmdSetup } = await import('../setup-
|
|
11469
|
+
const { cmdSetup } = await import('../setup-RAMLTORM.js');
|
|
11130
11470
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
11131
11471
|
});
|
|
11132
11472
|
program.addCommand(makeInstallCommand());
|
|
@@ -11200,6 +11540,10 @@ program.command("path").description("Show resolved paths (honours SKAILE_HOME an
|
|
|
11200
11540
|
console.log();
|
|
11201
11541
|
});
|
|
11202
11542
|
program.addCommand(makeCompleteCommand(program));
|
|
11543
|
+
process.stdout.on("error", (err2) => {
|
|
11544
|
+
if (err2.code === "EPIPE") process.exit(0);
|
|
11545
|
+
throw err2;
|
|
11546
|
+
});
|
|
11203
11547
|
try {
|
|
11204
11548
|
await program.parseAsync();
|
|
11205
11549
|
} catch (err2) {
|