@skaile/workspaces 0.21.0 → 0.22.0-beta.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 +40 -0
- package/dist/{asset-feeds-CI76R7FI.js → asset-feeds-PJDJ3QYI.js} +11 -11
- package/dist/{asset-feeds-CI76R7FI.js.map → asset-feeds-PJDJ3QYI.js.map} +1 -1
- package/dist/asset-manager/index.js +9 -9
- package/dist/asset-manager/installer.js +8 -8
- package/dist/base-assets/connectors/deploy.js +10 -9
- package/dist/base-assets/connectors/devserver.js +10 -9
- package/dist/base-assets/connectors/flow/adapter.js +10 -9
- package/dist/base-assets/connectors/flow/run-flow.js +11 -10
- package/dist/base-assets/connectors/flow.js +10 -9
- package/dist/base-assets/connectors/git.js +10 -9
- package/dist/base-assets/connectors/gmail.js +10 -9
- package/dist/base-assets/connectors/googledrive.js +10 -9
- package/dist/base-assets/connectors/local.js +10 -9
- package/dist/base-assets/connectors/mattermost.js +10 -9
- package/dist/base-assets/connectors/memory.js +10 -9
- package/dist/base-assets/connectors/minio.js +10 -9
- package/dist/base-assets/connectors/postgres.js +10 -9
- package/dist/base-assets/connectors/s3.js +10 -9
- package/dist/base-assets/connectors/sharepoint.js +10 -9
- package/dist/base-assets/connectors/sqlite.js +10 -9
- package/dist/base-assets/connectors/static-server.js +10 -9
- package/dist/base-assets/connectors/tunnel.js +10 -9
- package/dist/base-assets/connectors/webdav.js +10 -9
- package/dist/base-assets/connectors/xstate-store.js +10 -9
- package/dist/base-assets/connectors/xstate.js +10 -9
- package/dist/bridge/drivers/claude-sdk.js +13 -3
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +13 -3
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/echo.js +13 -4
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/omp.js +13 -3
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/index.js +3 -2
- package/dist/bridge/src/drivers/claude-sdk.d.ts +7 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts +7 -0
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/echo.d.ts +6 -0
- package/dist/bridge/src/drivers/echo.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts +6 -0
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/registry.d.ts +32 -34
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/{chunk-DEQ3OOTU.js → chunk-2DNSSQ22.js} +7 -7
- package/dist/{chunk-DEQ3OOTU.js.map → chunk-2DNSSQ22.js.map} +1 -1
- package/dist/{chunk-ZWIG55ZX.js → chunk-2XY6732A.js} +3 -3
- package/dist/{chunk-ZWIG55ZX.js.map → chunk-2XY6732A.js.map} +1 -1
- package/dist/{chunk-2WVQMRIE.js → chunk-CSDQBWE6.js} +5 -5
- package/dist/{chunk-2WVQMRIE.js.map → chunk-CSDQBWE6.js.map} +1 -1
- package/dist/{chunk-KFDTS7RX.js → chunk-F3MGZ5E6.js} +3 -3
- package/dist/{chunk-KFDTS7RX.js.map → chunk-F3MGZ5E6.js.map} +1 -1
- package/dist/{chunk-XAVM2BAJ.js → chunk-G6GKWGOW.js} +114 -619
- package/dist/chunk-G6GKWGOW.js.map +1 -0
- package/dist/{chunk-H45ANMIU.js → chunk-GKM6MDUC.js} +3 -3
- package/dist/{chunk-H45ANMIU.js.map → chunk-GKM6MDUC.js.map} +1 -1
- package/dist/{chunk-4ACWI5YT.js → chunk-IGQEXBBG.js} +44 -36
- package/dist/chunk-IGQEXBBG.js.map +1 -0
- package/dist/{chunk-RDH4SSMH.js → chunk-J2FCO6TM.js} +2 -2
- package/dist/{chunk-RDH4SSMH.js.map → chunk-J2FCO6TM.js.map} +1 -1
- package/dist/{chunk-BSY56QS7.js → chunk-KA46DUM4.js} +3 -3
- package/dist/{chunk-BSY56QS7.js.map → chunk-KA46DUM4.js.map} +1 -1
- package/dist/{chunk-XGWGLIHZ.js → chunk-MO4JPTRD.js} +4 -4
- package/dist/{chunk-XGWGLIHZ.js.map → chunk-MO4JPTRD.js.map} +1 -1
- package/dist/{chunk-G4BR355S.js → chunk-NGC7ZQI4.js} +10 -10
- package/dist/{chunk-G4BR355S.js.map → chunk-NGC7ZQI4.js.map} +1 -1
- package/dist/{chunk-W5DFC35Z.js → chunk-RENHNO4J.js} +81 -4
- package/dist/chunk-RENHNO4J.js.map +1 -0
- package/dist/{chunk-4S4TZDCD.js → chunk-SL6JVGRD.js} +3 -3
- package/dist/{chunk-4S4TZDCD.js.map → chunk-SL6JVGRD.js.map} +1 -1
- package/dist/{chunk-5QNQLSBW.js → chunk-TKOLD2O7.js} +22 -5
- package/dist/chunk-TKOLD2O7.js.map +1 -0
- package/dist/{chunk-DFUXWNTS.js → chunk-TTY56FQQ.js} +4 -4
- package/dist/{chunk-DFUXWNTS.js.map → chunk-TTY56FQQ.js.map} +1 -1
- package/dist/chunk-UZRY5UI2.js +96 -0
- package/dist/chunk-UZRY5UI2.js.map +1 -0
- package/dist/{chunk-NCUTHLRV.js → chunk-UZVHJ7LX.js} +4 -4
- package/dist/{chunk-NCUTHLRV.js.map → chunk-UZVHJ7LX.js.map} +1 -1
- package/dist/{chunk-FRPKLIEZ.js → chunk-WIR34WMU.js} +3 -3
- package/dist/{chunk-FRPKLIEZ.js.map → chunk-WIR34WMU.js.map} +1 -1
- package/dist/{chunk-37JKX6D7.js → chunk-X5Y4EGZB.js} +2 -2
- package/dist/{chunk-37JKX6D7.js.map → chunk-X5Y4EGZB.js.map} +1 -1
- package/dist/{chunk-S2OVTCAL.js → chunk-XHFMUGDD.js} +3 -3
- package/dist/{chunk-S2OVTCAL.js.map → chunk-XHFMUGDD.js.map} +1 -1
- package/dist/cli/index.js +701 -413
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/deploy.d.ts +24 -0
- package/dist/cli/src/commands/deploy.d.ts.map +1 -0
- package/dist/cli/src/commands/integration.d.ts +19 -0
- package/dist/cli/src/commands/integration.d.ts.map +1 -0
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts +22 -0
- package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -0
- package/dist/cli/src/commands/serve.d.ts.map +1 -1
- package/dist/cli/src/plugin-store/index.d.ts +37 -0
- package/dist/cli/src/plugin-store/index.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/load.d.ts +35 -0
- package/dist/cli/src/plugin-store/load.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/paths.d.ts +23 -0
- package/dist/cli/src/plugin-store/paths.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/reconcile.d.ts +50 -0
- package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -0
- package/dist/cli/src/plugin-store/spec.d.ts +25 -0
- package/dist/cli/src/plugin-store/spec.d.ts.map +1 -0
- package/dist/connectors/config.js +8 -8
- package/dist/connectors/index.js +10 -9
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-registry.d.ts +42 -22
- package/dist/connectors/src/connector-registry.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +2 -3
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors-shared/index.js +8 -0
- package/dist/connectors-shared/index.js.map +1 -0
- package/dist/connectors-shared/src/index.d.ts +11 -0
- package/dist/connectors-shared/src/index.d.ts.map +1 -0
- package/dist/connectors-shared/src/schemas.d.ts +10 -0
- package/dist/connectors-shared/src/schemas.d.ts.map +1 -0
- package/dist/connectors-shared/src/types.d.ts +11 -0
- package/dist/connectors-shared/src/types.d.ts.map +1 -0
- package/dist/core/index.js +7 -7
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/runtime-assets.js +4 -4
- package/dist/core/src/index.d.ts +2 -2
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +20 -1
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +13 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +14 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +20 -0
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +3 -3
- package/dist/deploy/index.js +454 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/deploy/src/handle-store.d.ts +22 -0
- package/dist/deploy/src/handle-store.d.ts.map +1 -0
- package/dist/deploy/src/index.d.ts +21 -0
- package/dist/deploy/src/index.d.ts.map +1 -0
- package/dist/deploy/src/targets/container-runtime.d.ts +38 -0
- package/dist/deploy/src/targets/container-runtime.d.ts.map +1 -0
- package/dist/deploy/src/targets/docker.d.ts +18 -0
- package/dist/deploy/src/targets/docker.d.ts.map +1 -0
- package/dist/deploy/src/targets/local.d.ts +30 -0
- package/dist/deploy/src/targets/local.d.ts.map +1 -0
- package/dist/deploy/src/targets/podman.d.ts +18 -0
- package/dist/deploy/src/targets/podman.d.ts.map +1 -0
- package/dist/deploy/src/targets/port.d.ts +10 -0
- package/dist/deploy/src/targets/port.d.ts.map +1 -0
- package/dist/deploy/src/targets/stream-lines.d.ts +44 -0
- package/dist/deploy/src/targets/stream-lines.d.ts.map +1 -0
- package/dist/discovery/index.js +3 -3
- package/dist/{ensure-sources-IDVQ77NJ.js → ensure-sources-COGVKY44.js} +11 -11
- package/dist/{ensure-sources-IDVQ77NJ.js.map → ensure-sources-COGVKY44.js.map} +1 -1
- package/dist/{flows-6BNO4GKK.js → flows-DYFTPCPM.js} +4 -4
- package/dist/{flows-6BNO4GKK.js.map → flows-DYFTPCPM.js.map} +1 -1
- package/dist/library/index.js +4 -4
- package/dist/open-library-DWAQFUSQ.js +13 -0
- package/dist/{open-library-IOYWFK7M.js.map → open-library-DWAQFUSQ.js.map} +1 -1
- package/dist/plugin-registry/index.js +4 -0
- package/dist/plugin-registry/index.js.map +1 -0
- package/dist/plugin-registry/src/context.d.ts +29 -0
- package/dist/plugin-registry/src/context.d.ts.map +1 -0
- package/dist/plugin-registry/src/deploy-handle.d.ts +60 -0
- package/dist/plugin-registry/src/deploy-handle.d.ts.map +1 -0
- package/dist/plugin-registry/src/errors.d.ts +23 -0
- package/dist/plugin-registry/src/errors.d.ts.map +1 -0
- package/dist/plugin-registry/src/index.d.ts +16 -0
- package/dist/plugin-registry/src/index.d.ts.map +1 -0
- package/dist/plugin-registry/src/internal.d.ts +13 -0
- package/dist/plugin-registry/src/internal.d.ts.map +1 -0
- package/dist/plugin-registry/src/registry.d.ts +25 -0
- package/dist/plugin-registry/src/registry.d.ts.map +1 -0
- package/dist/plugin-registry/src/targets.d.ts +42 -0
- package/dist/plugin-registry/src/targets.d.ts.map +1 -0
- package/dist/plugin-store-6OENKNFW.js +144 -0
- package/dist/plugin-store-6OENKNFW.js.map +1 -0
- package/dist/runner/index.js +14 -13
- package/dist/sdk/asset-manager.js +9 -9
- package/dist/sdk/bridge.js +3 -2
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/index.js +15 -14
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runner.js +14 -13
- package/dist/{setup-AIOLUTKV.js → setup-ACMP3QZC.js} +12 -11
- package/dist/setup-ACMP3QZC.js.map +1 -0
- package/dist/store-client-ZSLNOOQG.js +14 -0
- package/dist/{store-client-CYEH2GKC.js.map → store-client-ZSLNOOQG.js.map} +1 -1
- package/dist/tui/index.js +14 -13
- package/dist/tui/index.js.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +2 -2
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +20 -23
- package/dist/base-assets/connectors/redis/adapter.d.ts +0 -39
- package/dist/base-assets/connectors/redis/adapter.d.ts.map +0 -1
- package/dist/base-assets/connectors/redis.js +0 -20
- package/dist/base-assets/connectors/redis.js.map +0 -1
- package/dist/base-assets/connectors/yjs/adapter.d.ts +0 -50
- package/dist/base-assets/connectors/yjs/adapter.d.ts.map +0 -1
- package/dist/base-assets/connectors/yjs.js +0 -20
- package/dist/base-assets/connectors/yjs.js.map +0 -1
- package/dist/chunk-4ACWI5YT.js.map +0 -1
- package/dist/chunk-5QNQLSBW.js.map +0 -1
- package/dist/chunk-W5DFC35Z.js.map +0 -1
- package/dist/chunk-XAVM2BAJ.js.map +0 -1
- package/dist/cli/src/commands/plugin.d.ts +0 -14
- package/dist/cli/src/commands/plugin.d.ts.map +0 -1
- package/dist/open-library-IOYWFK7M.js +0 -13
- package/dist/setup-AIOLUTKV.js.map +0 -1
- package/dist/store-client-CYEH2GKC.js +0 -14
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-NCUTHLRV.js';
|
|
3
|
-
import { logErr, S, logOk, colorRef, logInfo, logWarn, kindColorPad, kindColor, formatRelativeTime } from '../chunk-4NDWKA64.js';
|
|
4
|
-
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-KFDTS7RX.js';
|
|
5
2
|
import { AI_RESOURCES } from '../chunk-2M3XTMOL.js';
|
|
3
|
+
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-UZVHJ7LX.js';
|
|
4
|
+
import { logErr, S, logOk, colorRef, logInfo, logWarn, kindColorPad, kindColor, formatRelativeTime } from '../chunk-4NDWKA64.js';
|
|
5
|
+
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-F3MGZ5E6.js';
|
|
6
6
|
import { LocalSecretsProvider } from '../chunk-JDX54X4Y.js';
|
|
7
|
-
import { resolveLibraryDir, LocalCatalogSource, skaileHomeDir } from '../chunk-
|
|
7
|
+
import { resolveLibraryDir, LocalCatalogSource, skaileHomeDir } from '../chunk-KA46DUM4.js';
|
|
8
8
|
import '../chunk-R7FOF242.js';
|
|
9
|
-
import '../chunk-
|
|
9
|
+
import '../chunk-SL6JVGRD.js';
|
|
10
10
|
import '../chunk-OKRUTSG7.js';
|
|
11
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
11
|
+
import { runFlow, resumeFlow } from '../chunk-CSDQBWE6.js';
|
|
12
12
|
import '../chunk-GCJXPUHG.js';
|
|
13
13
|
import { validateFlowVersions, parseSkillFrontmatter } from '../chunk-IPUYL6TD.js';
|
|
14
|
-
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-
|
|
15
|
-
import { buildClaudePluginFiles } from '../chunk-
|
|
14
|
+
import { runAgentChat, loadSessionById, loadSession, listSessions, setCurrentSession, deleteSession, clearSession, loadAgentManifest, compileComposition, MarkdownStreamer, resolveMixin } from '../chunk-NGC7ZQI4.js';
|
|
15
|
+
import { buildClaudePluginFiles } from '../chunk-J2FCO6TM.js';
|
|
16
16
|
import '../chunk-X5YPJV4N.js';
|
|
17
17
|
import '../chunk-O7SG5PC2.js';
|
|
18
18
|
import '../chunk-W2O5LWYU.js';
|
|
@@ -20,29 +20,30 @@ import '../chunk-7PTP3SQJ.js';
|
|
|
20
20
|
import '../chunk-PBWMV5GM.js';
|
|
21
21
|
import '../chunk-W3UDISS2.js';
|
|
22
22
|
import '../chunk-TDSRLMDB.js';
|
|
23
|
-
import '../chunk-
|
|
23
|
+
import '../chunk-XHFMUGDD.js';
|
|
24
24
|
import '../chunk-DQWREFRQ.js';
|
|
25
25
|
import '../chunk-KOVLSBXK.js';
|
|
26
26
|
import '../chunk-RRVQAE5D.js';
|
|
27
|
-
import '../chunk-
|
|
28
|
-
import '../chunk-
|
|
29
|
-
import '../chunk-
|
|
27
|
+
import '../chunk-IGQEXBBG.js';
|
|
28
|
+
import '../chunk-G6GKWGOW.js';
|
|
29
|
+
import '../chunk-GKM6MDUC.js';
|
|
30
30
|
import '../chunk-6MB7CRME.js';
|
|
31
31
|
import '../chunk-QAVZOJCV.js';
|
|
32
|
+
import '../chunk-UZRY5UI2.js';
|
|
32
33
|
import { loadAllFlows } from '../chunk-ICS76R4T.js';
|
|
33
34
|
import '../chunk-GZWJGNNN.js';
|
|
34
35
|
import '../chunk-FVTV7M76.js';
|
|
35
|
-
import { AssetManager } from '../chunk-
|
|
36
|
-
import '../chunk-
|
|
37
|
-
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-
|
|
38
|
-
import '../chunk-JKNWJ64A.js';
|
|
39
|
-
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
36
|
+
import { AssetManager } from '../chunk-2DNSSQ22.js';
|
|
37
|
+
import '../chunk-MO4JPTRD.js';
|
|
38
|
+
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-RENHNO4J.js';
|
|
40
39
|
import { DRIVER_DEFAULTS } from '../chunk-K5GBV4SA.js';
|
|
41
40
|
import '../chunk-KLNL7QHN.js';
|
|
42
|
-
import '../chunk-
|
|
43
|
-
import { resolveSkWorkspaceConfig, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename } from '../chunk-
|
|
44
|
-
import '../chunk-
|
|
45
|
-
import { ASSET_KINDS } from '../chunk-
|
|
41
|
+
import '../chunk-TTY56FQQ.js';
|
|
42
|
+
import { resolveSkWorkspaceConfig, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename } from '../chunk-TKOLD2O7.js';
|
|
43
|
+
import '../chunk-WIR34WMU.js';
|
|
44
|
+
import { ASSET_KINDS } from '../chunk-X5Y4EGZB.js';
|
|
45
|
+
import '../chunk-JKNWJ64A.js';
|
|
46
|
+
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
46
47
|
import { openSqlite } from '../chunk-24UIWON4.js';
|
|
47
48
|
import '../chunk-KTBKW2FI.js';
|
|
48
49
|
import '../chunk-UQ6LFBPZ.js';
|
|
@@ -53,8 +54,8 @@ import '../chunk-LV2HPH3C.js';
|
|
|
53
54
|
import '../chunk-NSBPE2FW.js';
|
|
54
55
|
import * as fs10 from 'fs';
|
|
55
56
|
import fs10__default, { readFileSync, existsSync, writeFileSync, rmSync, statSync } from 'fs';
|
|
56
|
-
import * as
|
|
57
|
-
import
|
|
57
|
+
import * as path14 from 'path';
|
|
58
|
+
import path14__default, { resolve, join } from 'path';
|
|
58
59
|
import { fileURLToPath } from 'url';
|
|
59
60
|
import { Help, Command, Option } from 'commander';
|
|
60
61
|
import * as p5 from '@clack/prompts';
|
|
@@ -103,10 +104,10 @@ function makeAssetCommand() {
|
|
|
103
104
|
);
|
|
104
105
|
process.exit(1);
|
|
105
106
|
}
|
|
106
|
-
const basename2 =
|
|
107
|
-
const destDir = target.structure === "domain" && opts.domain ?
|
|
107
|
+
const basename2 = path14.basename(srcPath);
|
|
108
|
+
const destDir = target.structure === "domain" && opts.domain ? path14.join(target.path, opts.domain) : target.path;
|
|
108
109
|
fs10.mkdirSync(destDir, { recursive: true });
|
|
109
|
-
const destPath =
|
|
110
|
+
const destPath = path14.join(destDir, basename2);
|
|
110
111
|
if (fs10.existsSync(destPath)) {
|
|
111
112
|
logErr(`Destination already exists: ${destPath}`);
|
|
112
113
|
process.exit(1);
|
|
@@ -119,7 +120,7 @@ function makeAssetCommand() {
|
|
|
119
120
|
fs10.renameSync(srcPath, destPath);
|
|
120
121
|
break;
|
|
121
122
|
case "link":
|
|
122
|
-
fs10.symlinkSync(
|
|
123
|
+
fs10.symlinkSync(path14.resolve(srcPath), destPath);
|
|
123
124
|
break;
|
|
124
125
|
}
|
|
125
126
|
if (target.backend === "git" && opts.commit) {
|
|
@@ -167,17 +168,17 @@ function makeAssetCommand() {
|
|
|
167
168
|
}
|
|
168
169
|
const manifestPath = def.manifest.path;
|
|
169
170
|
const candidateSubpath = typeof manifestPath === "string" && manifestPath.length > 0 ? manifestPath : def.name;
|
|
170
|
-
const srcPath =
|
|
171
|
+
const srcPath = path14.join(lib.path, candidateSubpath);
|
|
171
172
|
if (!fs10.existsSync(srcPath)) {
|
|
172
173
|
logErr(`Asset path not found: ${srcPath}`);
|
|
173
174
|
process.exit(1);
|
|
174
175
|
}
|
|
175
|
-
const destPath =
|
|
176
|
-
fs10.mkdirSync(
|
|
176
|
+
const destPath = path14.join(target, candidateSubpath);
|
|
177
|
+
fs10.mkdirSync(path14.dirname(destPath), { recursive: true });
|
|
177
178
|
if (opts.mode === "copy") {
|
|
178
179
|
fs10.cpSync(srcPath, destPath, { recursive: true });
|
|
179
180
|
} else {
|
|
180
|
-
fs10.symlinkSync(
|
|
181
|
+
fs10.symlinkSync(path14.resolve(srcPath), destPath);
|
|
181
182
|
}
|
|
182
183
|
logOk(`Installed ${ref} \u2192 ${destPath} (${opts.mode})`);
|
|
183
184
|
} finally {
|
|
@@ -271,7 +272,7 @@ function makeSearchCommand() {
|
|
|
271
272
|
const showLocal = !opts.store;
|
|
272
273
|
const showStore = !opts.local;
|
|
273
274
|
if (showLocal) {
|
|
274
|
-
const am2 = new AssetManager({ projectDir:
|
|
275
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
275
276
|
const entries = am2.search(query, kind);
|
|
276
277
|
if (entries.length === 0) {
|
|
277
278
|
if (!showStore) {
|
|
@@ -308,7 +309,7 @@ function makeSearchCommand() {
|
|
|
308
309
|
}
|
|
309
310
|
if (showStore) {
|
|
310
311
|
try {
|
|
311
|
-
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-
|
|
312
|
+
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-ZSLNOOQG.js');
|
|
312
313
|
const config = getStoreConfig2();
|
|
313
314
|
const params = {};
|
|
314
315
|
if (query) params.q = query;
|
|
@@ -337,7 +338,7 @@ function makeSearchCommand() {
|
|
|
337
338
|
function makeAddCommand() {
|
|
338
339
|
return new Command("add").description("Add to skaile.yaml + deploy").argument("<ref>", "Asset reference (kind:name[@repo])").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Deploy to global dir (~/.claude)").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
|
|
339
340
|
const am2 = new AssetManager({
|
|
340
|
-
projectDir:
|
|
341
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
341
342
|
global: opts.global,
|
|
342
343
|
driverTarget: opts.target
|
|
343
344
|
});
|
|
@@ -358,7 +359,7 @@ function makeAddCommand() {
|
|
|
358
359
|
function makeRemoveCommand() {
|
|
359
360
|
return new Command("remove").description("Remove from skaile.yaml + undeploy").argument("<ref>", "Asset reference (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).option("--global", "Remove from global dir").option("--target <agent>", "Driver target", "claude-code").action((ref, opts) => {
|
|
360
361
|
const am2 = new AssetManager({
|
|
361
|
-
projectDir:
|
|
362
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
362
363
|
global: opts.global,
|
|
363
364
|
driverTarget: opts.target
|
|
364
365
|
});
|
|
@@ -372,7 +373,7 @@ function makeListCommand() {
|
|
|
372
373
|
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
373
374
|
).action((kind, opts) => {
|
|
374
375
|
const am2 = new AssetManager({
|
|
375
|
-
projectDir:
|
|
376
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
376
377
|
global: opts.global,
|
|
377
378
|
driverTarget: opts.target
|
|
378
379
|
});
|
|
@@ -396,7 +397,7 @@ function makeListCommand() {
|
|
|
396
397
|
}
|
|
397
398
|
function makeInfoCommand() {
|
|
398
399
|
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((ref, opts) => {
|
|
399
|
-
const am2 = new AssetManager({ projectDir:
|
|
400
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
400
401
|
const entry = am2.info(ref);
|
|
401
402
|
if (!entry) {
|
|
402
403
|
logErr(
|
|
@@ -429,7 +430,7 @@ function makeCreateCommand() {
|
|
|
429
430
|
new Option("-k, --kind <kind>", "Asset kind").default("skill").choices([...ASSET_KINDS])
|
|
430
431
|
).option("-d, --dir <dir>", "Target directory (default: cwd)").action((name, opts) => {
|
|
431
432
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
432
|
-
const destDir = opts.dir ?
|
|
433
|
+
const destDir = opts.dir ? path14__default.resolve(opts.dir) : process.cwd();
|
|
433
434
|
const result = am2.create(name, opts.kind, destDir);
|
|
434
435
|
if (result.ok) logOk(`Created ${kindColor(opts.kind)}: ${pc5.dim(result.path)}`);
|
|
435
436
|
else {
|
|
@@ -440,7 +441,7 @@ function makeCreateCommand() {
|
|
|
440
441
|
}
|
|
441
442
|
function makeDoctorCommand() {
|
|
442
443
|
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((name, opts) => {
|
|
443
|
-
const am2 = new AssetManager({ projectDir:
|
|
444
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
444
445
|
const issues = am2.doctor();
|
|
445
446
|
if (issues.length === 0) {
|
|
446
447
|
logOk("No missing dependencies.");
|
|
@@ -466,11 +467,11 @@ function makeCatalogCommand() {
|
|
|
466
467
|
const catalog = new Command("catalog").description("Catalog source health and configuration");
|
|
467
468
|
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) => {
|
|
468
469
|
const { resolveConfig, isLocalCatalogUrl, trpcGetUrl } = await import('../library/index.js');
|
|
469
|
-
const projectDir = opts.projectDir ?
|
|
470
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
|
|
470
471
|
const cfg = resolveConfig({ projectDir });
|
|
471
472
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
472
473
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
473
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
474
|
+
const { resolveCatalogSource } = await import('../open-library-DWAQFUSQ.js');
|
|
474
475
|
let resolved;
|
|
475
476
|
try {
|
|
476
477
|
resolved = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
@@ -559,7 +560,7 @@ function makeCatalogCommand() {
|
|
|
559
560
|
});
|
|
560
561
|
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) => {
|
|
561
562
|
const { resolveConfig } = await import('../library/index.js');
|
|
562
|
-
const projectDir = opts.projectDir ?
|
|
563
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : void 0;
|
|
563
564
|
const cfg = resolveConfig({ projectDir });
|
|
564
565
|
console.log(`url: ${cfg.catalog.url}`);
|
|
565
566
|
console.log(`framing: ${cfg.catalog.framing}`);
|
|
@@ -616,7 +617,7 @@ function findSkills(domain) {
|
|
|
616
617
|
if (!fs10__default.existsSync(AI_RESOURCES)) return skills;
|
|
617
618
|
const domains = fs10__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory()).filter((d) => true);
|
|
618
619
|
for (const d of domains) {
|
|
619
|
-
const skillsDir =
|
|
620
|
+
const skillsDir = path14__default.join(AI_RESOURCES, d.name, "skills");
|
|
620
621
|
if (!fs10__default.existsSync(skillsDir)) continue;
|
|
621
622
|
walkSkills(skillsDir, d.name, skills);
|
|
622
623
|
}
|
|
@@ -624,9 +625,9 @@ function findSkills(domain) {
|
|
|
624
625
|
}
|
|
625
626
|
function walkSkills(dir, domain, out) {
|
|
626
627
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
627
|
-
const full =
|
|
628
|
+
const full = path14__default.join(dir, entry.name);
|
|
628
629
|
if (entry.isDirectory()) {
|
|
629
|
-
const skillMd =
|
|
630
|
+
const skillMd = path14__default.join(full, "SKILL.md");
|
|
630
631
|
if (fs10__default.existsSync(skillMd)) {
|
|
631
632
|
out.push({ name: entry.name, path: full, skillPath: skillMd, domain });
|
|
632
633
|
} else {
|
|
@@ -652,7 +653,7 @@ function resolveFlowIds() {
|
|
|
652
653
|
}
|
|
653
654
|
}
|
|
654
655
|
function resolveSessionIds(projectDir) {
|
|
655
|
-
const sessionsDir =
|
|
656
|
+
const sessionsDir = path14__default.join(projectDir, ".skaile", "sessions");
|
|
656
657
|
if (!fs10__default.existsSync(sessionsDir)) return [];
|
|
657
658
|
try {
|
|
658
659
|
return fs10__default.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
@@ -713,7 +714,7 @@ var API_KEY_PREFIX = "apiKey.";
|
|
|
713
714
|
function makeConfigCommand() {
|
|
714
715
|
const cmd = new Command("config").description("Manage personal config (.skaile/settings.json)");
|
|
715
716
|
cmd.command("show").description("Show effective config with sources").option("--project-dir <path>", "Project directory").action(async (opts) => {
|
|
716
|
-
const projectDir = opts.projectDir ?
|
|
717
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
717
718
|
const config = await resolveSettings(projectDir);
|
|
718
719
|
const wsDefaults = {};
|
|
719
720
|
try {
|
|
@@ -770,13 +771,13 @@ function makeConfigCommand() {
|
|
|
770
771
|
console.log();
|
|
771
772
|
});
|
|
772
773
|
cmd.command("get <key>").description("Get an effective config value").option("--project-dir <path>", "Project directory").action(async (key, opts) => {
|
|
773
|
-
const projectDir = opts.projectDir ?
|
|
774
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
774
775
|
const config = await resolveSettings(projectDir);
|
|
775
776
|
const value = config[key];
|
|
776
777
|
console.log(value ?? S.dim("(not set)"));
|
|
777
778
|
});
|
|
778
779
|
cmd.command("set <key> <value>").description("Set a personal config value (driver, model, provider, apiKey.<provider>)").option("--project-dir <path>", "Project directory").option("--global", "Write to ~/.skaile/settings.json instead of project-local").action(async (key, value, opts) => {
|
|
779
|
-
const projectDir = opts.projectDir ?
|
|
780
|
+
const projectDir = opts.projectDir ? path14__default.resolve(opts.projectDir) : process.cwd();
|
|
780
781
|
const isApiKey = key.startsWith(API_KEY_PREFIX);
|
|
781
782
|
if (!PERSONAL_KEYS.has(key) && !isApiKey) {
|
|
782
783
|
logErr(
|
|
@@ -1083,8 +1084,8 @@ function makeConnectorCommand() {
|
|
|
1083
1084
|
async (driver, opts) => {
|
|
1084
1085
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
1085
1086
|
const { scanDirectory, resolveBaseAssetsRoot, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1086
|
-
const projectDir =
|
|
1087
|
-
const yamlPath =
|
|
1087
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1088
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
1088
1089
|
if (!existsSync(yamlPath)) {
|
|
1089
1090
|
logErr("No skaile.yaml found in current directory. Run 'skaile init' first.");
|
|
1090
1091
|
process.exit(1);
|
|
@@ -1147,8 +1148,8 @@ ${installResult.output}`);
|
|
|
1147
1148
|
);
|
|
1148
1149
|
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) => {
|
|
1149
1150
|
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1150
|
-
const projectDir =
|
|
1151
|
-
const yamlPath =
|
|
1151
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1152
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
1152
1153
|
if (!existsSync(yamlPath)) {
|
|
1153
1154
|
logErr("No skaile.yaml found in current directory.");
|
|
1154
1155
|
process.exit(1);
|
|
@@ -1165,7 +1166,7 @@ ${installResult.output}`);
|
|
|
1165
1166
|
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) => {
|
|
1166
1167
|
const res = await import('../connectors/index.js');
|
|
1167
1168
|
res.registerBuiltinConnectors();
|
|
1168
|
-
const projectDir =
|
|
1169
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1169
1170
|
const declarations = res.loadConnectorDeclarations(projectDir);
|
|
1170
1171
|
if (declarations.length === 0) {
|
|
1171
1172
|
console.log("No connectors configured in skaile.yaml.");
|
|
@@ -1189,7 +1190,7 @@ ${installResult.output}`);
|
|
|
1189
1190
|
await manager.disconnectAll();
|
|
1190
1191
|
});
|
|
1191
1192
|
cmd.command("list").description("List all configured connectors").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
|
|
1192
|
-
const projectDir =
|
|
1193
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1193
1194
|
const manager = await connectConnectors(projectDir);
|
|
1194
1195
|
try {
|
|
1195
1196
|
console.log(JSON.stringify(manager.listConnectors(), null, 2));
|
|
@@ -1198,7 +1199,7 @@ ${installResult.output}`);
|
|
|
1198
1199
|
}
|
|
1199
1200
|
});
|
|
1200
1201
|
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) => {
|
|
1201
|
-
const projectDir =
|
|
1202
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1202
1203
|
const manager = await connectConnectors(projectDir);
|
|
1203
1204
|
try {
|
|
1204
1205
|
if (opts.all) {
|
|
@@ -1222,7 +1223,7 @@ ${installResult.output}`);
|
|
|
1222
1223
|
}
|
|
1223
1224
|
});
|
|
1224
1225
|
cmd.command("ops <id>").description("List available operations for a connector").option("--project-dir <path>", "Workspace directory", process.cwd()).action(async (id, opts) => {
|
|
1225
|
-
const projectDir =
|
|
1226
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1226
1227
|
const manager = await connectConnectors(projectDir);
|
|
1227
1228
|
try {
|
|
1228
1229
|
if (!manager.has(id)) {
|
|
@@ -1237,7 +1238,7 @@ ${installResult.output}`);
|
|
|
1237
1238
|
}
|
|
1238
1239
|
});
|
|
1239
1240
|
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) => {
|
|
1240
|
-
const projectDir =
|
|
1241
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1241
1242
|
const manager = await connectConnectors(projectDir);
|
|
1242
1243
|
try {
|
|
1243
1244
|
const content = await manager.read(id, resourcePath);
|
|
@@ -1247,7 +1248,7 @@ ${installResult.output}`);
|
|
|
1247
1248
|
}
|
|
1248
1249
|
});
|
|
1249
1250
|
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) => {
|
|
1250
|
-
const projectDir =
|
|
1251
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1251
1252
|
const manager = await connectConnectors(projectDir);
|
|
1252
1253
|
try {
|
|
1253
1254
|
await manager.write(id, resourcePath, { data: content });
|
|
@@ -1257,7 +1258,7 @@ ${installResult.output}`);
|
|
|
1257
1258
|
}
|
|
1258
1259
|
});
|
|
1259
1260
|
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", parseInt).action(async (id, resourcePath, opts) => {
|
|
1260
|
-
const projectDir =
|
|
1261
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1261
1262
|
const manager = await connectConnectors(projectDir);
|
|
1262
1263
|
try {
|
|
1263
1264
|
const entries = await manager.list(id, resourcePath, {
|
|
@@ -1270,7 +1271,7 @@ ${installResult.output}`);
|
|
|
1270
1271
|
}
|
|
1271
1272
|
});
|
|
1272
1273
|
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) => {
|
|
1273
|
-
const projectDir =
|
|
1274
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1274
1275
|
const manager = await connectConnectors(projectDir);
|
|
1275
1276
|
try {
|
|
1276
1277
|
const results = await manager.search(id, query);
|
|
@@ -1280,7 +1281,7 @@ ${installResult.output}`);
|
|
|
1280
1281
|
}
|
|
1281
1282
|
});
|
|
1282
1283
|
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) => {
|
|
1283
|
-
const projectDir =
|
|
1284
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1284
1285
|
const manager = await connectConnectors(projectDir);
|
|
1285
1286
|
try {
|
|
1286
1287
|
const ok = await manager.delete(id, resourcePath);
|
|
@@ -1290,7 +1291,7 @@ ${installResult.output}`);
|
|
|
1290
1291
|
}
|
|
1291
1292
|
});
|
|
1292
1293
|
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) => {
|
|
1293
|
-
const projectDir =
|
|
1294
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1294
1295
|
const manager = await connectConnectors(projectDir);
|
|
1295
1296
|
try {
|
|
1296
1297
|
if (!manager.has(id)) {
|
|
@@ -1379,9 +1380,172 @@ function makeDebugCommand() {
|
|
|
1379
1380
|
});
|
|
1380
1381
|
return cmd;
|
|
1381
1382
|
}
|
|
1383
|
+
function action(fn) {
|
|
1384
|
+
return async (...args) => {
|
|
1385
|
+
try {
|
|
1386
|
+
await fn(...args);
|
|
1387
|
+
} catch (err) {
|
|
1388
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
1389
|
+
process.exitCode = 1;
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
function envRecord() {
|
|
1394
|
+
const out = {};
|
|
1395
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
1396
|
+
if (typeof v === "string") out[k] = v;
|
|
1397
|
+
}
|
|
1398
|
+
return out;
|
|
1399
|
+
}
|
|
1400
|
+
async function buildDeployContext(projectDir) {
|
|
1401
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1402
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1403
|
+
const workspaceId = config.name ?? path14__default.basename(projectDir);
|
|
1404
|
+
let log;
|
|
1405
|
+
try {
|
|
1406
|
+
const { createLogger } = await import('../core/logging.js');
|
|
1407
|
+
log = createLogger({ kind: "gateway", subkind: "deploy" });
|
|
1408
|
+
} catch {
|
|
1409
|
+
const shim = {
|
|
1410
|
+
debug: (m) => console.error(S.dim(` \xB7 ${m}`)),
|
|
1411
|
+
info: (m) => console.error(S.dim(` \xB7 ${m}`)),
|
|
1412
|
+
warn: (m) => logWarn(m),
|
|
1413
|
+
error: (m, e) => logErr(`${m}${e ? `: ${e instanceof Error ? e.message : String(e)}` : ""}`),
|
|
1414
|
+
child: () => shim
|
|
1415
|
+
};
|
|
1416
|
+
log = shim;
|
|
1417
|
+
}
|
|
1418
|
+
const controller = new AbortController();
|
|
1419
|
+
const ctx = {
|
|
1420
|
+
workspaceId,
|
|
1421
|
+
env: envRecord(),
|
|
1422
|
+
log,
|
|
1423
|
+
signal: controller.signal,
|
|
1424
|
+
...process.env.SKAILE_WS_AUTH_TOKEN ? { wsAuth: process.env.SKAILE_WS_AUTH_TOKEN } : {}
|
|
1425
|
+
};
|
|
1426
|
+
return { ctx, controller };
|
|
1427
|
+
}
|
|
1428
|
+
async function ensureTargetsRegistered(projectDir) {
|
|
1429
|
+
const { registerBuiltinDeployTargets } = await import('../deploy/index.js');
|
|
1430
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1431
|
+
registerBuiltinDeployTargets(pluginRegistry);
|
|
1432
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1433
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1434
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
1435
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-6OENKNFW.js');
|
|
1436
|
+
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
1437
|
+
for (const f of result.failed) logWarn(f.error);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
async function runUp(opts) {
|
|
1441
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1442
|
+
await ensureTargetsRegistered(projectDir);
|
|
1443
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
1444
|
+
const { resolveDeployTarget, pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1445
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
1446
|
+
const resolution = await resolveDeployTarget(
|
|
1447
|
+
{ deploy: config.deploy },
|
|
1448
|
+
opts.target ? { target: opts.target, config: config.deploy?.config ?? {}, reason: "cli --target" } : void 0,
|
|
1449
|
+
pluginRegistry
|
|
1450
|
+
);
|
|
1451
|
+
const { ctx, controller } = await buildDeployContext(projectDir);
|
|
1452
|
+
ctx.log.debug(`deploy target resolved`, {
|
|
1453
|
+
target: resolution.target.id,
|
|
1454
|
+
source: resolution.provenance.source,
|
|
1455
|
+
reason: resolution.provenance.reason
|
|
1456
|
+
});
|
|
1457
|
+
logInfo(`Deploying to ${S.cmd(resolution.target.id)} (${S.dim(resolution.provenance.source)})\u2026`);
|
|
1458
|
+
const handle = await resolution.target.create(resolution.config, ctx);
|
|
1459
|
+
await handle.waitReady();
|
|
1460
|
+
logOk(`Ready at ${S.cmd(handle.wsUrl)}`);
|
|
1461
|
+
console.log(` ${S.dim("source")} ${resolution.provenance.source}`);
|
|
1462
|
+
if (opts.detach) {
|
|
1463
|
+
const { writeHandle } = await import('../deploy/index.js');
|
|
1464
|
+
await writeHandle(projectDir, resolution.target.id, handle.payload);
|
|
1465
|
+
logInfo(`Detached \u2014 handle written to ${S.cmd(".skaile/deploy/handle.json")}`);
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
logInfo("Holding deploy in the foreground \u2014 press Ctrl-C to stop.");
|
|
1469
|
+
await holdUntilSignal(handle, controller);
|
|
1470
|
+
}
|
|
1471
|
+
function holdUntilSignal(handle, controller) {
|
|
1472
|
+
return new Promise((resolve4) => {
|
|
1473
|
+
const onSig = () => {
|
|
1474
|
+
process.removeListener("SIGINT", onSig);
|
|
1475
|
+
controller.abort();
|
|
1476
|
+
logInfo("Stopping\u2026");
|
|
1477
|
+
handle.stop().then(() => logOk("Stopped.")).catch((e) => logErr(`stop failed: ${e instanceof Error ? e.message : String(e)}`)).finally(() => resolve4());
|
|
1478
|
+
};
|
|
1479
|
+
process.on("SIGINT", onSig);
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
async function restoreFromHandle(projectDir) {
|
|
1483
|
+
const { readHandle } = await import('../deploy/index.js');
|
|
1484
|
+
const stored = await readHandle(projectDir);
|
|
1485
|
+
if (!stored) {
|
|
1486
|
+
logInfo("No active deploy \u2014 nothing to do (no .skaile/deploy/handle.json).");
|
|
1487
|
+
return null;
|
|
1488
|
+
}
|
|
1489
|
+
await ensureTargetsRegistered(projectDir);
|
|
1490
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
1491
|
+
const target = pluginRegistry.get("deployTarget", stored.targetId);
|
|
1492
|
+
if (!target) {
|
|
1493
|
+
logErr(`unknown deploy target "${stored.targetId}" \u2014 is its plugin installed?`);
|
|
1494
|
+
return null;
|
|
1495
|
+
}
|
|
1496
|
+
const { ctx } = await buildDeployContext(projectDir);
|
|
1497
|
+
const handle = await target.restore(stored.payload, ctx);
|
|
1498
|
+
return { target, handle, ctx };
|
|
1499
|
+
}
|
|
1500
|
+
async function runDown(opts) {
|
|
1501
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1502
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1503
|
+
if (!restored) return;
|
|
1504
|
+
await restored.handle.stop();
|
|
1505
|
+
const { clearHandle } = await import('../deploy/index.js');
|
|
1506
|
+
await clearHandle(projectDir);
|
|
1507
|
+
logOk(`Stopped ${S.cmd(restored.target.id)} and cleared the handle.`);
|
|
1508
|
+
}
|
|
1509
|
+
async function runStatus(opts) {
|
|
1510
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1511
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1512
|
+
if (!restored) return;
|
|
1513
|
+
const health = await restored.handle.health();
|
|
1514
|
+
console.log();
|
|
1515
|
+
console.log(` ${S.label("target")} ${S.cmd(restored.target.id)}`);
|
|
1516
|
+
console.log(` ${S.label("state")} ${restored.handle.state}`);
|
|
1517
|
+
console.log(` ${S.label("wsUrl")} ${S.cmd(restored.handle.wsUrl)}`);
|
|
1518
|
+
console.log(
|
|
1519
|
+
` ${S.label("health")} ${health.healthy ? S.ok("healthy") : S.err("unhealthy")}${health.detail ? ` ${S.dim(`(${health.detail})`)}` : ""}`
|
|
1520
|
+
);
|
|
1521
|
+
console.log();
|
|
1522
|
+
}
|
|
1523
|
+
async function runLogs(opts) {
|
|
1524
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
1525
|
+
const restored = await restoreFromHandle(projectDir);
|
|
1526
|
+
if (!restored) return;
|
|
1527
|
+
if (!restored.handle.logs) {
|
|
1528
|
+
logInfo(`logs not supported by target ${S.cmd(restored.target.id)}`);
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
for await (const entry of restored.handle.logs({ follow: opts.follow })) {
|
|
1532
|
+
console.log(entry.line);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
function makeDeployCommand() {
|
|
1536
|
+
const cmd = new Command("deploy").description(
|
|
1537
|
+
"Deploy a workspace to a target (up / down / status / logs)"
|
|
1538
|
+
);
|
|
1539
|
+
cmd.command("up").description("Resolve a deploy target, stand the workspace up, and wait until ready").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <id>", "Override the deploy target (precedence: override > yaml > default)").option("--detach", "Persist the handle and return instead of holding in the foreground").action(action(runUp));
|
|
1540
|
+
cmd.command("down").description("Tear down the active deploy and clear its handle").option("--project-dir <path>", "Project directory", process.cwd()).action(action(runDown));
|
|
1541
|
+
cmd.command("status").description("Show the active deploy's state, ws URL, and health").option("--project-dir <path>", "Project directory", process.cwd()).action(action(runStatus));
|
|
1542
|
+
cmd.command("logs").description("Stream logs from the active deploy (if the target supports it)").option("--project-dir <path>", "Project directory", process.cwd()).option("--follow", "Keep streaming new log lines").action(action(runLogs));
|
|
1543
|
+
cmd.action(() => cmd.help());
|
|
1544
|
+
return cmd;
|
|
1545
|
+
}
|
|
1382
1546
|
function makeDiffCommand() {
|
|
1383
1547
|
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((ref, opts) => {
|
|
1384
|
-
const am2 = new AssetManager({ projectDir:
|
|
1548
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1385
1549
|
const result = am2.diff(ref);
|
|
1386
1550
|
if (result === null) {
|
|
1387
1551
|
logInfo("No differences (or asset not found).");
|
|
@@ -1434,7 +1598,7 @@ function makeFlowCommand() {
|
|
|
1434
1598
|
function makeHistoryCommand() {
|
|
1435
1599
|
const cmd = new Command("history").description("Show recent add/remove/update actions");
|
|
1436
1600
|
cmd.argument("[limit]", "Number of entries to show", "20").option("--project-dir <path>", "Project directory", process.cwd()).action((limitStr, opts) => {
|
|
1437
|
-
const am2 = new AssetManager({ projectDir:
|
|
1601
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1438
1602
|
const limit = parseInt(limitStr, 10) || 20;
|
|
1439
1603
|
const entries = am2.history(limit);
|
|
1440
1604
|
if (entries.length === 0) {
|
|
@@ -1454,7 +1618,7 @@ function makeHistoryCommand() {
|
|
|
1454
1618
|
console.log();
|
|
1455
1619
|
});
|
|
1456
1620
|
cmd.command("clear").description("Clear action history").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1457
|
-
const am2 = new AssetManager({ projectDir:
|
|
1621
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
1458
1622
|
am2.clearHistory();
|
|
1459
1623
|
logOk("History cleared.");
|
|
1460
1624
|
});
|
|
@@ -1522,7 +1686,7 @@ function makeLibraryCommand() {
|
|
|
1522
1686
|
cmd.command("init <name>").description("Create a new local library at ~/.skaile/libraries/<name>").option("--git <url>", "Initialize as a git library tracking <url>").option("--owner", "Mark as owner (default for local)").option("--contributor", "Mark as contributor").option("--reader", "Mark as reader").action(
|
|
1523
1687
|
async (name, opts) => {
|
|
1524
1688
|
const libDir = resolveLibraryDir();
|
|
1525
|
-
const libPath =
|
|
1689
|
+
const libPath = path14.join(libDir, name);
|
|
1526
1690
|
const ownership = opts.contributor ? "contributor" : opts.reader ? "reader" : "owner";
|
|
1527
1691
|
const { manager, close } = await openLibraryManager();
|
|
1528
1692
|
try {
|
|
@@ -1595,7 +1759,7 @@ function makeLibraryCommand() {
|
|
|
1595
1759
|
target = def;
|
|
1596
1760
|
}
|
|
1597
1761
|
const am2 = new AssetManager({ projectDir: process.cwd() });
|
|
1598
|
-
const destDir = opts.dir ?
|
|
1762
|
+
const destDir = opts.dir ? path14.join(target.path, opts.dir) : target.path;
|
|
1599
1763
|
const res = am2.create(name, opts.kind ?? kind, destDir);
|
|
1600
1764
|
if (res.ok) {
|
|
1601
1765
|
logOk(`Created ${opts.kind ?? kind}: ${pc5.dim(res.path)}`);
|
|
@@ -1621,8 +1785,8 @@ function makeLibraryCommand() {
|
|
|
1621
1785
|
const { manager, close } = await openLibraryManager();
|
|
1622
1786
|
try {
|
|
1623
1787
|
const lib = await manager.requireLibrary(oldName);
|
|
1624
|
-
const parent =
|
|
1625
|
-
const newPath =
|
|
1788
|
+
const parent = path14.dirname(lib.path);
|
|
1789
|
+
const newPath = path14.join(parent, newName);
|
|
1626
1790
|
if (fs10.existsSync(newPath)) {
|
|
1627
1791
|
logErr(`Target directory already exists: ${newPath}`);
|
|
1628
1792
|
process.exit(1);
|
|
@@ -1813,9 +1977,9 @@ async function printOverallStatus(projectDir, asJson) {
|
|
|
1813
1977
|
} catch {
|
|
1814
1978
|
secretsStrategy = "unavailable";
|
|
1815
1979
|
}
|
|
1816
|
-
const resolvedProjectDir =
|
|
1817
|
-
const hasWorkspaceConfig = existsSync(
|
|
1818
|
-
const hasLockFile = existsSync(
|
|
1980
|
+
const resolvedProjectDir = path14.resolve(projectDir);
|
|
1981
|
+
const hasWorkspaceConfig = existsSync(path14.join(resolvedProjectDir, "skaile.yaml"));
|
|
1982
|
+
const hasLockFile = existsSync(path14.join(resolvedProjectDir, "skaile.lock.yaml"));
|
|
1819
1983
|
let subscriptions = [];
|
|
1820
1984
|
if (hasWorkspaceConfig) {
|
|
1821
1985
|
try {
|
|
@@ -2092,16 +2256,16 @@ function assetRefOf(r) {
|
|
|
2092
2256
|
function findAssetRow(ref) {
|
|
2093
2257
|
return state.assetRows.find((r) => isAsset(r) && assetRefOf(r) === ref);
|
|
2094
2258
|
}
|
|
2095
|
-
function setSelection(ref,
|
|
2259
|
+
function setSelection(ref, action3) {
|
|
2096
2260
|
const row = findAssetRow(ref);
|
|
2097
2261
|
if (!row) return;
|
|
2098
|
-
if (
|
|
2262
|
+
if (action3 === "clear") {
|
|
2099
2263
|
state.pendingAdds.delete(ref);
|
|
2100
2264
|
state.pendingRemoves.delete(ref);
|
|
2101
2265
|
return;
|
|
2102
2266
|
}
|
|
2103
2267
|
let resolved;
|
|
2104
|
-
if (
|
|
2268
|
+
if (action3 === "toggle") {
|
|
2105
2269
|
if (state.pendingAdds.has(ref) || state.pendingRemoves.has(ref)) {
|
|
2106
2270
|
state.pendingAdds.delete(ref);
|
|
2107
2271
|
state.pendingRemoves.delete(ref);
|
|
@@ -2109,7 +2273,7 @@ function setSelection(ref, action) {
|
|
|
2109
2273
|
}
|
|
2110
2274
|
resolved = row.installed ? "remove" : "add";
|
|
2111
2275
|
} else {
|
|
2112
|
-
resolved =
|
|
2276
|
+
resolved = action3;
|
|
2113
2277
|
}
|
|
2114
2278
|
if (resolved === "add") {
|
|
2115
2279
|
state.pendingRemoves.delete(ref);
|
|
@@ -2121,22 +2285,22 @@ function setSelection(ref, action) {
|
|
|
2121
2285
|
state.pendingRemoves.add(ref);
|
|
2122
2286
|
}
|
|
2123
2287
|
}
|
|
2124
|
-
function bulkSelection(refs,
|
|
2125
|
-
for (const ref of refs) setSelection(ref,
|
|
2288
|
+
function bulkSelection(refs, action3) {
|
|
2289
|
+
for (const ref of refs) setSelection(ref, action3);
|
|
2126
2290
|
}
|
|
2127
|
-
function actOnHeader(row,
|
|
2291
|
+
function actOnHeader(row, action3) {
|
|
2128
2292
|
if (row.type === "source-header") {
|
|
2129
|
-
bulkSelection(sourceAssetRefs(state.assetRows, row.source),
|
|
2293
|
+
bulkSelection(sourceAssetRefs(state.assetRows, row.source), action3);
|
|
2130
2294
|
return true;
|
|
2131
2295
|
}
|
|
2132
2296
|
if (row.type === "header") {
|
|
2133
|
-
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain),
|
|
2297
|
+
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain), action3);
|
|
2134
2298
|
return true;
|
|
2135
2299
|
}
|
|
2136
2300
|
return false;
|
|
2137
2301
|
}
|
|
2138
2302
|
async function loadAssets() {
|
|
2139
|
-
const { gatherAssetFeeds } = await import('../asset-feeds-
|
|
2303
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-PJDJ3QYI.js');
|
|
2140
2304
|
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
2141
2305
|
if (notes.length > 0) {
|
|
2142
2306
|
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
@@ -2193,12 +2357,12 @@ async function loadAssets() {
|
|
|
2193
2357
|
async function loadSourcesAndLibraries() {
|
|
2194
2358
|
try {
|
|
2195
2359
|
const [{ openLibraryManager: openLibraryManager2 }, { skaileHomeDir: skaileHomeDir2 }] = await Promise.all([
|
|
2196
|
-
import('../open-library-
|
|
2360
|
+
import('../open-library-DWAQFUSQ.js'),
|
|
2197
2361
|
import('../library/index.js')
|
|
2198
2362
|
]);
|
|
2199
2363
|
const { manager, library, close } = await openLibraryManager2();
|
|
2200
2364
|
try {
|
|
2201
|
-
const sourcesDir2 =
|
|
2365
|
+
const sourcesDir2 = path14__default.join(skaileHomeDir2(), "sources");
|
|
2202
2366
|
const isSourceRow = (l) => l.path.startsWith(sourcesDir2);
|
|
2203
2367
|
const libs = await manager.listLibraries();
|
|
2204
2368
|
const defs = await library.listAssetDefs();
|
|
@@ -2469,14 +2633,14 @@ async function syncAll() {
|
|
|
2469
2633
|
"Sync is not yet driven from the manage TUI. Run `skaile source sync` (sources) or `skaile library sync <name>` (git-backed libraries) from the shell."
|
|
2470
2634
|
);
|
|
2471
2635
|
}
|
|
2472
|
-
function sourceShellHint(
|
|
2636
|
+
function sourceShellHint(action3) {
|
|
2473
2637
|
state.message = pc5.yellow(
|
|
2474
|
-
`${
|
|
2638
|
+
`${action3} is a shell command. Run \`skaile source \u2026\` from the shell.`
|
|
2475
2639
|
);
|
|
2476
2640
|
}
|
|
2477
|
-
function libraryShellHint(
|
|
2641
|
+
function libraryShellHint(action3) {
|
|
2478
2642
|
state.message = pc5.yellow(
|
|
2479
|
-
`${
|
|
2643
|
+
`${action3} is a shell command. Run \`skaile library \u2026\` from the shell.`
|
|
2480
2644
|
);
|
|
2481
2645
|
}
|
|
2482
2646
|
async function showInfo() {
|
|
@@ -2700,13 +2864,13 @@ async function run(projectDir) {
|
|
|
2700
2864
|
}
|
|
2701
2865
|
function makeManageCommand() {
|
|
2702
2866
|
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2703
|
-
await run(
|
|
2867
|
+
await run(path14__default.resolve(opts.projectDir));
|
|
2704
2868
|
});
|
|
2705
2869
|
}
|
|
2706
2870
|
function makeMcpServerCommand() {
|
|
2707
2871
|
return new Command("mcp-server").description("Start skaile workspace MCP server (stdio transport)").option("--project-dir <path>", "Project directory (default: cwd)", process.cwd()).action(async (opts) => {
|
|
2708
|
-
const
|
|
2709
|
-
const projectDir =
|
|
2872
|
+
const path34 = await import('path');
|
|
2873
|
+
const projectDir = path34.default.resolve(opts.projectDir);
|
|
2710
2874
|
const { LogStore, StdoutSink, registerLogStore } = await import('../core/logging.js');
|
|
2711
2875
|
registerLogStore(
|
|
2712
2876
|
new LogStore({
|
|
@@ -2741,7 +2905,7 @@ function makeNpxCommand() {
|
|
|
2741
2905
|
const npx = new Command("npx").description("Compatibility shim for npx skills syntax");
|
|
2742
2906
|
const skills = npx.command("skills").description("Skill installation from external repos");
|
|
2743
2907
|
skills.command("add <url>").description("Register a repo as a Library Source and install a skill from it").requiredOption("--skill <name>", "Skill name to install from the repo").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").option("--global", "Deploy globally").action(async (url, opts) => {
|
|
2744
|
-
const projectDir =
|
|
2908
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
2745
2909
|
const spinner5 = p5.spinner();
|
|
2746
2910
|
let sourcePath;
|
|
2747
2911
|
const isUrl = /^(https?:|git@|git:)/.test(url);
|
|
@@ -2752,14 +2916,14 @@ function makeNpxCommand() {
|
|
|
2752
2916
|
if (!existsSync(sourcePath)) {
|
|
2753
2917
|
execSync(`git clone ${url} ${sourcePath}`, { stdio: "ignore" });
|
|
2754
2918
|
}
|
|
2755
|
-
spinner5.stop(`Cloned to ${
|
|
2919
|
+
spinner5.stop(`Cloned to ${path14__default.basename(sourcePath)}`);
|
|
2756
2920
|
} catch (err) {
|
|
2757
2921
|
spinner5.stop("Clone failed");
|
|
2758
2922
|
logErr(err instanceof Error ? err.message : String(err));
|
|
2759
2923
|
process.exit(1);
|
|
2760
2924
|
}
|
|
2761
2925
|
} else {
|
|
2762
|
-
sourcePath =
|
|
2926
|
+
sourcePath = path14__default.resolve(url);
|
|
2763
2927
|
if (!existsSync(sourcePath)) {
|
|
2764
2928
|
logErr(`Path does not exist: ${sourcePath}`);
|
|
2765
2929
|
process.exit(1);
|
|
@@ -2772,7 +2936,7 @@ function makeNpxCommand() {
|
|
|
2772
2936
|
if (!source) {
|
|
2773
2937
|
source = await library.addSource({
|
|
2774
2938
|
backend: "local",
|
|
2775
|
-
name:
|
|
2939
|
+
name: path14__default.basename(sourcePath),
|
|
2776
2940
|
path: sourcePath,
|
|
2777
2941
|
ownership: "owner"
|
|
2778
2942
|
});
|
|
@@ -2813,7 +2977,7 @@ function makeNpxCommand() {
|
|
|
2813
2977
|
}
|
|
2814
2978
|
function cloneDestination(url) {
|
|
2815
2979
|
const cleaned = url.replace(/\.git$/, "");
|
|
2816
|
-
const root =
|
|
2980
|
+
const root = path14__default.join(homedir(), ".skaile", "clones");
|
|
2817
2981
|
let host = "unknown";
|
|
2818
2982
|
let pathPart = cleaned;
|
|
2819
2983
|
const httpMatch = cleaned.match(/^https?:\/\/([^/]+)\/(.+)$/);
|
|
@@ -2829,83 +2993,7 @@ function cloneDestination(url) {
|
|
|
2829
2993
|
host = gitProtoMatch[1];
|
|
2830
2994
|
pathPart = gitProtoMatch[2];
|
|
2831
2995
|
}
|
|
2832
|
-
return
|
|
2833
|
-
}
|
|
2834
|
-
function makeOutdatedCommand() {
|
|
2835
|
-
return new Command("outdated").description("Check for assets behind their repo").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).addOption(
|
|
2836
|
-
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
2837
|
-
).action((name, opts) => {
|
|
2838
|
-
const am2 = new AssetManager({
|
|
2839
|
-
projectDir: path15__default.resolve(opts.projectDir),
|
|
2840
|
-
driverTarget: opts.target
|
|
2841
|
-
});
|
|
2842
|
-
const entries = am2.outdated();
|
|
2843
|
-
if (entries.length === 0) {
|
|
2844
|
-
logInfo("All assets are up to date.");
|
|
2845
|
-
return;
|
|
2846
|
-
}
|
|
2847
|
-
const filtered = name ? entries.filter((e) => `${e.kind}:${e.name}` === name || e.name === name) : entries;
|
|
2848
|
-
if (filtered.length === 0) {
|
|
2849
|
-
logInfo(`${name} is up to date.`);
|
|
2850
|
-
return;
|
|
2851
|
-
}
|
|
2852
|
-
const nameW = Math.max(4, ...filtered.map((e) => e.name.length));
|
|
2853
|
-
console.log();
|
|
2854
|
-
console.log(S.heading(" Outdated Assets"));
|
|
2855
|
-
console.log(` ${S.rule(nameW + 40)}`);
|
|
2856
|
-
for (const e of filtered) {
|
|
2857
|
-
console.log(
|
|
2858
|
-
` ${kindColorPad(e.kind)} ${e.name.padEnd(nameW)} ${S.dim(e.repository)} ${pc5.yellow(`${e.behind} commit(s) behind`)}`
|
|
2859
|
-
);
|
|
2860
|
-
}
|
|
2861
|
-
console.log();
|
|
2862
|
-
logWarn(`Run ${S.cmd("skaile update")} to re-deploy.`);
|
|
2863
|
-
});
|
|
2864
|
-
}
|
|
2865
|
-
function makePatchCommand() {
|
|
2866
|
-
const cmd = new Command("patch").description("Patch workflow for skill improvement");
|
|
2867
|
-
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2868
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2869
|
-
try {
|
|
2870
|
-
const dest = am2.patch(ref);
|
|
2871
|
-
logOk(`Extracted to ${S.dim(dest)}`);
|
|
2872
|
-
console.log(` Edit the files, then run ${S.cmd(`skaile patch commit ${ref}`)}`);
|
|
2873
|
-
} catch (err) {
|
|
2874
|
-
logErr(String(err));
|
|
2875
|
-
process.exit(1);
|
|
2876
|
-
}
|
|
2877
|
-
});
|
|
2878
|
-
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2879
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2880
|
-
try {
|
|
2881
|
-
const patchFile = am2.patchCommit(ref);
|
|
2882
|
-
logOk(`Patch saved to ${S.dim(patchFile)}`);
|
|
2883
|
-
console.log(` Add to skaile.yaml patches section, then run ${S.cmd("skaile install")}`);
|
|
2884
|
-
} catch (err) {
|
|
2885
|
-
logErr(String(err));
|
|
2886
|
-
process.exit(1);
|
|
2887
|
-
}
|
|
2888
|
-
});
|
|
2889
|
-
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2890
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2891
|
-
try {
|
|
2892
|
-
am2.patchSubmit(ref);
|
|
2893
|
-
logOk("Patch applied to repo clone and committed.");
|
|
2894
|
-
console.log(
|
|
2895
|
-
` Push upstream from the source repo directly \u2014 the legacy ${S.cmd("skaile repo contrib push")} command was removed on 2026-05-12.`
|
|
2896
|
-
);
|
|
2897
|
-
} catch (err) {
|
|
2898
|
-
logErr(String(err));
|
|
2899
|
-
process.exit(1);
|
|
2900
|
-
}
|
|
2901
|
-
});
|
|
2902
|
-
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
2903
|
-
const am2 = new AssetManager({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
2904
|
-
am2.patchRemove(ref);
|
|
2905
|
-
logOk(`Patch removed for ${ref}`);
|
|
2906
|
-
});
|
|
2907
|
-
cmd.action(() => cmd.help());
|
|
2908
|
-
return cmd;
|
|
2996
|
+
return path14__default.join(root, host, pathPart);
|
|
2909
2997
|
}
|
|
2910
2998
|
var SKAILE_MCP_NAME = "skaile-workspace";
|
|
2911
2999
|
var MCP_SERVER_ENTRY = {
|
|
@@ -2914,7 +3002,7 @@ var MCP_SERVER_ENTRY = {
|
|
|
2914
3002
|
env: {}
|
|
2915
3003
|
};
|
|
2916
3004
|
function pluginDir(projectDir) {
|
|
2917
|
-
return
|
|
3005
|
+
return path14__default.join(projectDir, ".claude", "plugins", "skaile");
|
|
2918
3006
|
}
|
|
2919
3007
|
async function readJsonStrict(p7) {
|
|
2920
3008
|
let raw;
|
|
@@ -2932,7 +3020,7 @@ async function readJsonStrict(p7) {
|
|
|
2932
3020
|
}
|
|
2933
3021
|
}
|
|
2934
3022
|
async function writeJson(p7, value) {
|
|
2935
|
-
await fs5.mkdir(
|
|
3023
|
+
await fs5.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
2936
3024
|
await fs5.writeFile(p7, `${JSON.stringify(value, null, 2)}
|
|
2937
3025
|
`);
|
|
2938
3026
|
}
|
|
@@ -2940,8 +3028,8 @@ async function copyDir(src, dest) {
|
|
|
2940
3028
|
await fs5.mkdir(dest, { recursive: true });
|
|
2941
3029
|
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
2942
3030
|
for (const entry of entries) {
|
|
2943
|
-
const srcPath =
|
|
2944
|
-
const destPath =
|
|
3031
|
+
const srcPath = path14__default.join(src, entry.name);
|
|
3032
|
+
const destPath = path14__default.join(dest, entry.name);
|
|
2945
3033
|
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
2946
3034
|
else await fs5.copyFile(srcPath, destPath);
|
|
2947
3035
|
}
|
|
@@ -2950,14 +3038,14 @@ async function install(projectDir, opts) {
|
|
|
2950
3038
|
return opts?.full ? installFullPlugin(projectDir) : installMcp(projectDir);
|
|
2951
3039
|
}
|
|
2952
3040
|
async function installMcp(projectDir) {
|
|
2953
|
-
const mcpPath =
|
|
3041
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
2954
3042
|
const existing = await readJsonStrict(mcpPath) ?? {};
|
|
2955
3043
|
const mcpServers = { ...existing.mcpServers ?? {} };
|
|
2956
3044
|
const previous = mcpServers[SKAILE_MCP_NAME];
|
|
2957
3045
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(MCP_SERVER_ENTRY);
|
|
2958
3046
|
let warning;
|
|
2959
3047
|
if (previous && !matches) {
|
|
2960
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${
|
|
3048
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME} entry in ${path14__default.relative(projectDir, mcpPath)}`;
|
|
2961
3049
|
}
|
|
2962
3050
|
mcpServers[SKAILE_MCP_NAME] = MCP_SERVER_ENTRY;
|
|
2963
3051
|
await writeJson(mcpPath, { ...existing, mcpServers });
|
|
@@ -2966,15 +3054,15 @@ async function installMcp(projectDir) {
|
|
|
2966
3054
|
async function installFullPlugin(projectDir) {
|
|
2967
3055
|
const dir = pluginDir(projectDir);
|
|
2968
3056
|
for (const [rel, content] of Object.entries(buildClaudePluginFiles())) {
|
|
2969
|
-
const dest =
|
|
2970
|
-
await fs5.mkdir(
|
|
3057
|
+
const dest = path14__default.join(dir, rel);
|
|
3058
|
+
await fs5.mkdir(path14__default.dirname(dest), { recursive: true });
|
|
2971
3059
|
await fs5.writeFile(dest, content);
|
|
2972
3060
|
}
|
|
2973
|
-
const projectSkillsDir =
|
|
3061
|
+
const projectSkillsDir = path14__default.join(projectDir, ".skaile", "skills");
|
|
2974
3062
|
if (existsSync(projectSkillsDir)) {
|
|
2975
|
-
await copyDir(projectSkillsDir,
|
|
3063
|
+
await copyDir(projectSkillsDir, path14__default.join(dir, "skills"));
|
|
2976
3064
|
}
|
|
2977
|
-
const settingsPath =
|
|
3065
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
2978
3066
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
2979
3067
|
const plugins = settings.plugins ?? [];
|
|
2980
3068
|
if (!plugins.includes(dir)) plugins.push(dir);
|
|
@@ -2982,8 +3070,8 @@ async function installFullPlugin(projectDir) {
|
|
|
2982
3070
|
return { changed: true, method: "plugin" };
|
|
2983
3071
|
}
|
|
2984
3072
|
async function uninstall(projectDir) {
|
|
2985
|
-
const settingsPath =
|
|
2986
|
-
const mcpPath =
|
|
3073
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3074
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
2987
3075
|
const dir = pluginDir(projectDir);
|
|
2988
3076
|
let changed = false;
|
|
2989
3077
|
const settings = await readJsonStrict(settingsPath);
|
|
@@ -3017,12 +3105,12 @@ async function uninstall(projectDir) {
|
|
|
3017
3105
|
async function detectInstall(projectDir) {
|
|
3018
3106
|
const dir = pluginDir(projectDir);
|
|
3019
3107
|
const settings = await readJsonStrict(
|
|
3020
|
-
|
|
3108
|
+
path14__default.join(projectDir, ".claude", "settings.json")
|
|
3021
3109
|
);
|
|
3022
|
-
if (existsSync(
|
|
3110
|
+
if (existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir)) {
|
|
3023
3111
|
return { method: "plugin", pluginPath: dir };
|
|
3024
3112
|
}
|
|
3025
|
-
const mcp = await readJsonStrict(
|
|
3113
|
+
const mcp = await readJsonStrict(path14__default.join(projectDir, ".claude", "mcp.json"));
|
|
3026
3114
|
if (mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers) {
|
|
3027
3115
|
return { method: "mcp" };
|
|
3028
3116
|
}
|
|
@@ -3031,7 +3119,7 @@ async function detectInstall(projectDir) {
|
|
|
3031
3119
|
async function enable(projectDir) {
|
|
3032
3120
|
const detected = await detectInstall(projectDir);
|
|
3033
3121
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3034
|
-
const settingsPath =
|
|
3122
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3035
3123
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3036
3124
|
if (detected.method === "plugin") {
|
|
3037
3125
|
const disabled2 = settings.disabledPlugins ?? [];
|
|
@@ -3053,7 +3141,7 @@ async function enable(projectDir) {
|
|
|
3053
3141
|
async function disable(projectDir) {
|
|
3054
3142
|
const detected = await detectInstall(projectDir);
|
|
3055
3143
|
if (!detected) throw new Error("plugin not installed for claude-code");
|
|
3056
|
-
const settingsPath =
|
|
3144
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3057
3145
|
const settings = await readJsonStrict(settingsPath) ?? {};
|
|
3058
3146
|
if (detected.method === "plugin") {
|
|
3059
3147
|
const list2 = settings.disabledPlugins ?? [];
|
|
@@ -3073,12 +3161,12 @@ async function disable(projectDir) {
|
|
|
3073
3161
|
return { changed: true };
|
|
3074
3162
|
}
|
|
3075
3163
|
async function status(projectDir) {
|
|
3076
|
-
const settingsPath =
|
|
3077
|
-
const mcpPath =
|
|
3164
|
+
const settingsPath = path14__default.join(projectDir, ".claude", "settings.json");
|
|
3165
|
+
const mcpPath = path14__default.join(projectDir, ".claude", "mcp.json");
|
|
3078
3166
|
const dir = pluginDir(projectDir);
|
|
3079
3167
|
const settings = await readJsonStrict(settingsPath);
|
|
3080
3168
|
const mcp = await readJsonStrict(mcpPath);
|
|
3081
|
-
const pluginInstalled = !!(existsSync(
|
|
3169
|
+
const pluginInstalled = !!(existsSync(path14__default.join(dir, ".claude-plugin", "plugin.json")) && settings?.plugins?.includes(dir));
|
|
3082
3170
|
const mcpInstalled = !!(mcp?.mcpServers && SKAILE_MCP_NAME in mcp.mcpServers);
|
|
3083
3171
|
if (!pluginInstalled && !mcpInstalled) {
|
|
3084
3172
|
return {
|
|
@@ -3096,7 +3184,7 @@ async function status(projectDir) {
|
|
|
3096
3184
|
installed: "yes",
|
|
3097
3185
|
enabled: disabled2 ? "no" : "yes",
|
|
3098
3186
|
method: "plugin",
|
|
3099
|
-
location:
|
|
3187
|
+
location: path14__default.relative(projectDir, dir)
|
|
3100
3188
|
};
|
|
3101
3189
|
}
|
|
3102
3190
|
const disabled = settings?.disabledMcpjsonServers?.includes(SKAILE_MCP_NAME) ?? false;
|
|
@@ -3105,7 +3193,7 @@ async function status(projectDir) {
|
|
|
3105
3193
|
installed: "yes",
|
|
3106
3194
|
enabled: disabled ? "no" : "yes",
|
|
3107
3195
|
method: "mcp",
|
|
3108
|
-
location:
|
|
3196
|
+
location: path14__default.relative(projectDir, mcpPath)
|
|
3109
3197
|
};
|
|
3110
3198
|
}
|
|
3111
3199
|
var SKAILE_MCP_NAME2 = "skaile-workspace";
|
|
@@ -3132,7 +3220,7 @@ async function readConfig(p7) {
|
|
|
3132
3220
|
}
|
|
3133
3221
|
}
|
|
3134
3222
|
async function writeConfig(p7, value) {
|
|
3135
|
-
await fs5.mkdir(
|
|
3223
|
+
await fs5.mkdir(path14__default.dirname(p7), { recursive: true });
|
|
3136
3224
|
const cleaned = {};
|
|
3137
3225
|
for (const [k, v] of Object.entries(value)) {
|
|
3138
3226
|
if (v === void 0) continue;
|
|
@@ -3141,7 +3229,7 @@ async function writeConfig(p7, value) {
|
|
|
3141
3229
|
await fs5.writeFile(p7, stringify(cleaned));
|
|
3142
3230
|
}
|
|
3143
3231
|
function configPath(projectDir) {
|
|
3144
|
-
return
|
|
3232
|
+
return path14__default.join(projectDir, ".codex", "config.toml");
|
|
3145
3233
|
}
|
|
3146
3234
|
async function install2(projectDir) {
|
|
3147
3235
|
const p7 = configPath(projectDir);
|
|
@@ -3152,7 +3240,7 @@ async function install2(projectDir) {
|
|
|
3152
3240
|
const matches = previous && JSON.stringify(previous) === JSON.stringify(next);
|
|
3153
3241
|
let warning;
|
|
3154
3242
|
if (previous && !matches) {
|
|
3155
|
-
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${
|
|
3243
|
+
warning = `overwrote existing ${SKAILE_MCP_NAME2} entry in ${path14__default.relative(projectDir, p7)}`;
|
|
3156
3244
|
}
|
|
3157
3245
|
if (matches) return { changed: false, method: "toml" };
|
|
3158
3246
|
servers[SKAILE_MCP_NAME2] = next;
|
|
@@ -3193,12 +3281,12 @@ async function status2(projectDir) {
|
|
|
3193
3281
|
installed: "yes",
|
|
3194
3282
|
enabled: "n/a",
|
|
3195
3283
|
method: "mcp",
|
|
3196
|
-
location:
|
|
3284
|
+
location: path14__default.relative(projectDir, p7)
|
|
3197
3285
|
};
|
|
3198
3286
|
}
|
|
3199
3287
|
async function install3(projectDir) {
|
|
3200
|
-
const extDir =
|
|
3201
|
-
const extPath =
|
|
3288
|
+
const extDir = path14__default.join(projectDir, ".omp", "extensions");
|
|
3289
|
+
const extPath = path14__default.join(extDir, "skaile.ts");
|
|
3202
3290
|
await fs5.mkdir(extDir, { recursive: true });
|
|
3203
3291
|
const { WorkspacePlugin } = await import('../workspace-plugin/index.js');
|
|
3204
3292
|
const plugin = new WorkspacePlugin({ projectDir });
|
|
@@ -3213,7 +3301,7 @@ async function install3(projectDir) {
|
|
|
3213
3301
|
return { changed: true, method: "generated" };
|
|
3214
3302
|
}
|
|
3215
3303
|
async function uninstall3(projectDir) {
|
|
3216
|
-
const extPath =
|
|
3304
|
+
const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3217
3305
|
try {
|
|
3218
3306
|
await fs5.unlink(extPath);
|
|
3219
3307
|
return { changed: true };
|
|
@@ -3222,14 +3310,14 @@ async function uninstall3(projectDir) {
|
|
|
3222
3310
|
}
|
|
3223
3311
|
}
|
|
3224
3312
|
async function status3(projectDir) {
|
|
3225
|
-
const extPath =
|
|
3313
|
+
const extPath = path14__default.join(projectDir, ".omp", "extensions", "skaile.ts");
|
|
3226
3314
|
if (existsSync(extPath)) {
|
|
3227
3315
|
return {
|
|
3228
3316
|
backend: "omp",
|
|
3229
3317
|
installed: "yes",
|
|
3230
3318
|
enabled: "n/a",
|
|
3231
3319
|
method: "extension",
|
|
3232
|
-
location:
|
|
3320
|
+
location: path14__default.relative(projectDir, extPath)
|
|
3233
3321
|
};
|
|
3234
3322
|
}
|
|
3235
3323
|
return {
|
|
@@ -3241,7 +3329,7 @@ async function status3(projectDir) {
|
|
|
3241
3329
|
};
|
|
3242
3330
|
}
|
|
3243
3331
|
|
|
3244
|
-
// cli/src/commands/
|
|
3332
|
+
// cli/src/commands/integration.ts
|
|
3245
3333
|
var ALL_BACKENDS = ["claude-code", "omp", "codex"];
|
|
3246
3334
|
var TOGGLE_SUPPORTED = ["claude-code"];
|
|
3247
3335
|
function resolveDriver(driver) {
|
|
@@ -3250,7 +3338,7 @@ function resolveDriver(driver) {
|
|
|
3250
3338
|
throw new Error(`unknown driver: ${driver} (expected: claude-code | omp | codex | all)`);
|
|
3251
3339
|
}
|
|
3252
3340
|
async function runInstall(opts) {
|
|
3253
|
-
const projectDir =
|
|
3341
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3254
3342
|
const targets = resolveDriver(opts.driver);
|
|
3255
3343
|
let exitCode = 0;
|
|
3256
3344
|
if (targets.includes("claude-code")) {
|
|
@@ -3305,7 +3393,7 @@ async function runInstall(opts) {
|
|
|
3305
3393
|
return exitCode;
|
|
3306
3394
|
}
|
|
3307
3395
|
async function runUninstall(opts) {
|
|
3308
|
-
const projectDir =
|
|
3396
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3309
3397
|
const targets = resolveDriver(opts.driver);
|
|
3310
3398
|
let exitCode = 0;
|
|
3311
3399
|
if (targets.includes("claude-code")) {
|
|
@@ -3341,15 +3429,15 @@ async function runUninstall(opts) {
|
|
|
3341
3429
|
if (exitCode === 0) logOk("Plugin uninstalled.");
|
|
3342
3430
|
return exitCode;
|
|
3343
3431
|
}
|
|
3344
|
-
async function runToggle(opts,
|
|
3345
|
-
const projectDir =
|
|
3432
|
+
async function runToggle(opts, action3) {
|
|
3433
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3346
3434
|
const requestedAll = opts.driver === "all";
|
|
3347
3435
|
const targets = resolveDriver(opts.driver);
|
|
3348
3436
|
if (!requestedAll) {
|
|
3349
3437
|
const unsupported = targets.filter((t) => !TOGGLE_SUPPORTED.includes(t));
|
|
3350
3438
|
if (unsupported.length > 0) {
|
|
3351
3439
|
logErr(
|
|
3352
|
-
`${
|
|
3440
|
+
`${action3} is only supported for claude-code; for ${unsupported.join(", ")} use uninstall/install`
|
|
3353
3441
|
);
|
|
3354
3442
|
return 2;
|
|
3355
3443
|
}
|
|
@@ -3357,27 +3445,27 @@ async function runToggle(opts, action) {
|
|
|
3357
3445
|
let exitCode = 0;
|
|
3358
3446
|
for (const t of targets) {
|
|
3359
3447
|
if (!TOGGLE_SUPPORTED.includes(t)) {
|
|
3360
|
-
logInfo(`${t}: ${
|
|
3448
|
+
logInfo(`${t}: ${action3} not supported; skipping`);
|
|
3361
3449
|
continue;
|
|
3362
3450
|
}
|
|
3363
3451
|
if (t === "claude-code") {
|
|
3364
3452
|
try {
|
|
3365
|
-
const r =
|
|
3453
|
+
const r = action3 === "enable" ? await enable(projectDir) : await disable(projectDir);
|
|
3366
3454
|
if (r.changed) {
|
|
3367
|
-
logOk(`claude-code: ${
|
|
3455
|
+
logOk(`claude-code: ${action3}d`);
|
|
3368
3456
|
} else {
|
|
3369
|
-
logInfo(`claude-code: already ${
|
|
3457
|
+
logInfo(`claude-code: already ${action3}d`);
|
|
3370
3458
|
}
|
|
3371
3459
|
} catch (e) {
|
|
3372
|
-
logErr(`claude-code ${
|
|
3460
|
+
logErr(`claude-code ${action3}: ${e instanceof Error ? e.message : String(e)}`);
|
|
3373
3461
|
exitCode = 1;
|
|
3374
3462
|
}
|
|
3375
3463
|
}
|
|
3376
3464
|
}
|
|
3377
3465
|
return exitCode;
|
|
3378
3466
|
}
|
|
3379
|
-
async function
|
|
3380
|
-
const projectDir =
|
|
3467
|
+
async function runStatus2(opts) {
|
|
3468
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3381
3469
|
const targets = resolveDriver(opts.driver);
|
|
3382
3470
|
const rows = [];
|
|
3383
3471
|
let exitCode = 0;
|
|
@@ -3448,7 +3536,7 @@ async function runHook(event) {
|
|
|
3448
3536
|
await plugin.shutdown();
|
|
3449
3537
|
return;
|
|
3450
3538
|
}
|
|
3451
|
-
const store = new PluginStore(
|
|
3539
|
+
const store = new PluginStore(path14__default.join(projectDir, ".skaile", "plugin-state.json"));
|
|
3452
3540
|
await store.load();
|
|
3453
3541
|
const status4 = store.get("connector:status");
|
|
3454
3542
|
if (status4 && typeof status4 === "object" && Object.keys(status4).length > 0) {
|
|
@@ -3463,9 +3551,9 @@ async function runHook(event) {
|
|
|
3463
3551
|
);
|
|
3464
3552
|
}
|
|
3465
3553
|
}
|
|
3466
|
-
function
|
|
3467
|
-
const cmd = new Command("
|
|
3468
|
-
"Manage skaile workspace
|
|
3554
|
+
function makeIntegrationCommand() {
|
|
3555
|
+
const cmd = new Command("integration").description(
|
|
3556
|
+
"Manage skaile agent integration / workspace-plugin adapter (Claude Code / OMP / Codex)"
|
|
3469
3557
|
);
|
|
3470
3558
|
cmd.command("install").description("Install skaile workspace plugin").option("--driver <name>", "Target: claude-code | omp | codex | all", "all").option("--project-dir <path>", "Project directory", process.cwd()).option(
|
|
3471
3559
|
"--full",
|
|
@@ -3483,7 +3571,7 @@ function makePluginCommand() {
|
|
|
3483
3571
|
process.exitCode = await runToggle(opts, "disable");
|
|
3484
3572
|
});
|
|
3485
3573
|
cmd.command("status").description("Show install / enable status across backends").option("--driver <name>", "Target: claude-code | omp | codex | all", "all").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
3486
|
-
process.exitCode = await
|
|
3574
|
+
process.exitCode = await runStatus2(opts);
|
|
3487
3575
|
});
|
|
3488
3576
|
cmd.command("hook <event>").description(
|
|
3489
3577
|
"Run a Claude Code lifecycle hook (session-start | session-end | user-prompt-submit)"
|
|
@@ -3508,12 +3596,189 @@ function makePluginCommand() {
|
|
|
3508
3596
|
cmd.action(() => cmd.help());
|
|
3509
3597
|
return cmd;
|
|
3510
3598
|
}
|
|
3599
|
+
function makeOutdatedCommand() {
|
|
3600
|
+
return new Command("outdated").description("Check for assets behind their repo").argument("[name]", "Check a specific asset (kind:name)").option("--project-dir <path>", "Project directory", process.cwd()).addOption(
|
|
3601
|
+
new Option("--target <agent>", "Driver target").default("claude-code").choices(SUPPORTED_DRIVER_TARGETS)
|
|
3602
|
+
).action((name, opts) => {
|
|
3603
|
+
const am2 = new AssetManager({
|
|
3604
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
3605
|
+
driverTarget: opts.target
|
|
3606
|
+
});
|
|
3607
|
+
const entries = am2.outdated();
|
|
3608
|
+
if (entries.length === 0) {
|
|
3609
|
+
logInfo("All assets are up to date.");
|
|
3610
|
+
return;
|
|
3611
|
+
}
|
|
3612
|
+
const filtered = name ? entries.filter((e) => `${e.kind}:${e.name}` === name || e.name === name) : entries;
|
|
3613
|
+
if (filtered.length === 0) {
|
|
3614
|
+
logInfo(`${name} is up to date.`);
|
|
3615
|
+
return;
|
|
3616
|
+
}
|
|
3617
|
+
const nameW = Math.max(4, ...filtered.map((e) => e.name.length));
|
|
3618
|
+
console.log();
|
|
3619
|
+
console.log(S.heading(" Outdated Assets"));
|
|
3620
|
+
console.log(` ${S.rule(nameW + 40)}`);
|
|
3621
|
+
for (const e of filtered) {
|
|
3622
|
+
console.log(
|
|
3623
|
+
` ${kindColorPad(e.kind)} ${e.name.padEnd(nameW)} ${S.dim(e.repository)} ${pc5.yellow(`${e.behind} commit(s) behind`)}`
|
|
3624
|
+
);
|
|
3625
|
+
}
|
|
3626
|
+
console.log();
|
|
3627
|
+
logWarn(`Run ${S.cmd("skaile update")} to re-deploy.`);
|
|
3628
|
+
});
|
|
3629
|
+
}
|
|
3630
|
+
function makePatchCommand() {
|
|
3631
|
+
const cmd = new Command("patch").description("Patch workflow for skill improvement");
|
|
3632
|
+
cmd.command("extract <ref>").alias("start").description("Extract asset for local editing").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3633
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3634
|
+
try {
|
|
3635
|
+
const dest = am2.patch(ref);
|
|
3636
|
+
logOk(`Extracted to ${S.dim(dest)}`);
|
|
3637
|
+
console.log(` Edit the files, then run ${S.cmd(`skaile patch commit ${ref}`)}`);
|
|
3638
|
+
} catch (err) {
|
|
3639
|
+
logErr(String(err));
|
|
3640
|
+
process.exit(1);
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
cmd.command("commit <ref>").description("Generate .patch file from edits").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3644
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3645
|
+
try {
|
|
3646
|
+
const patchFile = am2.patchCommit(ref);
|
|
3647
|
+
logOk(`Patch saved to ${S.dim(patchFile)}`);
|
|
3648
|
+
console.log(` Add to skaile.yaml patches section, then run ${S.cmd("skaile install")}`);
|
|
3649
|
+
} catch (err) {
|
|
3650
|
+
logErr(String(err));
|
|
3651
|
+
process.exit(1);
|
|
3652
|
+
}
|
|
3653
|
+
});
|
|
3654
|
+
cmd.command("submit <ref>").description("Apply patch to repo clone and prepare for PR").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3655
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3656
|
+
try {
|
|
3657
|
+
am2.patchSubmit(ref);
|
|
3658
|
+
logOk("Patch applied to repo clone and committed.");
|
|
3659
|
+
console.log(
|
|
3660
|
+
` Push upstream from the source repo directly \u2014 the legacy ${S.cmd("skaile repo contrib push")} command was removed on 2026-05-12.`
|
|
3661
|
+
);
|
|
3662
|
+
} catch (err) {
|
|
3663
|
+
logErr(String(err));
|
|
3664
|
+
process.exit(1);
|
|
3665
|
+
}
|
|
3666
|
+
});
|
|
3667
|
+
cmd.command("remove <ref>").description("Remove local patch after upstream merge").option("--project-dir <path>", "Project directory", process.cwd()).action((ref, opts) => {
|
|
3668
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3669
|
+
am2.patchRemove(ref);
|
|
3670
|
+
logOk(`Patch removed for ${ref}`);
|
|
3671
|
+
});
|
|
3672
|
+
cmd.action(() => cmd.help());
|
|
3673
|
+
return cmd;
|
|
3674
|
+
}
|
|
3675
|
+
function action2(fn) {
|
|
3676
|
+
return async (...args) => {
|
|
3677
|
+
try {
|
|
3678
|
+
await fn(...args);
|
|
3679
|
+
} catch (err) {
|
|
3680
|
+
logErr(err instanceof Error ? err.message : String(err));
|
|
3681
|
+
process.exitCode = 1;
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
}
|
|
3685
|
+
async function reconcileAndReport(projectDir, plugins) {
|
|
3686
|
+
const { reconcilePlugins } = await import('../plugin-store-6OENKNFW.js');
|
|
3687
|
+
if (plugins.length === 0) {
|
|
3688
|
+
logInfo("No plugins declared \u2014 nothing to reconcile.");
|
|
3689
|
+
return;
|
|
3690
|
+
}
|
|
3691
|
+
try {
|
|
3692
|
+
const result = await reconcilePlugins(projectDir, plugins);
|
|
3693
|
+
if (result.changed) logOk(`Reconciled plugin store (${result.reason}).`);
|
|
3694
|
+
else logInfo(`Plugin store ${result.reason}.`);
|
|
3695
|
+
} catch (err) {
|
|
3696
|
+
logWarn(`reconcile skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
async function runInstall2(spec, opts) {
|
|
3700
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3701
|
+
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
3702
|
+
const { specName } = await import('../plugin-store-6OENKNFW.js');
|
|
3703
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
3704
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
3705
|
+
const replaced = editor.addPlugin(spec, specName);
|
|
3706
|
+
editor.save();
|
|
3707
|
+
if (replaced) logOk(`Updated ${S.cmd(specName(spec))} \u2192 ${S.cmd(spec)} in skaile.yaml`);
|
|
3708
|
+
else logOk(`Added ${S.cmd(spec)} to skaile.yaml plugins`);
|
|
3709
|
+
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
3710
|
+
}
|
|
3711
|
+
async function runRemove(name, opts) {
|
|
3712
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3713
|
+
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
3714
|
+
const { specName } = await import('../plugin-store-6OENKNFW.js');
|
|
3715
|
+
const yamlPath = path14__default.join(projectDir, "skaile.yaml");
|
|
3716
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
3717
|
+
const removed = editor.removePlugin(name, specName);
|
|
3718
|
+
if (!removed) {
|
|
3719
|
+
logInfo(`No plugin matching ${S.cmd(name)} in skaile.yaml plugins.`);
|
|
3720
|
+
return;
|
|
3721
|
+
}
|
|
3722
|
+
editor.save();
|
|
3723
|
+
logOk(`Removed ${S.cmd(name)} from skaile.yaml plugins`);
|
|
3724
|
+
await reconcileAndReport(projectDir, editor.getPlugins());
|
|
3725
|
+
}
|
|
3726
|
+
async function runList(opts) {
|
|
3727
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3728
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
3729
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
3730
|
+
const declared = config.plugins ?? [];
|
|
3731
|
+
console.log();
|
|
3732
|
+
console.log(S.heading(" Declared plugins (skaile.yaml):"));
|
|
3733
|
+
if (declared.length === 0) {
|
|
3734
|
+
console.log(` ${S.dim("(none)")}`);
|
|
3735
|
+
} else {
|
|
3736
|
+
for (const spec of declared) console.log(` ${S.dim("\xB7")} ${S.cmd(spec)}`);
|
|
3737
|
+
}
|
|
3738
|
+
const { createPluginRegistry } = await import('../plugin-registry/index.js');
|
|
3739
|
+
const registry = createPluginRegistry();
|
|
3740
|
+
if (declared.length > 0) {
|
|
3741
|
+
try {
|
|
3742
|
+
const { loadPlugins } = await import('../plugin-store-6OENKNFW.js');
|
|
3743
|
+
const result = await loadPlugins(projectDir, declared, registry);
|
|
3744
|
+
for (const f of result.failed) logWarn(f.error);
|
|
3745
|
+
} catch (err) {
|
|
3746
|
+
logWarn(`could not load plugins: ${err instanceof Error ? err.message : String(err)}`);
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
const kinds = [
|
|
3750
|
+
{ kind: "driver", label: "drivers" },
|
|
3751
|
+
{ kind: "connector", label: "connectors" },
|
|
3752
|
+
{ kind: "deployTarget", label: "deploy targets" }
|
|
3753
|
+
];
|
|
3754
|
+
console.log();
|
|
3755
|
+
console.log(S.heading(" Contributed targets:"));
|
|
3756
|
+
let any = false;
|
|
3757
|
+
for (const { kind, label } of kinds) {
|
|
3758
|
+
const metas = registry.list(kind);
|
|
3759
|
+
if (metas.length === 0) continue;
|
|
3760
|
+
any = true;
|
|
3761
|
+
console.log(` ${S.label(label)}: ${metas.map((m) => S.cmd(m.id)).join(", ")}`);
|
|
3762
|
+
}
|
|
3763
|
+
if (!any) console.log(` ${S.dim("(none \u2014 plugins not installed, or contribute nothing)")}`);
|
|
3764
|
+
console.log();
|
|
3765
|
+
}
|
|
3766
|
+
function makePluginCommand() {
|
|
3767
|
+
const cmd = new Command("plugin").description(
|
|
3768
|
+
"Manage registry plugins (drivers / connectors / deploy targets) declared in skaile.yaml"
|
|
3769
|
+
);
|
|
3770
|
+
cmd.command("install <spec>").description("Add a plugin spec to skaile.yaml plugins and reconcile the store").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runInstall2));
|
|
3771
|
+
cmd.command("remove <name>").description("Remove a plugin (by package name) from skaile.yaml plugins and reconcile").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runRemove));
|
|
3772
|
+
cmd.command("list").description("List declared plugins and the targets they contribute").option("--project-dir <path>", "Project directory", process.cwd()).action(action2(runList));
|
|
3773
|
+
cmd.action(() => cmd.help());
|
|
3774
|
+
return cmd;
|
|
3775
|
+
}
|
|
3511
3776
|
function makePresetCommand() {
|
|
3512
3777
|
const cmd = new Command("preset").description("Scaffold and validate preset YAML files");
|
|
3513
3778
|
cmd.command("init [name]").description("Scaffold a new .preset.yaml file").option("--dir <path>", "Output directory", process.cwd()).action(async (name, opts) => {
|
|
3514
3779
|
const presetName = name ?? "my-preset";
|
|
3515
3780
|
const filename = `${presetName}.preset.yaml`;
|
|
3516
|
-
const outPath =
|
|
3781
|
+
const outPath = path14__default.join(path14__default.resolve(opts.dir), filename);
|
|
3517
3782
|
if (existsSync(outPath)) {
|
|
3518
3783
|
logErr(`File already exists: ${outPath}`);
|
|
3519
3784
|
logInfo("Choose a different name or remove the existing file.");
|
|
@@ -3527,7 +3792,7 @@ function makePresetCommand() {
|
|
|
3527
3792
|
logInfo(` skaile preset validate ${filename}`);
|
|
3528
3793
|
});
|
|
3529
3794
|
cmd.command("validate <path>").description("Validate a preset YAML file (schema + cycles + nesting depth)").action(async (filePath) => {
|
|
3530
|
-
const resolved =
|
|
3795
|
+
const resolved = path14__default.resolve(filePath);
|
|
3531
3796
|
if (!existsSync(resolved)) {
|
|
3532
3797
|
logErr(`File not found: ${resolved}`);
|
|
3533
3798
|
process.exit(1);
|
|
@@ -3553,7 +3818,7 @@ function makePresetCommand() {
|
|
|
3553
3818
|
logInfo(`Nested preset refs: ${nestedRefs.length} (depth validated at apply-time)`);
|
|
3554
3819
|
}
|
|
3555
3820
|
const { detectCycles } = await import('../discovery/index.js');
|
|
3556
|
-
const presetRef =
|
|
3821
|
+
const presetRef = path14__default.basename(resolved, ".preset.yaml");
|
|
3557
3822
|
const edges = [];
|
|
3558
3823
|
for (const item of preset.items) {
|
|
3559
3824
|
if (item.ref) {
|
|
@@ -3677,8 +3942,8 @@ function makeInstallCommand() {
|
|
|
3677
3942
|
const spinner6 = p5.spinner();
|
|
3678
3943
|
spinner6.start(`Installing ${ref}`);
|
|
3679
3944
|
try {
|
|
3680
|
-
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-
|
|
3681
|
-
const catalog = await openCatalogSource2({ projectDir:
|
|
3945
|
+
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-DWAQFUSQ.js');
|
|
3946
|
+
const catalog = await openCatalogSource2({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3682
3947
|
if (!supportsInstallManifest(catalog)) {
|
|
3683
3948
|
throw new Error(
|
|
3684
3949
|
"pointer-only install (skaile install <ref>) requires a tRPC-framed Catalog. The configured catalog uses REST framing, which does not serve install manifests. Set catalog.url to https://skaile.store, or catalog.framing: trpc, in ~/.skaile/config.yaml."
|
|
@@ -3707,9 +3972,9 @@ function makeInstallCommand() {
|
|
|
3707
3972
|
}
|
|
3708
3973
|
return;
|
|
3709
3974
|
}
|
|
3710
|
-
const projectDir =
|
|
3975
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3711
3976
|
try {
|
|
3712
|
-
const { ensureSourcesCloned } = await import('../ensure-sources-
|
|
3977
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-COGVKY44.js');
|
|
3713
3978
|
const hydrate = ensureSourcesCloned(projectDir, { quiet: true });
|
|
3714
3979
|
if (hydrate.cloned.length > 0) {
|
|
3715
3980
|
logOk(`Cloned source(s): ${hydrate.cloned.join(", ")}`);
|
|
@@ -3762,7 +4027,7 @@ function makeInstallCommand() {
|
|
|
3762
4027
|
}
|
|
3763
4028
|
function makeCheckCommand() {
|
|
3764
4029
|
return new Command("check").description("Check for unmet requirements").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
3765
|
-
const am2 = new AssetManager({ projectDir:
|
|
4030
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
3766
4031
|
const issues = am2.doctor();
|
|
3767
4032
|
if (issues.length === 0) {
|
|
3768
4033
|
logOk("All dependencies satisfied.");
|
|
@@ -3779,10 +4044,10 @@ function makeCheckCommand() {
|
|
|
3779
4044
|
function makeCleanCommand() {
|
|
3780
4045
|
return new Command("clean").description("Remove all skaile-managed assets from the workspace").option("--all", "Full reset: also remove history, patches, repos, and lock file").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()).option("--target <agent>", "Agent framework", "claude-code").action(async (opts) => {
|
|
3781
4046
|
const am2 = new AssetManager({
|
|
3782
|
-
projectDir:
|
|
4047
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
3783
4048
|
driverTarget: opts.target
|
|
3784
4049
|
});
|
|
3785
|
-
const lock = readLock(
|
|
4050
|
+
const lock = readLock(path14__default.resolve(opts.projectDir, "skaile.lock.yaml"));
|
|
3786
4051
|
if (!lock || Object.keys(lock.assets).length === 0) {
|
|
3787
4052
|
logInfo("Nothing to clean (no skaile-managed assets found).");
|
|
3788
4053
|
return;
|
|
@@ -3835,14 +4100,14 @@ function makeCleanCommand() {
|
|
|
3835
4100
|
}
|
|
3836
4101
|
function makeRebuildCommand() {
|
|
3837
4102
|
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) => {
|
|
3838
|
-
const projectDir =
|
|
4103
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3839
4104
|
let agentDir;
|
|
3840
4105
|
if (agentArg) {
|
|
3841
4106
|
if (agentArg.includes("/") || agentArg.includes("\\")) {
|
|
3842
|
-
agentDir =
|
|
4107
|
+
agentDir = path14__default.resolve(projectDir, agentArg);
|
|
3843
4108
|
} else {
|
|
3844
4109
|
const resolved = resolveAgentDir(projectDir);
|
|
3845
|
-
agentDir = resolved ??
|
|
4110
|
+
agentDir = resolved ?? path14__default.resolve(projectDir, agentArg);
|
|
3846
4111
|
}
|
|
3847
4112
|
} else {
|
|
3848
4113
|
const resolved = resolveAgentDir(projectDir);
|
|
@@ -3920,7 +4185,7 @@ function makeFlowEventHandler() {
|
|
|
3920
4185
|
}
|
|
3921
4186
|
function makeRunCommand() {
|
|
3922
4187
|
const cmd = new Command("run").description("Start a flow or run a single-shot text prompt").argument("[flow-id-or-text...]", "Flow ID or text prompt").option("--project-dir <path>", "Project directory", process.cwd()).option("--driver <name>", "Driver backend (claude-sdk, codex, omp)").option("--provider <name>", "LLM provider").option("--model <name>", "Model override").option("--label <label>", "Human-readable session label").option("--dry-run", "Print plan without executing").option("--skill <name>", "Skill name (for single-shot mode)").action(async (positional, opts) => {
|
|
3923
|
-
const projectDir =
|
|
4188
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
3924
4189
|
const cliDriver = opts.driver;
|
|
3925
4190
|
const dryRun = opts.dryRun ?? false;
|
|
3926
4191
|
let flowId = positional[0];
|
|
@@ -3974,15 +4239,15 @@ function makeRunCommand() {
|
|
|
3974
4239
|
let flowPath;
|
|
3975
4240
|
let dir = projectDir;
|
|
3976
4241
|
for (let i = 0; i < 6; i++) {
|
|
3977
|
-
const candidate =
|
|
4242
|
+
const candidate = path14__default.join(dir, "ai-assets");
|
|
3978
4243
|
if (fs10__default.existsSync(candidate)) {
|
|
3979
4244
|
for (const domain of fs10__default.readdirSync(candidate)) {
|
|
3980
|
-
const p_ =
|
|
4245
|
+
const p_ = path14__default.join(candidate, domain, "flows", `${flowId}.flow.yaml`);
|
|
3981
4246
|
if (fs10__default.existsSync(p_)) {
|
|
3982
4247
|
flowPath = p_;
|
|
3983
4248
|
break;
|
|
3984
4249
|
}
|
|
3985
|
-
const legacy =
|
|
4250
|
+
const legacy = path14__default.join(candidate, domain, "flows", `${flowId}.json`);
|
|
3986
4251
|
if (fs10__default.existsSync(legacy)) {
|
|
3987
4252
|
flowPath = legacy;
|
|
3988
4253
|
break;
|
|
@@ -3990,16 +4255,16 @@ function makeRunCommand() {
|
|
|
3990
4255
|
}
|
|
3991
4256
|
break;
|
|
3992
4257
|
}
|
|
3993
|
-
dir =
|
|
4258
|
+
dir = path14__default.dirname(dir);
|
|
3994
4259
|
}
|
|
3995
4260
|
if (!flowPath) {
|
|
3996
4261
|
for (const domain of fs10__default.readdirSync(AI_RESOURCES)) {
|
|
3997
|
-
const p_ =
|
|
4262
|
+
const p_ = path14__default.join(AI_RESOURCES, domain, "flows", `${flowId}.flow.yaml`);
|
|
3998
4263
|
if (fs10__default.existsSync(p_)) {
|
|
3999
4264
|
flowPath = p_;
|
|
4000
4265
|
break;
|
|
4001
4266
|
}
|
|
4002
|
-
const legacy =
|
|
4267
|
+
const legacy = path14__default.join(AI_RESOURCES, domain, "flows", `${flowId}.json`);
|
|
4003
4268
|
if (fs10__default.existsSync(legacy)) {
|
|
4004
4269
|
flowPath = legacy;
|
|
4005
4270
|
break;
|
|
@@ -4033,7 +4298,7 @@ function makeRunCommand() {
|
|
|
4033
4298
|
}
|
|
4034
4299
|
function makeResumeCommand() {
|
|
4035
4300
|
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) => {
|
|
4036
|
-
const projectDir =
|
|
4301
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4037
4302
|
const sessionId = opts.session;
|
|
4038
4303
|
const dryRun = opts.dryRun ?? false;
|
|
4039
4304
|
const session = sessionId ? await loadSessionById(projectDir, sessionId) : await loadSession(projectDir);
|
|
@@ -4060,7 +4325,7 @@ function makeResumeCommand() {
|
|
|
4060
4325
|
}
|
|
4061
4326
|
function makeStatusCommand() {
|
|
4062
4327
|
return new Command("status").description("Show current session state").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4063
|
-
const projectDir =
|
|
4328
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4064
4329
|
const session = await loadSession(projectDir);
|
|
4065
4330
|
if (!session) {
|
|
4066
4331
|
logInfo("No active session.");
|
|
@@ -4085,7 +4350,7 @@ function makeStatusCommand() {
|
|
|
4085
4350
|
}
|
|
4086
4351
|
function makeClearCommand() {
|
|
4087
4352
|
return new Command("clear").description("Unset current session pointer").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4088
|
-
const projectDir =
|
|
4353
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4089
4354
|
await clearSession(projectDir);
|
|
4090
4355
|
logOk("Session cleared.");
|
|
4091
4356
|
});
|
|
@@ -4095,7 +4360,7 @@ function makeReplCommand() {
|
|
|
4095
4360
|
const { findWorkspaceRoot: findWorkspaceRoot2 } = await import('../core/index.js');
|
|
4096
4361
|
const { startRepl } = await import('../tui/index.js');
|
|
4097
4362
|
const os = await import('os');
|
|
4098
|
-
const userCwd =
|
|
4363
|
+
const userCwd = path14__default.resolve(opts.projectDir ?? process.cwd());
|
|
4099
4364
|
const workspaceRoot = findWorkspaceRoot2(userCwd);
|
|
4100
4365
|
let projectDir;
|
|
4101
4366
|
let agentCwd;
|
|
@@ -4117,12 +4382,12 @@ function makeReplCommand() {
|
|
|
4117
4382
|
p5.cancel("Cancelled.");
|
|
4118
4383
|
process.exit(0);
|
|
4119
4384
|
}
|
|
4120
|
-
const tmpDir = fs10__default.mkdtempSync(
|
|
4385
|
+
const tmpDir = fs10__default.mkdtempSync(path14__default.join(os.tmpdir(), "skaile-repl-"));
|
|
4121
4386
|
projectDir = tmpDir;
|
|
4122
4387
|
agentCwd = userCwd;
|
|
4123
4388
|
logOk(`Temporary workspace: ${S.cmd(tmpDir)}`);
|
|
4124
4389
|
if (!driverOverride) {
|
|
4125
|
-
const claudeDir =
|
|
4390
|
+
const claudeDir = path14__default.join(os.homedir(), ".claude");
|
|
4126
4391
|
if (fs10__default.existsSync(claudeDir)) {
|
|
4127
4392
|
driverOverride = "claude-sdk";
|
|
4128
4393
|
logInfo(`Detected ${S.cmd("~/.claude")} \u2192 using ${S.cmd("claude-sdk")} backend`);
|
|
@@ -4154,6 +4419,7 @@ function makeServeCommand() {
|
|
|
4154
4419
|
await runCompileTest({ ...opts, withCodex: opts.withCodex ?? false });
|
|
4155
4420
|
return;
|
|
4156
4421
|
}
|
|
4422
|
+
await ensurePluginsLoadedForServe(opts.projectDir);
|
|
4157
4423
|
const { startAgentServer } = await import('../runner/index.js');
|
|
4158
4424
|
await startAgentServer({
|
|
4159
4425
|
port: parseInt(opts.port, 10),
|
|
@@ -4167,6 +4433,25 @@ function makeServeCommand() {
|
|
|
4167
4433
|
}
|
|
4168
4434
|
);
|
|
4169
4435
|
}
|
|
4436
|
+
async function ensurePluginsLoadedForServe(projectDir) {
|
|
4437
|
+
const { logInfo: logInfo2, logWarn: logWarn2 } = await import('../helpers-I3SREIC3.js');
|
|
4438
|
+
try {
|
|
4439
|
+
const { resolveSkWorkspaceConfig: resolveSkWorkspaceConfig2 } = await import('../core/index.js');
|
|
4440
|
+
const config = resolveSkWorkspaceConfig2(projectDir);
|
|
4441
|
+
if (!config.plugins || config.plugins.length === 0) return;
|
|
4442
|
+
const { ensurePluginsLoaded } = await import('../plugin-store-6OENKNFW.js');
|
|
4443
|
+
const { pluginRegistry } = await import('../plugin-registry/index.js');
|
|
4444
|
+
const result = await ensurePluginsLoaded(projectDir, config.plugins, pluginRegistry);
|
|
4445
|
+
if (result.loaded.length > 0) {
|
|
4446
|
+
logInfo2(`Loaded ${result.loaded.length} plugin(s): ${result.loaded.join(", ")}`);
|
|
4447
|
+
}
|
|
4448
|
+
for (const f of result.failed) {
|
|
4449
|
+
logWarn2(f.error);
|
|
4450
|
+
}
|
|
4451
|
+
} catch (err) {
|
|
4452
|
+
logWarn2(`plugin store skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4170
4455
|
async function runCompileTest(opts) {
|
|
4171
4456
|
const { logOk: logOk2, logErr: logErr2, logInfo: logInfo2, S: S2 } = await import('../helpers-I3SREIC3.js');
|
|
4172
4457
|
const { tmpdir } = await import('os');
|
|
@@ -4645,7 +4930,7 @@ function resolveMode(opts) {
|
|
|
4645
4930
|
if (opts.forceLocal && opts.forceRemote) {
|
|
4646
4931
|
throw new Error("Cannot use both --local and --remote");
|
|
4647
4932
|
}
|
|
4648
|
-
const startDir =
|
|
4933
|
+
const startDir = path14__default.resolve(opts.projectDir ?? process.cwd());
|
|
4649
4934
|
const localDb = findLogsDb(startDir);
|
|
4650
4935
|
if (opts.forceLocal) {
|
|
4651
4936
|
if (!localDb) {
|
|
@@ -4678,14 +4963,14 @@ function resolveMode(opts) {
|
|
|
4678
4963
|
function findLogsDb(startDir) {
|
|
4679
4964
|
let dir = startDir;
|
|
4680
4965
|
for (let i = 0; i < MAX_WALK_LEVELS; i++) {
|
|
4681
|
-
const candidate =
|
|
4966
|
+
const candidate = path14__default.join(dir, ".skaile", "logs.db");
|
|
4682
4967
|
if (existsSync(candidate)) {
|
|
4683
4968
|
try {
|
|
4684
4969
|
if (statSync(candidate).isFile()) return candidate;
|
|
4685
4970
|
} catch {
|
|
4686
4971
|
}
|
|
4687
4972
|
}
|
|
4688
|
-
const parent =
|
|
4973
|
+
const parent = path14__default.dirname(dir);
|
|
4689
4974
|
if (parent === dir) return void 0;
|
|
4690
4975
|
dir = parent;
|
|
4691
4976
|
}
|
|
@@ -4711,7 +4996,7 @@ function readApiToken() {
|
|
|
4711
4996
|
}
|
|
4712
4997
|
function readGlobalSettings() {
|
|
4713
4998
|
try {
|
|
4714
|
-
const settingsPath =
|
|
4999
|
+
const settingsPath = path14__default.join(homedir(), ".skaile", "settings.json");
|
|
4715
5000
|
if (!existsSync(settingsPath)) return {};
|
|
4716
5001
|
return JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
4717
5002
|
} catch {
|
|
@@ -4859,7 +5144,7 @@ function parsePositiveInt(value, flag) {
|
|
|
4859
5144
|
function makeSessionCommand() {
|
|
4860
5145
|
const cmd = new Command("session").description("Manage sessions");
|
|
4861
5146
|
cmd.command("list").description("List all sessions for a project").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
4862
|
-
const projectDir =
|
|
5147
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4863
5148
|
const sessions = await listSessions(projectDir);
|
|
4864
5149
|
const current = await loadSession(projectDir);
|
|
4865
5150
|
if (sessions.length === 0) {
|
|
@@ -4887,7 +5172,7 @@ function makeSessionCommand() {
|
|
|
4887
5172
|
console.log();
|
|
4888
5173
|
});
|
|
4889
5174
|
cmd.command("show <run-id>").description("Show a specific session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4890
|
-
const projectDir =
|
|
5175
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4891
5176
|
const session = await loadSessionById(projectDir, runId);
|
|
4892
5177
|
if (!session) {
|
|
4893
5178
|
logErr(`Session not found: ${runId}`);
|
|
@@ -4896,12 +5181,12 @@ function makeSessionCommand() {
|
|
|
4896
5181
|
console.log(JSON.stringify(session, null, 2));
|
|
4897
5182
|
});
|
|
4898
5183
|
cmd.command("switch <run-id>").description("Switch the current session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4899
|
-
const projectDir =
|
|
5184
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4900
5185
|
await setCurrentSession(projectDir, runId);
|
|
4901
5186
|
logOk(`Switched to session: ${S.dim(runId.slice(0, 8))}`);
|
|
4902
5187
|
});
|
|
4903
5188
|
cmd.command("delete <run-id>").description("Delete a session").option("--project-dir <path>", "Project directory", process.cwd()).action(async (runId, opts) => {
|
|
4904
|
-
const projectDir =
|
|
5189
|
+
const projectDir = path14__default.resolve(opts.projectDir);
|
|
4905
5190
|
await deleteSession(projectDir, runId);
|
|
4906
5191
|
logOk(`Deleted session: ${S.dim(runId.slice(0, 8))}`);
|
|
4907
5192
|
});
|
|
@@ -4964,7 +5249,7 @@ function showAsset(am2, kind, name) {
|
|
|
4964
5249
|
function makeShowCommand() {
|
|
4965
5250
|
return new Command("show").description("Show deployed assets overview, or print asset content").argument("[kind]", "Asset kind (skill, agent, prompt, flow, bundle, contract)").argument("[name]", "Asset name").option("--project-dir <path>", "Project directory", process.cwd()).option("--target <agent>", "Agent framework", "claude-code").action((kind, name, opts) => {
|
|
4966
5251
|
const am2 = new AssetManager({
|
|
4967
|
-
projectDir:
|
|
5252
|
+
projectDir: path14__default.resolve(opts.projectDir),
|
|
4968
5253
|
driverTarget: opts.target
|
|
4969
5254
|
});
|
|
4970
5255
|
if (!kind) {
|
|
@@ -5002,10 +5287,10 @@ function addSourceManifestCommands(src) {
|
|
|
5002
5287
|
|
|
5003
5288
|
// cli/src/commands/source.ts
|
|
5004
5289
|
function sourcesDir() {
|
|
5005
|
-
return
|
|
5290
|
+
return path14.join(skaileHomeDir(), "sources");
|
|
5006
5291
|
}
|
|
5007
5292
|
function sourceClonePath(name) {
|
|
5008
|
-
return
|
|
5293
|
+
return path14.join(sourcesDir(), name);
|
|
5009
5294
|
}
|
|
5010
5295
|
function deriveSlug(url) {
|
|
5011
5296
|
return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
|
|
@@ -5018,7 +5303,7 @@ function requireProjectYamlPath() {
|
|
|
5018
5303
|
);
|
|
5019
5304
|
process.exit(1);
|
|
5020
5305
|
}
|
|
5021
|
-
return
|
|
5306
|
+
return path14.join(root, workspaceConfigFilename());
|
|
5022
5307
|
}
|
|
5023
5308
|
function readProjectSources(yamlPath) {
|
|
5024
5309
|
if (!existsSync(yamlPath)) return [];
|
|
@@ -5112,7 +5397,7 @@ function makeSourceCommand() {
|
|
|
5112
5397
|
const result = await refreshManifestCache(entry, opts.dev);
|
|
5113
5398
|
logOk(`Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from "${slug}".`);
|
|
5114
5399
|
for (const err of result.errors) logWarn(err);
|
|
5115
|
-
logOk(`Source "${slug}" registered in ${
|
|
5400
|
+
logOk(`Source "${slug}" registered in ${path14.relative(process.cwd(), yamlPath)}.`);
|
|
5116
5401
|
}
|
|
5117
5402
|
);
|
|
5118
5403
|
cmd.command("list").description("List sources registered in this project's skaile.yaml").option("--json", "Output as JSON").action(async (opts) => {
|
|
@@ -5371,7 +5656,7 @@ function printTree(node, prefix = "", isLast = true) {
|
|
|
5371
5656
|
}
|
|
5372
5657
|
function makeTreeCommand() {
|
|
5373
5658
|
return new Command("tree").description("Show full dependency tree").option("--project-dir <path>", "Project directory", process.cwd()).action((opts) => {
|
|
5374
|
-
const am2 = new AssetManager({ projectDir:
|
|
5659
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5375
5660
|
const root = am2.tree();
|
|
5376
5661
|
if (root.children.length === 0) {
|
|
5377
5662
|
logInfo("No dependencies in lock file. Run `skaile install` first.");
|
|
@@ -5389,7 +5674,7 @@ function makeUpdateCommand() {
|
|
|
5389
5674
|
try {
|
|
5390
5675
|
const catalogSpinner = p5.spinner();
|
|
5391
5676
|
catalogSpinner.start("Refreshing catalog cache");
|
|
5392
|
-
const remote = await openCatalogSource({ projectDir:
|
|
5677
|
+
const remote = await openCatalogSource({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5393
5678
|
const result2 = await remote.refresh();
|
|
5394
5679
|
catalogSpinner.stop(
|
|
5395
5680
|
`Catalog refreshed: ${S.heading(String(result2.assetsCached))} assets cached`
|
|
@@ -5401,7 +5686,7 @@ function makeUpdateCommand() {
|
|
|
5401
5686
|
}
|
|
5402
5687
|
}
|
|
5403
5688
|
if (opts.catalogOnly) return;
|
|
5404
|
-
const am2 = new AssetManager({ projectDir:
|
|
5689
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5405
5690
|
const spinner5 = p5.spinner();
|
|
5406
5691
|
spinner5.start("Re-deploying assets");
|
|
5407
5692
|
const result = await am2.install();
|
|
@@ -5447,7 +5732,7 @@ function findManifestCandidates(rootPath) {
|
|
|
5447
5732
|
return;
|
|
5448
5733
|
}
|
|
5449
5734
|
for (const entry of entries) {
|
|
5450
|
-
const fullPath =
|
|
5735
|
+
const fullPath = path14__default.join(dir, entry.name);
|
|
5451
5736
|
if (entry.isDirectory()) {
|
|
5452
5737
|
if (!SKIP_DIRS.has(entry.name)) walk(fullPath);
|
|
5453
5738
|
} else if (entry.isFile()) {
|
|
@@ -5469,7 +5754,7 @@ function parseMdFrontmatter(content) {
|
|
|
5469
5754
|
return parse(fmMatch[1]);
|
|
5470
5755
|
}
|
|
5471
5756
|
function validateManifests(rootPath) {
|
|
5472
|
-
const absRoot =
|
|
5757
|
+
const absRoot = path14__default.resolve(rootPath);
|
|
5473
5758
|
if (!fs10__default.existsSync(absRoot)) {
|
|
5474
5759
|
logErr(`Path does not exist: ${absRoot}`);
|
|
5475
5760
|
return { total: 0, errors: 1, warnings: 0 };
|
|
@@ -5490,14 +5775,14 @@ function validateManifests(rootPath) {
|
|
|
5490
5775
|
try {
|
|
5491
5776
|
parsed = c.filePath.endsWith(".json") ? JSON.parse(content) : parse(content);
|
|
5492
5777
|
} catch (e) {
|
|
5493
|
-
const relPath2 =
|
|
5778
|
+
const relPath2 = path14__default.relative(absRoot, c.filePath);
|
|
5494
5779
|
logErr(`${relPath2} \u2014 parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
5495
5780
|
errors++;
|
|
5496
5781
|
continue;
|
|
5497
5782
|
}
|
|
5498
5783
|
}
|
|
5499
5784
|
const provider = registry.getProvider(c.kind);
|
|
5500
|
-
const relPath =
|
|
5785
|
+
const relPath = path14__default.relative(absRoot, c.filePath);
|
|
5501
5786
|
if (!provider) {
|
|
5502
5787
|
logWarn(`${relPath} [${c.kind}] \u2014 kind "${c.kind}" is not registered, skipping validation`);
|
|
5503
5788
|
warnings++;
|
|
@@ -5519,20 +5804,20 @@ function collectAssetVersions() {
|
|
|
5519
5804
|
if (!fs10__default.existsSync(AI_RESOURCES)) return assets;
|
|
5520
5805
|
const domains = fs10__default.readdirSync(AI_RESOURCES, { withFileTypes: true }).filter((d) => d.isDirectory() && !EXCLUDED_DOMAINS.has(d.name));
|
|
5521
5806
|
for (const d of domains) {
|
|
5522
|
-
const domainDir =
|
|
5523
|
-
const skillsDir =
|
|
5807
|
+
const domainDir = path14__default.join(AI_RESOURCES, d.name);
|
|
5808
|
+
const skillsDir = path14__default.join(domainDir, "skills");
|
|
5524
5809
|
if (fs10__default.existsSync(skillsDir)) {
|
|
5525
5810
|
collectSkillVersions(skillsDir, d.name, assets);
|
|
5526
5811
|
}
|
|
5527
|
-
const agentsDir =
|
|
5812
|
+
const agentsDir = path14__default.join(domainDir, "agents");
|
|
5528
5813
|
if (fs10__default.existsSync(agentsDir)) {
|
|
5529
5814
|
collectAgentVersions(agentsDir, d.name, assets);
|
|
5530
5815
|
}
|
|
5531
|
-
const flowsDir =
|
|
5816
|
+
const flowsDir = path14__default.join(domainDir, "flows");
|
|
5532
5817
|
if (fs10__default.existsSync(flowsDir)) {
|
|
5533
5818
|
for (const f of fs10__default.readdirSync(flowsDir)) {
|
|
5534
5819
|
if (!f.endsWith(".flow.yaml")) continue;
|
|
5535
|
-
const fp =
|
|
5820
|
+
const fp = path14__default.join(flowsDir, f);
|
|
5536
5821
|
const content = fs10__default.readFileSync(fp, "utf-8");
|
|
5537
5822
|
const parsed = parse(content);
|
|
5538
5823
|
assets.push({
|
|
@@ -5544,11 +5829,11 @@ function collectAssetVersions() {
|
|
|
5544
5829
|
});
|
|
5545
5830
|
}
|
|
5546
5831
|
}
|
|
5547
|
-
const promptsDir =
|
|
5832
|
+
const promptsDir = path14__default.join(domainDir, "prompts");
|
|
5548
5833
|
if (fs10__default.existsSync(promptsDir)) {
|
|
5549
5834
|
for (const f of fs10__default.readdirSync(promptsDir)) {
|
|
5550
5835
|
if (!f.endsWith(".prompt.md")) continue;
|
|
5551
|
-
const fp =
|
|
5836
|
+
const fp = path14__default.join(promptsDir, f);
|
|
5552
5837
|
const content = fs10__default.readFileSync(fp, "utf-8");
|
|
5553
5838
|
const fm = parseSkillFrontmatter(content);
|
|
5554
5839
|
assets.push({
|
|
@@ -5566,8 +5851,8 @@ function collectAssetVersions() {
|
|
|
5566
5851
|
function collectSkillVersions(dir, domain, out) {
|
|
5567
5852
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
5568
5853
|
if (!entry.isDirectory()) continue;
|
|
5569
|
-
const full =
|
|
5570
|
-
const skillMd =
|
|
5854
|
+
const full = path14__default.join(dir, entry.name);
|
|
5855
|
+
const skillMd = path14__default.join(full, "SKILL.md");
|
|
5571
5856
|
if (fs10__default.existsSync(skillMd)) {
|
|
5572
5857
|
const content = fs10__default.readFileSync(skillMd, "utf-8");
|
|
5573
5858
|
const fm = parseSkillFrontmatter(content);
|
|
@@ -5586,7 +5871,7 @@ function collectSkillVersions(dir, domain, out) {
|
|
|
5586
5871
|
function collectAgentVersions(dir, domain, out) {
|
|
5587
5872
|
for (const entry of fs10__default.readdirSync(dir, { withFileTypes: true })) {
|
|
5588
5873
|
if (!entry.isDirectory()) continue;
|
|
5589
|
-
const agentYaml =
|
|
5874
|
+
const agentYaml = path14__default.join(dir, entry.name, "agent.yaml");
|
|
5590
5875
|
if (!fs10__default.existsSync(agentYaml)) continue;
|
|
5591
5876
|
const content = fs10__default.readFileSync(agentYaml, "utf-8");
|
|
5592
5877
|
const parsed = parse(content);
|
|
@@ -5617,7 +5902,7 @@ function makeValidateCommand() {
|
|
|
5617
5902
|
"Validate asset manifests, versions, and changelogs"
|
|
5618
5903
|
);
|
|
5619
5904
|
cmd.argument("[path]", "Path to asset repo or directory to validate", ".").action((targetPath) => {
|
|
5620
|
-
const absPath =
|
|
5905
|
+
const absPath = path14__default.resolve(targetPath);
|
|
5621
5906
|
logInfo(`Validating manifests in ${absPath}`);
|
|
5622
5907
|
const { total, errors } = validateManifests(absPath);
|
|
5623
5908
|
console.log();
|
|
@@ -5638,7 +5923,7 @@ function makeValidateCommand() {
|
|
|
5638
5923
|
encoding: "utf-8"
|
|
5639
5924
|
});
|
|
5640
5925
|
const changedFiles = new Set(
|
|
5641
|
-
diffOutput.trim().split("\n").filter(Boolean).map((f) =>
|
|
5926
|
+
diffOutput.trim().split("\n").filter(Boolean).map((f) => path14__default.resolve(AI_RESOURCES, f))
|
|
5642
5927
|
);
|
|
5643
5928
|
assets = assets.filter((a) => changedFiles.has(a.filePath));
|
|
5644
5929
|
} catch {
|
|
@@ -5660,7 +5945,7 @@ function makeValidateCommand() {
|
|
|
5660
5945
|
if (opts.changedOnly) {
|
|
5661
5946
|
for (const a of assets) {
|
|
5662
5947
|
if (!a.version) continue;
|
|
5663
|
-
const relPath =
|
|
5948
|
+
const relPath = path14__default.relative(AI_RESOURCES, a.filePath);
|
|
5664
5949
|
try {
|
|
5665
5950
|
const headContent = execSync(`git show HEAD:${relPath}`, {
|
|
5666
5951
|
cwd: AI_RESOURCES,
|
|
@@ -5740,7 +6025,7 @@ function makeValidateCommand() {
|
|
|
5740
6025
|
let errors = 0;
|
|
5741
6026
|
for (const domain of modifiedDomains) {
|
|
5742
6027
|
const changelogModified = modifiedFiles.some(
|
|
5743
|
-
(f) => f === `${domain}/CHANGELOG.md` || f ===
|
|
6028
|
+
(f) => f === `${domain}/CHANGELOG.md` || f === path14__default.join(domain, "CHANGELOG.md")
|
|
5744
6029
|
);
|
|
5745
6030
|
if (changelogModified) {
|
|
5746
6031
|
logOk(`${domain}/CHANGELOG.md updated`);
|
|
@@ -5822,7 +6107,7 @@ function makeVerifyCommand() {
|
|
|
5822
6107
|
}
|
|
5823
6108
|
function makeWhyCommand() {
|
|
5824
6109
|
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((ref, opts) => {
|
|
5825
|
-
const am2 = new AssetManager({ projectDir:
|
|
6110
|
+
const am2 = new AssetManager({ projectDir: path14__default.resolve(opts.projectDir) });
|
|
5826
6111
|
const chain = am2.why(ref);
|
|
5827
6112
|
if (chain.length === 0) {
|
|
5828
6113
|
logErr(`${ref} not found in lock file. Run \`skaile install\` first.`);
|
|
@@ -5843,7 +6128,7 @@ function makeWhyCommand() {
|
|
|
5843
6128
|
var _defaultFormatHelp = Help.prototype.formatHelp;
|
|
5844
6129
|
var pkg = JSON.parse(
|
|
5845
6130
|
readFileSync(
|
|
5846
|
-
|
|
6131
|
+
path14__default.resolve(path14__default.dirname(fileURLToPath(import.meta.url)), "../../package.json"),
|
|
5847
6132
|
"utf-8"
|
|
5848
6133
|
)
|
|
5849
6134
|
);
|
|
@@ -5891,11 +6176,18 @@ Execution:
|
|
|
5891
6176
|
resume Resume last session
|
|
5892
6177
|
serve [--compile-test] Start WebSocket agent server
|
|
5893
6178
|
mcp-server Start workspace MCP server (for .claude/mcp.json)
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
6179
|
+
integration install [--driver all] Install agent integration (claude-code | omp | codex)
|
|
6180
|
+
integration uninstall [--driver all] Uninstall agent integration
|
|
6181
|
+
integration enable Enable integration (claude-code only)
|
|
6182
|
+
integration disable Disable integration (claude-code only)
|
|
6183
|
+
integration status Show install / enable state across backends
|
|
6184
|
+
plugin install <spec> Add a registry plugin to skaile.yaml + reconcile
|
|
6185
|
+
plugin remove <name> Remove a registry plugin from skaile.yaml
|
|
6186
|
+
plugin list List declared plugins + the targets they contribute
|
|
6187
|
+
deploy up [--target] [--detach] Stand the workspace up on a deploy target
|
|
6188
|
+
deploy down Tear down the active deploy
|
|
6189
|
+
deploy status Show the active deploy's state + ws URL
|
|
6190
|
+
deploy logs [--follow] Stream logs from the active deploy
|
|
5899
6191
|
debug tools|connectors|mcp|config|state Inspect running container state
|
|
5900
6192
|
connect <url> Interactive WebSocket REPL
|
|
5901
6193
|
logs [--follow] [--filter] Tail skaile container logs
|
|
@@ -5947,136 +6239,130 @@ Advanced:
|
|
|
5947
6239
|
`;
|
|
5948
6240
|
}
|
|
5949
6241
|
});
|
|
5950
|
-
program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option(
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
}
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
const
|
|
6016
|
-
|
|
6017
|
-
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
6018
|
-
const append = entries.filter((e) => !have.has(e));
|
|
6019
|
-
if (append.length > 0) {
|
|
6020
|
-
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
6021
|
-
writeFileSync2(gitignorePath, existing + prefix + `${append.join("\n")}
|
|
6242
|
+
program.command("init [project-dir]").description("Initialize a project directory (defaults to current directory)").option("--backend <name>", "Coding-agent backend (claude-code | omp | codex)", "claude-code").option("--no-git", "Skip git init and .gitignore").action(async (projectDir, opts) => {
|
|
6243
|
+
const { execSync: execSync3 } = await import('child_process');
|
|
6244
|
+
const { existsSync: existsSync12, mkdirSync: mkdirSync3, readFileSync: readFileSync5, writeFileSync: writeFileSync2 } = await import('fs');
|
|
6245
|
+
const { stringify } = await import('yaml');
|
|
6246
|
+
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
6247
|
+
const backend = opts.backend;
|
|
6248
|
+
if (!SUPPORTED_DRIVER_TARGETS2.includes(backend)) {
|
|
6249
|
+
logErr(
|
|
6250
|
+
`Unknown backend "${opts.backend}". Supported: ${SUPPORTED_DRIVER_TARGETS2.join(", ")}`
|
|
6251
|
+
);
|
|
6252
|
+
process.exitCode = 1;
|
|
6253
|
+
return;
|
|
6254
|
+
}
|
|
6255
|
+
const resolved = path14__default.resolve(projectDir ?? ".");
|
|
6256
|
+
const projectName = path14__default.basename(resolved);
|
|
6257
|
+
const created = [];
|
|
6258
|
+
if (!existsSync12(resolved)) {
|
|
6259
|
+
mkdirSync3(resolved, { recursive: true });
|
|
6260
|
+
created.push(".");
|
|
6261
|
+
}
|
|
6262
|
+
const skaileDir = path14__default.join(resolved, ".skaile");
|
|
6263
|
+
if (!existsSync12(skaileDir)) {
|
|
6264
|
+
mkdirSync3(path14__default.join(skaileDir, "sessions"), { recursive: true });
|
|
6265
|
+
created.push(".skaile/");
|
|
6266
|
+
}
|
|
6267
|
+
const settingsPath = path14__default.join(skaileDir, "settings.json");
|
|
6268
|
+
if (!existsSync12(settingsPath)) {
|
|
6269
|
+
writeFileSync2(settingsPath, "{}\n");
|
|
6270
|
+
created.push(".skaile/settings.json");
|
|
6271
|
+
}
|
|
6272
|
+
const wsConfigPath = path14__default.join(resolved, "skaile.yaml");
|
|
6273
|
+
if (!existsSync12(wsConfigPath)) {
|
|
6274
|
+
writeFileSync2(
|
|
6275
|
+
wsConfigPath,
|
|
6276
|
+
stringify({
|
|
6277
|
+
name: projectName,
|
|
6278
|
+
description: `${projectName} AI skill dependencies`,
|
|
6279
|
+
"agent-config": {
|
|
6280
|
+
default: {
|
|
6281
|
+
agent: backend,
|
|
6282
|
+
provider: "anthropic",
|
|
6283
|
+
model: "claude-sonnet-4-6",
|
|
6284
|
+
driver: "claude-sdk",
|
|
6285
|
+
max_turns: 200
|
|
6286
|
+
}
|
|
6287
|
+
},
|
|
6288
|
+
ai_resources: []
|
|
6289
|
+
})
|
|
6290
|
+
);
|
|
6291
|
+
created.push("skaile.yaml");
|
|
6292
|
+
}
|
|
6293
|
+
for (const dir of new Set(Object.values(DRIVER_TARGETS[backend].local))) {
|
|
6294
|
+
const full = path14__default.join(resolved, dir);
|
|
6295
|
+
if (!existsSync12(full)) {
|
|
6296
|
+
mkdirSync3(full, { recursive: true });
|
|
6297
|
+
created.push(`${dir}/`);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
if (opts.git) {
|
|
6301
|
+
const gitignorePath = path14__default.join(resolved, ".gitignore");
|
|
6302
|
+
const entries = ["node_modules/", ".skaile/sessions/", "*.log", ".env", ".env.local"];
|
|
6303
|
+
const existing = existsSync12(gitignorePath) ? readFileSync5(gitignorePath, "utf-8") : "";
|
|
6304
|
+
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
6305
|
+
const append = entries.filter((e) => !have.has(e));
|
|
6306
|
+
if (append.length > 0) {
|
|
6307
|
+
const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
6308
|
+
writeFileSync2(gitignorePath, existing + prefix + `${append.join("\n")}
|
|
6022
6309
|
`);
|
|
6023
|
-
|
|
6024
|
-
}
|
|
6025
|
-
if (!existsSync12(path15__default.join(resolved, ".git"))) {
|
|
6026
|
-
try {
|
|
6027
|
-
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
6028
|
-
created.push(".git/");
|
|
6029
|
-
} catch (err) {
|
|
6030
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
6031
|
-
console.log(` ${S.dim(`\u26A0 git init failed: ${msg}`)}`);
|
|
6032
|
-
}
|
|
6033
|
-
}
|
|
6310
|
+
if (!existing) created.push(".gitignore");
|
|
6034
6311
|
}
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
const
|
|
6041
|
-
|
|
6042
|
-
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
6043
|
-
});
|
|
6044
|
-
console.log(` ${S.dim(`\u2713 wrote default user config at ${userCfgPath}`)}`);
|
|
6312
|
+
if (!existsSync12(path14__default.join(resolved, ".git"))) {
|
|
6313
|
+
try {
|
|
6314
|
+
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
6315
|
+
created.push(".git/");
|
|
6316
|
+
} catch (err) {
|
|
6317
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6318
|
+
console.log(` ${S.dim(`\u26A0 git init failed: ${msg}`)}`);
|
|
6045
6319
|
}
|
|
6046
|
-
} catch (err) {
|
|
6047
|
-
console.log(
|
|
6048
|
-
` ${S.dim(`\u26A0 could not bootstrap user config: ${err instanceof Error ? err.message : String(err)}`)}`
|
|
6049
|
-
);
|
|
6050
6320
|
}
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6321
|
+
}
|
|
6322
|
+
try {
|
|
6323
|
+
const fs11 = await import('fs');
|
|
6324
|
+
const { userConfigPath, saveConfig, getConfigDefaults } = await import('../library/index.js');
|
|
6325
|
+
const userCfgPath = userConfigPath();
|
|
6326
|
+
if (!fs11.existsSync(userCfgPath)) {
|
|
6327
|
+
const defaults = getConfigDefaults();
|
|
6328
|
+
saveConfig(userCfgPath, {
|
|
6329
|
+
catalog: { url: defaults.catalog.url, cache_ttl: defaults.catalog.cache_ttl }
|
|
6330
|
+
});
|
|
6331
|
+
console.log(` ${S.dim(`\u2713 wrote default user config at ${userCfgPath}`)}`);
|
|
6061
6332
|
}
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6333
|
+
} catch (err) {
|
|
6334
|
+
console.log(
|
|
6335
|
+
` ${S.dim(`\u26A0 could not bootstrap user config: ${err instanceof Error ? err.message : String(err)}`)}`
|
|
6336
|
+
);
|
|
6337
|
+
}
|
|
6338
|
+
try {
|
|
6339
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-COGVKY44.js');
|
|
6340
|
+
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
6341
|
+
for (const n of hydrate.cloned) created.push(`~/.skaile/sources/${n}/`);
|
|
6342
|
+
if (hydrate.failed.length > 0) {
|
|
6343
|
+
logErr(`Failed to clone source(s): ${hydrate.failed.join(", ")}`);
|
|
6344
|
+
}
|
|
6345
|
+
} catch (err) {
|
|
6346
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6347
|
+
console.log(` ${S.dim(`\u26A0 source hydration skipped: ${msg}`)}`);
|
|
6348
|
+
}
|
|
6349
|
+
for (const c of created) console.log(` ${S.dim(`+ ${c}`)}`);
|
|
6350
|
+
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
6351
|
+
console.log();
|
|
6352
|
+
console.log(S.heading(" Next steps:"));
|
|
6353
|
+
const isCurrentDir = resolved === path14__default.resolve(".");
|
|
6354
|
+
let step = 1;
|
|
6355
|
+
if (!isCurrentDir) {
|
|
6356
|
+
console.log(` ${S.dim(`${step}.`)} ${S.cmd(`cd ${projectDir}`)}`);
|
|
6073
6357
|
step++;
|
|
6074
|
-
console.log(` ${S.dim(`${step}.`)} ${S.cmd("skaile install")}`);
|
|
6075
|
-
console.log();
|
|
6076
6358
|
}
|
|
6077
|
-
);
|
|
6359
|
+
console.log(` ${S.dim(`${step}.`)} Edit ${S.cmd("skaile.yaml")} to add dependencies`);
|
|
6360
|
+
step++;
|
|
6361
|
+
console.log(` ${S.dim(`${step}.`)} ${S.cmd("skaile install")}`);
|
|
6362
|
+
console.log();
|
|
6363
|
+
});
|
|
6078
6364
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
6079
|
-
const { cmdSetup } = await import('../setup-
|
|
6365
|
+
const { cmdSetup } = await import('../setup-ACMP3QZC.js');
|
|
6080
6366
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
6081
6367
|
});
|
|
6082
6368
|
program.addCommand(makeInstallCommand());
|
|
@@ -6105,7 +6391,9 @@ program.addCommand(makeReplCommand());
|
|
|
6105
6391
|
program.addCommand(makeResumeCommand());
|
|
6106
6392
|
program.addCommand(makeServeCommand());
|
|
6107
6393
|
program.addCommand(makeMcpServerCommand());
|
|
6394
|
+
program.addCommand(makeIntegrationCommand());
|
|
6108
6395
|
program.addCommand(makePluginCommand());
|
|
6396
|
+
program.addCommand(makeDeployCommand());
|
|
6109
6397
|
program.addCommand(makeDebugCommand());
|
|
6110
6398
|
program.addCommand(makeConnectCommand());
|
|
6111
6399
|
program.addCommand(makeLogsCommand());
|