@skaile/workspaces 0.15.0 → 0.16.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 +53 -0
- package/dist/asset-feeds-L4ROBIAZ.js +90 -0
- package/dist/asset-feeds-L4ROBIAZ.js.map +1 -0
- package/dist/asset-manager/index.js +5 -5
- package/dist/asset-manager/installer.js +4 -4
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/asset-manager/src/installer.d.ts.map +1 -1
- package/dist/base-assets/connectors/deploy.js +5 -5
- package/dist/base-assets/connectors/devserver.js +5 -5
- package/dist/base-assets/connectors/flow/adapter.js +5 -5
- package/dist/base-assets/connectors/flow/run-flow.js +6 -6
- package/dist/base-assets/connectors/flow.js +5 -5
- package/dist/base-assets/connectors/git.js +5 -5
- package/dist/base-assets/connectors/gmail.js +5 -5
- package/dist/base-assets/connectors/googledrive.js +5 -5
- package/dist/base-assets/connectors/local.js +5 -5
- package/dist/base-assets/connectors/mattermost.js +5 -5
- package/dist/base-assets/connectors/memory.js +5 -5
- package/dist/base-assets/connectors/minio.js +5 -5
- package/dist/base-assets/connectors/postgres.js +5 -5
- package/dist/base-assets/connectors/redis.js +5 -5
- package/dist/base-assets/connectors/s3.js +5 -5
- package/dist/base-assets/connectors/sharepoint.js +5 -5
- package/dist/base-assets/connectors/sqlite.js +5 -5
- package/dist/base-assets/connectors/static-server.js +5 -5
- package/dist/base-assets/connectors/tunnel.js +5 -5
- package/dist/base-assets/connectors/webdav.js +5 -5
- package/dist/base-assets/connectors/xstate-store.js +5 -5
- package/dist/base-assets/connectors/xstate.js +5 -5
- package/dist/base-assets/connectors/yjs.js +5 -5
- package/dist/{chunk-SVNFQSU3.js → chunk-3DS5VIQP.js} +3 -3
- package/dist/{chunk-SVNFQSU3.js.map → chunk-3DS5VIQP.js.map} +1 -1
- package/dist/{chunk-4GEVGRWB.js → chunk-42YLNYFK.js} +11 -13
- package/dist/chunk-42YLNYFK.js.map +1 -0
- package/dist/{chunk-4RUVG5GX.js → chunk-4BRSVK7Q.js} +46 -3
- package/dist/chunk-4BRSVK7Q.js.map +1 -0
- package/dist/{chunk-Z24KPZKU.js → chunk-75M5W7FX.js} +8 -8
- package/dist/{chunk-Z24KPZKU.js.map → chunk-75M5W7FX.js.map} +1 -1
- package/dist/{chunk-SO43XRWF.js → chunk-ALJM24WL.js} +5 -5
- package/dist/{chunk-SO43XRWF.js.map → chunk-ALJM24WL.js.map} +1 -1
- package/dist/{chunk-2NIOMFSQ.js → chunk-FNCYNUGS.js} +78 -81
- package/dist/chunk-FNCYNUGS.js.map +1 -0
- package/dist/{chunk-6EN5IJ2Y.js → chunk-IY4X7PZN.js} +3 -3
- package/dist/{chunk-6EN5IJ2Y.js.map → chunk-IY4X7PZN.js.map} +1 -1
- package/dist/{chunk-W75ASXH4.js → chunk-KJ2LLWRF.js} +3 -3
- package/dist/{chunk-W75ASXH4.js.map → chunk-KJ2LLWRF.js.map} +1 -1
- package/dist/{chunk-6DEGWPAR.js → chunk-SMFZFFIZ.js} +3 -3
- package/dist/{chunk-6DEGWPAR.js.map → chunk-SMFZFFIZ.js.map} +1 -1
- package/dist/{chunk-GAZINYCS.js → chunk-SOQMVRQL.js} +19 -3
- package/dist/chunk-SOQMVRQL.js.map +1 -0
- package/dist/{chunk-7R4WLTZW.js → chunk-YMMWP3YL.js} +29 -19
- package/dist/chunk-YMMWP3YL.js.map +1 -0
- package/dist/{chunk-HSOEX3TA.js → chunk-YW36VEVN.js} +4 -4
- package/dist/{chunk-HSOEX3TA.js.map → chunk-YW36VEVN.js.map} +1 -1
- package/dist/{chunk-G7O7WDXX.js → chunk-ZUQXHBEH.js} +2 -2
- package/dist/{chunk-G7O7WDXX.js.map → chunk-ZUQXHBEH.js.map} +1 -1
- package/dist/cli/index.js +376 -207
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/asset-feeds.d.ts +42 -0
- package/dist/cli/src/asset-feeds.d.ts.map +1 -0
- package/dist/cli/src/commands/manage.d.ts +31 -20
- package/dist/cli/src/commands/manage.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts +6 -4
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/ensure-sources.d.ts +25 -0
- package/dist/cli/src/ensure-sources.d.ts.map +1 -0
- package/dist/connectors/config.js +4 -4
- package/dist/connectors/index.js +5 -5
- package/dist/core/index.js +3 -3
- package/dist/core/runtime-assets.js +2 -2
- package/dist/core/src/index.d.ts +1 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +27 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts +10 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +1 -1
- package/dist/ensure-sources-V26CZNJF.js +68 -0
- package/dist/ensure-sources-V26CZNJF.js.map +1 -0
- package/dist/library/index.js +1 -1
- package/dist/library/src/local/db.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts.map +1 -1
- package/dist/{open-library-XD7QYLMW.js → open-library-T6RXQJTQ.js} +4 -4
- package/dist/{open-library-XD7QYLMW.js.map → open-library-T6RXQJTQ.js.map} +1 -1
- package/dist/runner/index.js +7 -7
- package/dist/sdk/asset-manager.js +5 -5
- package/dist/sdk/core.js +3 -3
- package/dist/sdk/index.js +7 -7
- package/dist/sdk/runner.js +7 -7
- package/dist/{setup-WZFCLQ2J.js → setup-R6VWIPLL.js} +5 -5
- package/dist/{setup-WZFCLQ2J.js.map → setup-R6VWIPLL.js.map} +1 -1
- package/dist/{store-client-BM3IBDPT.js → store-client-FLD3XUY7.js} +6 -6
- package/dist/{store-client-BM3IBDPT.js.map → store-client-FLD3XUY7.js.map} +1 -1
- package/dist/tui/index.js +7 -7
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2NIOMFSQ.js.map +0 -1
- package/dist/chunk-4GEVGRWB.js.map +0 -1
- package/dist/chunk-4RUVG5GX.js.map +0 -1
- package/dist/chunk-7R4WLTZW.js.map +0 -1
- package/dist/chunk-GAZINYCS.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-
|
|
2
|
+
import { openCatalogSource, openLibrary, createFullRegistry, openLibraryManager } from '../chunk-IY4X7PZN.js';
|
|
3
3
|
import { logErr, S, logOk, colorRef, logInfo, logWarn, kindColorPad, kindColor, formatRelativeTime } from '../chunk-4NDWKA64.js';
|
|
4
|
-
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-
|
|
4
|
+
import { getStoreConfig, storeFetch, saveStoreTokens, clearStoreTokens, isStoreAuthenticated } from '../chunk-SMFZFFIZ.js';
|
|
5
5
|
import { AI_RESOURCES } from '../chunk-2M3XTMOL.js';
|
|
6
6
|
import { LocalSecretsProvider } from '../chunk-JDX54X4Y.js';
|
|
7
|
-
import { resolveLibraryDir, skaileHomeDir } from '../chunk-
|
|
7
|
+
import { resolveLibraryDir, LocalCatalogSource, skaileHomeDir } from '../chunk-FNCYNUGS.js';
|
|
8
8
|
import '../chunk-R7FOF242.js';
|
|
9
9
|
import '../chunk-GKIA2PU5.js';
|
|
10
10
|
import '../chunk-OKRUTSG7.js';
|
|
11
|
-
import { runFlow, resumeFlow } from '../chunk-
|
|
11
|
+
import { runFlow, resumeFlow } from '../chunk-ALJM24WL.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-75M5W7FX.js';
|
|
15
|
+
import { buildClaudePluginFiles } from '../chunk-ZUQXHBEH.js';
|
|
16
16
|
import '../chunk-X5YPJV4N.js';
|
|
17
17
|
import '../chunk-O7SG5PC2.js';
|
|
18
18
|
import '../chunk-W2O5LWYU.js';
|
|
@@ -25,22 +25,22 @@ import '../chunk-DQWREFRQ.js';
|
|
|
25
25
|
import '../chunk-KOVLSBXK.js';
|
|
26
26
|
import '../chunk-RRVQAE5D.js';
|
|
27
27
|
import '../chunk-4ACWI5YT.js';
|
|
28
|
-
import '../chunk-
|
|
29
|
-
import '../chunk-
|
|
28
|
+
import '../chunk-YW36VEVN.js';
|
|
29
|
+
import '../chunk-KJ2LLWRF.js';
|
|
30
30
|
import '../chunk-6MB7CRME.js';
|
|
31
31
|
import '../chunk-QAVZOJCV.js';
|
|
32
32
|
import { loadAllFlows } from '../chunk-ICS76R4T.js';
|
|
33
33
|
import '../chunk-GZWJGNNN.js';
|
|
34
34
|
import '../chunk-FVTV7M76.js';
|
|
35
|
-
import { AssetManager } from '../chunk-
|
|
36
|
-
import '../chunk-
|
|
37
|
-
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync } from '../chunk-
|
|
35
|
+
import { AssetManager } from '../chunk-YMMWP3YL.js';
|
|
36
|
+
import '../chunk-42YLNYFK.js';
|
|
37
|
+
import { readLock, resolveSettings, globalSettingsPath, projectSettingsPath, loadSettings, saveSettings, portableSpawn, portableSpawnSync, WorkspaceYamlEditor } from '../chunk-4BRSVK7Q.js';
|
|
38
38
|
import '../chunk-JKNWJ64A.js';
|
|
39
39
|
import { SUPPORTED_DRIVER_TARGETS } from '../chunk-O4JH3KUE.js';
|
|
40
40
|
import { DRIVER_DEFAULTS } from '../chunk-K5GBV4SA.js';
|
|
41
41
|
import '../chunk-KLNL7QHN.js';
|
|
42
|
-
import '../chunk-
|
|
43
|
-
import { resolveSkWorkspaceConfig, resolveAgentDir } from '../chunk-
|
|
42
|
+
import '../chunk-3DS5VIQP.js';
|
|
43
|
+
import { resolveSkWorkspaceConfig, resolveAgentDir, findWorkspaceRoot, workspaceConfigFilename } from '../chunk-SOQMVRQL.js';
|
|
44
44
|
import '../chunk-ZHLRRT5D.js';
|
|
45
45
|
import { ASSET_KINDS } from '../chunk-37JKX6D7.js';
|
|
46
46
|
import { openSqlite } from '../chunk-24UIWON4.js';
|
|
@@ -52,7 +52,7 @@ import '../chunk-CGYEHQOX.js';
|
|
|
52
52
|
import '../chunk-LV2HPH3C.js';
|
|
53
53
|
import '../chunk-NSBPE2FW.js';
|
|
54
54
|
import * as fs10 from 'fs';
|
|
55
|
-
import fs10__default, { readFileSync, existsSync, writeFileSync, statSync } from 'fs';
|
|
55
|
+
import fs10__default, { readFileSync, existsSync, writeFileSync, rmSync, statSync } from 'fs';
|
|
56
56
|
import * as path15 from 'path';
|
|
57
57
|
import path15__default, { resolve, join } from 'path';
|
|
58
58
|
import { fileURLToPath } from 'url';
|
|
@@ -308,7 +308,7 @@ function makeSearchCommand() {
|
|
|
308
308
|
}
|
|
309
309
|
if (showStore) {
|
|
310
310
|
try {
|
|
311
|
-
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-
|
|
311
|
+
const { getStoreConfig: getStoreConfig2, storeFetch: storeFetch2 } = await import('../store-client-FLD3XUY7.js');
|
|
312
312
|
const config = getStoreConfig2();
|
|
313
313
|
const params = {};
|
|
314
314
|
if (query) params.q = query;
|
|
@@ -470,7 +470,7 @@ function makeCatalogCommand() {
|
|
|
470
470
|
const cfg = resolveConfig({ projectDir });
|
|
471
471
|
const baseUrl = opts.url ?? cfg.catalog.url;
|
|
472
472
|
if (isLocalCatalogUrl(baseUrl)) {
|
|
473
|
-
const { resolveCatalogSource } = await import('../open-library-
|
|
473
|
+
const { resolveCatalogSource } = await import('../open-library-T6RXQJTQ.js');
|
|
474
474
|
let resolved;
|
|
475
475
|
try {
|
|
476
476
|
resolved = await resolveCatalogSource({ projectDir: opts.projectDir });
|
|
@@ -1082,7 +1082,7 @@ function makeConnectorCommand() {
|
|
|
1082
1082
|
cmd.command("add <driver>").option("--id <id>", "Connector instance ID (defaults to driver name)").option("--access <level>", "Access level: read-only | read-write", "read-only").option("--no-install", "Skip npm dependency installation").option("--project-dir <path>", "Workspace directory", process.cwd()).description("Add a connector to skaile.yaml and install its npm deps").action(
|
|
1083
1083
|
async (driver, opts) => {
|
|
1084
1084
|
const { installNpmPackages } = await import('../connectors/index.js');
|
|
1085
|
-
const { scanDirectory, resolveBaseAssetsRoot, WorkspaceYamlEditor } = await import('../core/index.js');
|
|
1085
|
+
const { scanDirectory, resolveBaseAssetsRoot, WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1086
1086
|
const projectDir = path15__default.resolve(opts.projectDir);
|
|
1087
1087
|
const yamlPath = path15__default.join(projectDir, "skaile.yaml");
|
|
1088
1088
|
if (!existsSync(yamlPath)) {
|
|
@@ -1132,7 +1132,7 @@ ${installResult.output}`);
|
|
|
1132
1132
|
` \u26A0 Skipping install. Add manually: bun add --optional ${allDeps.join(" ")}`
|
|
1133
1133
|
);
|
|
1134
1134
|
}
|
|
1135
|
-
const editor =
|
|
1135
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
1136
1136
|
editor.setConnector({
|
|
1137
1137
|
id,
|
|
1138
1138
|
driver,
|
|
@@ -1146,14 +1146,14 @@ ${installResult.output}`);
|
|
|
1146
1146
|
}
|
|
1147
1147
|
);
|
|
1148
1148
|
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
|
-
const { WorkspaceYamlEditor } = await import('../core/index.js');
|
|
1149
|
+
const { WorkspaceYamlEditor: WorkspaceYamlEditor2 } = await import('../core/index.js');
|
|
1150
1150
|
const projectDir = path15__default.resolve(opts.projectDir);
|
|
1151
1151
|
const yamlPath = path15__default.join(projectDir, "skaile.yaml");
|
|
1152
1152
|
if (!existsSync(yamlPath)) {
|
|
1153
1153
|
logErr("No skaile.yaml found in current directory.");
|
|
1154
1154
|
process.exit(1);
|
|
1155
1155
|
}
|
|
1156
|
-
const editor =
|
|
1156
|
+
const editor = WorkspaceYamlEditor2.load(yamlPath);
|
|
1157
1157
|
const removed = editor.removeConnector(id);
|
|
1158
1158
|
if (!removed) {
|
|
1159
1159
|
logErr(`No connector with id '${id}' found in skaile.yaml.`);
|
|
@@ -2022,42 +2022,43 @@ function makeLogsCommand() {
|
|
|
2022
2022
|
}
|
|
2023
2023
|
var am;
|
|
2024
2024
|
var state = {
|
|
2025
|
-
tab: "
|
|
2025
|
+
tab: "assets",
|
|
2026
2026
|
cursor: 0,
|
|
2027
2027
|
assetRows: [],
|
|
2028
|
+
sourceRows: [],
|
|
2028
2029
|
libraryRows: [],
|
|
2029
2030
|
visibleRows: [],
|
|
2030
2031
|
pendingAdds: /* @__PURE__ */ new Set(),
|
|
2031
2032
|
pendingRemoves: /* @__PURE__ */ new Set(),
|
|
2032
|
-
|
|
2033
|
+
collapsedSources: /* @__PURE__ */ new Set(),
|
|
2033
2034
|
collapsedDomains: /* @__PURE__ */ new Set(),
|
|
2034
2035
|
message: "",
|
|
2035
2036
|
cols: 80,
|
|
2036
2037
|
awaitingExitConfirm: false
|
|
2037
2038
|
};
|
|
2038
|
-
function buildVisibleRows(rows,
|
|
2039
|
+
function buildVisibleRows(rows, collapsedSources, collapsedDomains) {
|
|
2039
2040
|
return rows.filter((row) => {
|
|
2040
|
-
if (row.type === "
|
|
2041
|
-
if (row.type === "header") return !
|
|
2042
|
-
const
|
|
2041
|
+
if (row.type === "source-header") return true;
|
|
2042
|
+
if (row.type === "header") return !collapsedSources.has(row.source);
|
|
2043
|
+
const source = row.entry?.repository ?? "other";
|
|
2043
2044
|
const domain = row.entry?.domain ?? "other";
|
|
2044
|
-
return !
|
|
2045
|
+
return !collapsedSources.has(source) && !collapsedDomains.has(`${source}:${domain}`);
|
|
2045
2046
|
});
|
|
2046
2047
|
}
|
|
2047
|
-
function domainAssetRefs(rows,
|
|
2048
|
-
return rows.filter((r) => isAsset(r) && inDomain(r,
|
|
2048
|
+
function domainAssetRefs(rows, source, domain) {
|
|
2049
|
+
return rows.filter((r) => isAsset(r) && inDomain(r, source, domain)).map((r) => assetRefOf(r));
|
|
2049
2050
|
}
|
|
2050
|
-
function
|
|
2051
|
-
return rows.filter((r) => isAsset(r) &&
|
|
2051
|
+
function sourceAssetRefs(rows, source) {
|
|
2052
|
+
return rows.filter((r) => isAsset(r) && inSource(r, source)).map((r) => assetRefOf(r));
|
|
2052
2053
|
}
|
|
2053
2054
|
function isAsset(r) {
|
|
2054
2055
|
return r.type === "asset";
|
|
2055
2056
|
}
|
|
2056
|
-
function
|
|
2057
|
-
return (r.entry?.repository ?? "other") ===
|
|
2057
|
+
function inSource(r, source) {
|
|
2058
|
+
return (r.entry?.repository ?? "other") === source;
|
|
2058
2059
|
}
|
|
2059
|
-
function inDomain(r,
|
|
2060
|
-
return
|
|
2060
|
+
function inDomain(r, source, domain) {
|
|
2061
|
+
return inSource(r, source) && (r.entry?.domain ?? "other") === domain;
|
|
2061
2062
|
}
|
|
2062
2063
|
function assetRefOf(r) {
|
|
2063
2064
|
if (!isAsset(r) || !r.entry) return null;
|
|
@@ -2081,17 +2082,17 @@ function setSelection(ref, action) {
|
|
|
2081
2082
|
state.pendingRemoves.delete(ref);
|
|
2082
2083
|
return;
|
|
2083
2084
|
}
|
|
2084
|
-
resolved = row.
|
|
2085
|
+
resolved = row.installed ? "remove" : "add";
|
|
2085
2086
|
} else {
|
|
2086
2087
|
resolved = action;
|
|
2087
2088
|
}
|
|
2088
2089
|
if (resolved === "add") {
|
|
2089
2090
|
state.pendingRemoves.delete(ref);
|
|
2090
|
-
if (row.
|
|
2091
|
+
if (row.installed) return;
|
|
2091
2092
|
state.pendingAdds.add(ref);
|
|
2092
2093
|
} else {
|
|
2093
2094
|
state.pendingAdds.delete(ref);
|
|
2094
|
-
if (!row.
|
|
2095
|
+
if (!row.installed) return;
|
|
2095
2096
|
state.pendingRemoves.add(ref);
|
|
2096
2097
|
}
|
|
2097
2098
|
}
|
|
@@ -2099,51 +2100,57 @@ function bulkSelection(refs, action) {
|
|
|
2099
2100
|
for (const ref of refs) setSelection(ref, action);
|
|
2100
2101
|
}
|
|
2101
2102
|
function actOnHeader(row, action) {
|
|
2102
|
-
if (row.type === "
|
|
2103
|
-
bulkSelection(
|
|
2103
|
+
if (row.type === "source-header") {
|
|
2104
|
+
bulkSelection(sourceAssetRefs(state.assetRows, row.source), action);
|
|
2104
2105
|
return true;
|
|
2105
2106
|
}
|
|
2106
2107
|
if (row.type === "header") {
|
|
2107
|
-
bulkSelection(domainAssetRefs(state.assetRows, row.
|
|
2108
|
+
bulkSelection(domainAssetRefs(state.assetRows, row.source, row.domain), action);
|
|
2108
2109
|
return true;
|
|
2109
2110
|
}
|
|
2110
2111
|
return false;
|
|
2111
2112
|
}
|
|
2112
|
-
function loadAssets() {
|
|
2113
|
-
const
|
|
2114
|
-
const
|
|
2115
|
-
|
|
2113
|
+
async function loadAssets() {
|
|
2114
|
+
const { gatherAssetFeeds } = await import('../asset-feeds-L4ROBIAZ.js');
|
|
2115
|
+
const { entries, notes } = await gatherAssetFeeds(am, am.projectDir);
|
|
2116
|
+
if (notes.length > 0) {
|
|
2117
|
+
state.message = notes.map((n) => `[${n.feed}] ${n.message}`).join(" \u2022 ");
|
|
2118
|
+
}
|
|
2119
|
+
const installed = new Set(am.listDeployed().map((e) => `${e.kind}:${e.name}`));
|
|
2120
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
2116
2121
|
for (const e of entries) {
|
|
2117
|
-
const
|
|
2122
|
+
const source = e.repository ?? "other";
|
|
2118
2123
|
const domain = e.domain ?? "other";
|
|
2119
|
-
if (!
|
|
2120
|
-
const domainMap =
|
|
2124
|
+
if (!bySource.has(source)) bySource.set(source, /* @__PURE__ */ new Map());
|
|
2125
|
+
const domainMap = bySource.get(source);
|
|
2121
2126
|
if (!domainMap.has(domain)) domainMap.set(domain, []);
|
|
2122
2127
|
domainMap.get(domain).push(e);
|
|
2123
2128
|
}
|
|
2124
2129
|
const rows = [];
|
|
2125
|
-
for (const [
|
|
2126
|
-
|
|
2130
|
+
for (const [source, domainMap] of [...bySource.entries()].sort(
|
|
2131
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
2132
|
+
)) {
|
|
2133
|
+
rows.push({ type: "source-header", source });
|
|
2127
2134
|
for (const [domain, items] of [...domainMap.entries()].sort(
|
|
2128
2135
|
(a, b) => a[0].localeCompare(b[0])
|
|
2129
2136
|
)) {
|
|
2130
|
-
rows.push({ type: "header",
|
|
2137
|
+
rows.push({ type: "header", source, domain });
|
|
2131
2138
|
items.sort(
|
|
2132
2139
|
(a, b) => a.kind !== b.kind ? a.kind.localeCompare(b.kind) : a.name.localeCompare(b.name)
|
|
2133
2140
|
);
|
|
2134
2141
|
for (const entry of items) {
|
|
2135
2142
|
const ref = `${entry.kind}:${entry.name}`;
|
|
2136
|
-
rows.push({ type: "asset", entry,
|
|
2143
|
+
rows.push({ type: "asset", entry, installed: installed.has(ref) });
|
|
2137
2144
|
}
|
|
2138
2145
|
}
|
|
2139
2146
|
}
|
|
2140
2147
|
state.assetRows = rows;
|
|
2141
|
-
const
|
|
2142
|
-
for (const
|
|
2143
|
-
if (!
|
|
2148
|
+
const newSources = new Set(rows.filter((r) => r.type === "source-header").map((r) => r.source));
|
|
2149
|
+
for (const s of state.collapsedSources) {
|
|
2150
|
+
if (!newSources.has(s)) state.collapsedSources.delete(s);
|
|
2144
2151
|
}
|
|
2145
2152
|
const newDomainKeys = new Set(
|
|
2146
|
-
rows.filter((r) => r.type === "header").map((r) => `${r.
|
|
2153
|
+
rows.filter((r) => r.type === "header").map((r) => `${r.source}:${r.domain}`)
|
|
2147
2154
|
);
|
|
2148
2155
|
for (const d of state.collapsedDomains) {
|
|
2149
2156
|
if (!newDomainKeys.has(d)) state.collapsedDomains.delete(d);
|
|
@@ -2151,11 +2158,16 @@ function loadAssets() {
|
|
|
2151
2158
|
for (const d of newDomainKeys) state.collapsedDomains.add(d);
|
|
2152
2159
|
rebuildVisible();
|
|
2153
2160
|
}
|
|
2154
|
-
async function
|
|
2161
|
+
async function loadSourcesAndLibraries() {
|
|
2155
2162
|
try {
|
|
2156
|
-
const { openLibraryManager: openLibraryManager2 } = await
|
|
2163
|
+
const [{ openLibraryManager: openLibraryManager2 }, { skaileHomeDir: skaileHomeDir2 }] = await Promise.all([
|
|
2164
|
+
import('../open-library-T6RXQJTQ.js'),
|
|
2165
|
+
import('../library/index.js')
|
|
2166
|
+
]);
|
|
2157
2167
|
const { manager, library, close } = await openLibraryManager2();
|
|
2158
2168
|
try {
|
|
2169
|
+
const sourcesDir2 = path15__default.join(skaileHomeDir2(), "sources");
|
|
2170
|
+
const isSourceRow = (l) => l.path.startsWith(sourcesDir2);
|
|
2159
2171
|
const libs = await manager.listLibraries();
|
|
2160
2172
|
const defs = await library.listAssetDefs();
|
|
2161
2173
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -2163,7 +2175,13 @@ async function loadLibraries() {
|
|
|
2163
2175
|
const id = d.libraryId ?? "";
|
|
2164
2176
|
counts.set(id, (counts.get(id) ?? 0) + 1);
|
|
2165
2177
|
}
|
|
2166
|
-
state.
|
|
2178
|
+
state.sourceRows = libs.filter(isSourceRow).map((l) => ({
|
|
2179
|
+
name: l.name,
|
|
2180
|
+
path: l.path,
|
|
2181
|
+
ownership: l.ownership,
|
|
2182
|
+
assetCount: counts.get(l.id) ?? 0
|
|
2183
|
+
}));
|
|
2184
|
+
state.libraryRows = libs.filter((l) => !isSourceRow(l)).map((l) => ({
|
|
2167
2185
|
name: l.name,
|
|
2168
2186
|
backend: l.backend,
|
|
2169
2187
|
ownership: l.ownership,
|
|
@@ -2174,13 +2192,14 @@ async function loadLibraries() {
|
|
|
2174
2192
|
close();
|
|
2175
2193
|
}
|
|
2176
2194
|
} catch {
|
|
2195
|
+
state.sourceRows = [];
|
|
2177
2196
|
state.libraryRows = [];
|
|
2178
2197
|
}
|
|
2179
2198
|
}
|
|
2180
2199
|
function rebuildVisible() {
|
|
2181
2200
|
state.visibleRows = buildVisibleRows(
|
|
2182
2201
|
state.assetRows,
|
|
2183
|
-
state.
|
|
2202
|
+
state.collapsedSources,
|
|
2184
2203
|
state.collapsedDomains
|
|
2185
2204
|
);
|
|
2186
2205
|
clampCursor();
|
|
@@ -2195,19 +2214,11 @@ function moveCursor(delta) {
|
|
|
2195
2214
|
state.cursor = Math.max(0, Math.min(maxCursor(), state.cursor + delta));
|
|
2196
2215
|
}
|
|
2197
2216
|
function nextTab() {
|
|
2198
|
-
const order = ["
|
|
2217
|
+
const order = ["assets", "sources", "libraries", "pending", "sync"];
|
|
2199
2218
|
state.tab = order[(order.indexOf(state.tab) + 1) % order.length];
|
|
2200
2219
|
state.cursor = 0;
|
|
2201
2220
|
}
|
|
2202
2221
|
var TABS = {
|
|
2203
|
-
libraries: {
|
|
2204
|
-
label: "Libraries",
|
|
2205
|
-
rowCount: () => state.libraryRows.length,
|
|
2206
|
-
selectableCount: () => state.libraryRows.length,
|
|
2207
|
-
emptyMsg: " No libraries registered. Run `skaile library init <name>` or `skaile library add <git-url>` from the shell.",
|
|
2208
|
-
renderRow: (i, sel) => renderLibraryRow(state.libraryRows[i], sel),
|
|
2209
|
-
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile library \u2026` from the shell for CRUD)"
|
|
2210
|
-
},
|
|
2211
2222
|
assets: {
|
|
2212
2223
|
label: "Assets",
|
|
2213
2224
|
rowCount: () => state.visibleRows.length,
|
|
@@ -2215,6 +2226,22 @@ var TABS = {
|
|
|
2215
2226
|
renderRow: (i, sel) => renderAssetRow(state.visibleRows[i], sel),
|
|
2216
2227
|
footer: " \u2191\u2193/jk navigate \u2190/\u2192 collapse/expand [space/+/-] select [a/\u21B5] apply [i] info Tab switch [q/esc] quit"
|
|
2217
2228
|
},
|
|
2229
|
+
sources: {
|
|
2230
|
+
label: "Sources",
|
|
2231
|
+
rowCount: () => state.sourceRows.length,
|
|
2232
|
+
selectableCount: () => state.sourceRows.length,
|
|
2233
|
+
emptyMsg: " No sources registered. Run `skaile source add <git-url>` from the shell to track a github repo.",
|
|
2234
|
+
renderRow: (i, sel) => renderSourceRow(state.sourceRows[i], sel),
|
|
2235
|
+
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile source \u2026` from the shell for CRUD)"
|
|
2236
|
+
},
|
|
2237
|
+
libraries: {
|
|
2238
|
+
label: "Libraries",
|
|
2239
|
+
rowCount: () => state.libraryRows.length,
|
|
2240
|
+
selectableCount: () => state.libraryRows.length,
|
|
2241
|
+
emptyMsg: " No libraries registered. Run `skaile library init <name>` from the shell to author your own.",
|
|
2242
|
+
renderRow: (i, sel) => renderLibraryRow(state.libraryRows[i], sel),
|
|
2243
|
+
footer: " \u2191\u2193 navigate Tab switch q quit (use `skaile library \u2026` from the shell for CRUD)"
|
|
2244
|
+
},
|
|
2218
2245
|
pending: {
|
|
2219
2246
|
label: "Pending",
|
|
2220
2247
|
rowCount: () => 0,
|
|
@@ -2227,7 +2254,7 @@ var TABS = {
|
|
|
2227
2254
|
label: "Sync",
|
|
2228
2255
|
rowCount: () => 0,
|
|
2229
2256
|
selectableCount: () => 0,
|
|
2230
|
-
emptyMsg: " Press S to sync all libraries (rich rendering deferred to AF-LIB-TUI-RICH).",
|
|
2257
|
+
emptyMsg: " Press S to sync all sources + libraries (rich rendering deferred to AF-LIB-TUI-RICH).",
|
|
2231
2258
|
renderRow: () => "",
|
|
2232
2259
|
footer: " s sync all Tab switch q quit"
|
|
2233
2260
|
}
|
|
@@ -2264,13 +2291,13 @@ function groupStatus(refs) {
|
|
|
2264
2291
|
if (refs.length === 0) return pc5.dim("\xB7 ");
|
|
2265
2292
|
if (refs.some((r) => state.pendingAdds.has(r))) return pc5.blue("+ ");
|
|
2266
2293
|
if (refs.some((r) => state.pendingRemoves.has(r))) return pc5.red("- ");
|
|
2267
|
-
const
|
|
2268
|
-
return
|
|
2294
|
+
const allInstalled = refs.every((r) => findAssetRow(r)?.installed);
|
|
2295
|
+
return allInstalled ? pc5.green("\u2713 ") : pc5.dim("\xB7 ");
|
|
2269
2296
|
}
|
|
2270
2297
|
function renderHeaderLine(opts) {
|
|
2271
2298
|
const indicator = opts.collapsed ? "\u25B6" : "\u25BC";
|
|
2272
2299
|
const total = state.assetRows.filter(opts.match).length;
|
|
2273
|
-
const installed = state.assetRows.filter((r) => opts.match(r) && r.
|
|
2300
|
+
const installed = state.assetRows.filter((r) => opts.match(r) && r.installed).length;
|
|
2274
2301
|
const [add, remove] = pendingCountsFor(opts.match);
|
|
2275
2302
|
let count = String(installed);
|
|
2276
2303
|
if (add > 0) count += pc5.green(`+${add}`);
|
|
@@ -2281,22 +2308,22 @@ function renderHeaderLine(opts) {
|
|
|
2281
2308
|
return opts.selected ? pc5.bgWhite(pc5.black(`${line} `.padEnd(state.cols))) : line;
|
|
2282
2309
|
}
|
|
2283
2310
|
function renderAssetRow(row, selected) {
|
|
2284
|
-
if (row.type === "
|
|
2311
|
+
if (row.type === "source-header") {
|
|
2285
2312
|
return renderHeaderLine({
|
|
2286
2313
|
indent: " ",
|
|
2287
|
-
collapsed: state.
|
|
2288
|
-
match: (r) => isAsset(r) &&
|
|
2289
|
-
refs:
|
|
2290
|
-
label: pc5.bold(pc5.cyan(row.
|
|
2314
|
+
collapsed: state.collapsedSources.has(row.source),
|
|
2315
|
+
match: (r) => isAsset(r) && inSource(r, row.source),
|
|
2316
|
+
refs: sourceAssetRefs(state.assetRows, row.source),
|
|
2317
|
+
label: pc5.bold(pc5.cyan(row.source)),
|
|
2291
2318
|
selected
|
|
2292
2319
|
});
|
|
2293
2320
|
}
|
|
2294
2321
|
if (row.type === "header") {
|
|
2295
2322
|
return renderHeaderLine({
|
|
2296
2323
|
indent: " ",
|
|
2297
|
-
collapsed: state.collapsedDomains.has(`${row.
|
|
2298
|
-
match: (r) => isAsset(r) && inDomain(r, row.
|
|
2299
|
-
refs: domainAssetRefs(state.assetRows, row.
|
|
2324
|
+
collapsed: state.collapsedDomains.has(`${row.source}:${row.domain}`),
|
|
2325
|
+
match: (r) => isAsset(r) && inDomain(r, row.source, row.domain),
|
|
2326
|
+
refs: domainAssetRefs(state.assetRows, row.source, row.domain),
|
|
2300
2327
|
label: pc5.bold(row.domain),
|
|
2301
2328
|
selected
|
|
2302
2329
|
});
|
|
@@ -2306,7 +2333,7 @@ function renderAssetRow(row, selected) {
|
|
|
2306
2333
|
let status4;
|
|
2307
2334
|
if (state.pendingAdds.has(ref)) status4 = pc5.blue("+ ");
|
|
2308
2335
|
else if (state.pendingRemoves.has(ref)) status4 = pc5.red("- ");
|
|
2309
|
-
else if (row.
|
|
2336
|
+
else if (row.installed) status4 = pc5.green("\u2713 ");
|
|
2310
2337
|
else status4 = pc5.dim("\xB7 ");
|
|
2311
2338
|
const kind = kindColorPad(e.kind, 8);
|
|
2312
2339
|
const name = e.name.padEnd(30);
|
|
@@ -2314,6 +2341,10 @@ function renderAssetRow(row, selected) {
|
|
|
2314
2341
|
const line = ` ${status4} ${kind} ${name} ${pc5.dim(desc)}`;
|
|
2315
2342
|
return selected ? pc5.inverse(line.padEnd(state.cols)) : line;
|
|
2316
2343
|
}
|
|
2344
|
+
function renderSourceRow(row, selected) {
|
|
2345
|
+
const line = ` ${S.cmd(row.name.padEnd(20))} ${pc5.dim(row.ownership.padEnd(12))} ${pc5.dim(`${row.assetCount} assets`)} ${pc5.dim(row.path)}`;
|
|
2346
|
+
return selected ? pc5.inverse(line.padEnd(state.cols)) : line;
|
|
2347
|
+
}
|
|
2317
2348
|
function renderLibraryRow(row, selected) {
|
|
2318
2349
|
const mark = row.isDefault ? pc5.green("\u25B8") : " ";
|
|
2319
2350
|
const line = `${mark} ${S.cmd(row.name.padEnd(16))} ${pc5.dim(row.backend.padEnd(7))} ${pc5.dim(row.ownership.padEnd(12))} ${pc5.dim(`${row.assetCount} assets`)}`;
|
|
@@ -2390,20 +2421,25 @@ async function applyChanges() {
|
|
|
2390
2421
|
}
|
|
2391
2422
|
state.pendingAdds.clear();
|
|
2392
2423
|
state.pendingRemoves.clear();
|
|
2393
|
-
loadAssets();
|
|
2424
|
+
await loadAssets();
|
|
2394
2425
|
const parts = [];
|
|
2395
2426
|
if (added > 0) parts.push(pc5.green(`+${added} added`));
|
|
2396
2427
|
if (removed > 0) parts.push(pc5.red(`-${removed} removed`));
|
|
2397
2428
|
if (parts.length) state.message = parts.join(" ");
|
|
2398
2429
|
}
|
|
2399
|
-
async function
|
|
2430
|
+
async function syncAll() {
|
|
2400
2431
|
state.message = pc5.yellow(
|
|
2401
|
-
"
|
|
2432
|
+
"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."
|
|
2402
2433
|
);
|
|
2403
2434
|
}
|
|
2404
|
-
function
|
|
2435
|
+
function sourceShellHint(action) {
|
|
2405
2436
|
state.message = pc5.yellow(
|
|
2406
|
-
`${action} is a shell command
|
|
2437
|
+
`${action} is a shell command. Run \`skaile source \u2026\` from the shell.`
|
|
2438
|
+
);
|
|
2439
|
+
}
|
|
2440
|
+
function libraryShellHint(action) {
|
|
2441
|
+
state.message = pc5.yellow(
|
|
2442
|
+
`${action} is a shell command. Run \`skaile library \u2026\` from the shell.`
|
|
2407
2443
|
);
|
|
2408
2444
|
}
|
|
2409
2445
|
async function showInfo() {
|
|
@@ -2417,9 +2453,9 @@ async function showInfo() {
|
|
|
2417
2453
|
console.log(` ${S.rule(50)}`);
|
|
2418
2454
|
if (e.version) console.log(` version: ${e.version}`);
|
|
2419
2455
|
if (e.description) console.log(` description: ${e.description}`);
|
|
2420
|
-
if (e.repository) console.log(`
|
|
2421
|
-
console.log(`
|
|
2422
|
-
console.log(`
|
|
2456
|
+
if (e.repository) console.log(` source: ${pc5.dim(e.repository)}`);
|
|
2457
|
+
console.log(` manifest: ${pc5.dim(e.source)}`);
|
|
2458
|
+
console.log(` installed: ${row.installed ? pc5.green("yes") : pc5.red("no")}`);
|
|
2423
2459
|
if (e.requires.length) {
|
|
2424
2460
|
console.log(` requires:`);
|
|
2425
2461
|
for (const d of e.requires) console.log(` ${kindColor(d.kind)}:${d.name}`);
|
|
@@ -2441,11 +2477,11 @@ async function showInfo() {
|
|
|
2441
2477
|
function expandUnderCursor() {
|
|
2442
2478
|
const row = state.visibleRows[state.cursor];
|
|
2443
2479
|
if (!row) return;
|
|
2444
|
-
if (row.type === "
|
|
2445
|
-
state.
|
|
2480
|
+
if (row.type === "source-header" && state.collapsedSources.has(row.source)) {
|
|
2481
|
+
state.collapsedSources.delete(row.source);
|
|
2446
2482
|
rebuildVisible();
|
|
2447
2483
|
} else if (row.type === "header") {
|
|
2448
|
-
const dk = `${row.
|
|
2484
|
+
const dk = `${row.source}:${row.domain}`;
|
|
2449
2485
|
if (state.collapsedDomains.has(dk)) {
|
|
2450
2486
|
state.collapsedDomains.delete(dk);
|
|
2451
2487
|
rebuildVisible();
|
|
@@ -2455,15 +2491,15 @@ function expandUnderCursor() {
|
|
|
2455
2491
|
function collapseOrJumpUnderCursor() {
|
|
2456
2492
|
const row = state.visibleRows[state.cursor];
|
|
2457
2493
|
if (!row) return;
|
|
2458
|
-
if (row.type === "
|
|
2459
|
-
if (!state.
|
|
2460
|
-
state.
|
|
2494
|
+
if (row.type === "source-header") {
|
|
2495
|
+
if (!state.collapsedSources.has(row.source)) {
|
|
2496
|
+
state.collapsedSources.add(row.source);
|
|
2461
2497
|
rebuildVisible();
|
|
2462
2498
|
}
|
|
2463
2499
|
return;
|
|
2464
2500
|
}
|
|
2465
2501
|
if (row.type === "header") {
|
|
2466
|
-
const dk = `${row.
|
|
2502
|
+
const dk = `${row.source}:${row.domain}`;
|
|
2467
2503
|
if (!state.collapsedDomains.has(dk)) {
|
|
2468
2504
|
state.collapsedDomains.add(dk);
|
|
2469
2505
|
rebuildVisible();
|
|
@@ -2471,7 +2507,7 @@ function collapseOrJumpUnderCursor() {
|
|
|
2471
2507
|
const idx2 = findLastIndex(
|
|
2472
2508
|
state.visibleRows,
|
|
2473
2509
|
state.cursor,
|
|
2474
|
-
(r) => r.type === "
|
|
2510
|
+
(r) => r.type === "source-header"
|
|
2475
2511
|
);
|
|
2476
2512
|
if (idx2 >= 0) state.cursor = idx2;
|
|
2477
2513
|
}
|
|
@@ -2480,7 +2516,7 @@ function collapseOrJumpUnderCursor() {
|
|
|
2480
2516
|
const idx = findLastIndex(
|
|
2481
2517
|
state.visibleRows,
|
|
2482
2518
|
state.cursor,
|
|
2483
|
-
(r) => r.type === "header" || r.type === "
|
|
2519
|
+
(r) => r.type === "header" || r.type === "source-header"
|
|
2484
2520
|
);
|
|
2485
2521
|
if (idx >= 0) state.cursor = idx;
|
|
2486
2522
|
}
|
|
@@ -2491,6 +2527,7 @@ function findLastIndex(arr, endExclusive, pred) {
|
|
|
2491
2527
|
return -1;
|
|
2492
2528
|
}
|
|
2493
2529
|
var TAB_ASSETS = (t) => t === "assets";
|
|
2530
|
+
var TAB_SOURCES = (t) => t === "sources";
|
|
2494
2531
|
var TAB_LIBRARIES = (t) => t === "libraries";
|
|
2495
2532
|
var KEYMAP = [
|
|
2496
2533
|
// Quit (with pending check) — handled here, not via a modal subroutine, so
|
|
@@ -2513,7 +2550,7 @@ var KEYMAP = [
|
|
|
2513
2550
|
// Collapse / expand — assets tab only
|
|
2514
2551
|
{ keys: ["\x1B[C"], when: TAB_ASSETS, run: expandUnderCursor },
|
|
2515
2552
|
{ keys: ["\x1B[D"], when: TAB_ASSETS, run: collapseOrJumpUnderCursor },
|
|
2516
|
-
// + : assets → bulk-add or single-add toggle
|
|
2553
|
+
// + : assets → bulk-add or single-add toggle
|
|
2517
2554
|
{
|
|
2518
2555
|
keys: ["+"],
|
|
2519
2556
|
when: TAB_ASSETS,
|
|
@@ -2526,9 +2563,28 @@ var KEYMAP = [
|
|
|
2526
2563
|
}
|
|
2527
2564
|
}
|
|
2528
2565
|
},
|
|
2529
|
-
//
|
|
2530
|
-
{ keys: ["+", "n"], when:
|
|
2531
|
-
|
|
2566
|
+
// Sources tab: +/-/n/r/x map to shell hints in the minimal scaffold.
|
|
2567
|
+
{ keys: ["+", "n", "a"], when: TAB_SOURCES, run: () => sourceShellHint("Adding a source") },
|
|
2568
|
+
{ keys: ["-", "r", "x"], when: TAB_SOURCES, run: () => sourceShellHint("Removing a source") },
|
|
2569
|
+
{ keys: ["\r", "\n"], when: TAB_SOURCES, run: () => sourceShellHint("Source actions") },
|
|
2570
|
+
// Libraries tab: +/-/n/r/x/d/enter map to shell hints in the minimal scaffold.
|
|
2571
|
+
{
|
|
2572
|
+
keys: ["+", "n", "a"],
|
|
2573
|
+
when: TAB_LIBRARIES,
|
|
2574
|
+
run: () => libraryShellHint("Adding a library")
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
keys: ["-", "r", "x"],
|
|
2578
|
+
when: TAB_LIBRARIES,
|
|
2579
|
+
run: () => libraryShellHint("Removing a library")
|
|
2580
|
+
},
|
|
2581
|
+
{
|
|
2582
|
+
keys: ["d"],
|
|
2583
|
+
when: TAB_LIBRARIES,
|
|
2584
|
+
run: () => libraryShellHint("Setting the default library")
|
|
2585
|
+
},
|
|
2586
|
+
{ keys: ["\r", "\n"], when: TAB_LIBRARIES, run: () => libraryShellHint("Library actions") },
|
|
2587
|
+
// - : assets → bulk-remove or single-remove toggle
|
|
2532
2588
|
{
|
|
2533
2589
|
keys: ["-"],
|
|
2534
2590
|
when: TAB_ASSETS,
|
|
@@ -2541,8 +2597,6 @@ var KEYMAP = [
|
|
|
2541
2597
|
}
|
|
2542
2598
|
}
|
|
2543
2599
|
},
|
|
2544
|
-
{ keys: ["-", "r", "x"], when: TAB_LIBRARIES, run: () => shellHint("Removing a library") },
|
|
2545
|
-
{ keys: ["d"], when: TAB_LIBRARIES, run: () => shellHint("Setting the default library") },
|
|
2546
2600
|
// Space — auto-toggle (single asset or bulk header)
|
|
2547
2601
|
{
|
|
2548
2602
|
keys: [" "],
|
|
@@ -2556,14 +2610,12 @@ var KEYMAP = [
|
|
|
2556
2610
|
}
|
|
2557
2611
|
}
|
|
2558
2612
|
},
|
|
2559
|
-
// s — sync (any tab) — minimal scaffold delegates to shell.
|
|
2560
|
-
{ keys: ["s"], run:
|
|
2561
|
-
// a : assets → apply
|
|
2613
|
+
// s — sync all (any tab) — minimal scaffold delegates to shell.
|
|
2614
|
+
{ keys: ["s"], run: syncAll },
|
|
2615
|
+
// a : assets → apply
|
|
2562
2616
|
{ keys: ["a"], when: TAB_ASSETS, run: applyChanges },
|
|
2563
|
-
|
|
2564
|
-
// Enter — apply on assets tab; libraries → shell hint
|
|
2617
|
+
// Enter — apply on assets tab
|
|
2565
2618
|
{ keys: ["\r", "\n"], when: TAB_ASSETS, run: applyChanges },
|
|
2566
|
-
{ keys: ["\r", "\n"], when: TAB_LIBRARIES, run: () => shellHint("Library actions") },
|
|
2567
2619
|
// Info — assets only
|
|
2568
2620
|
{ keys: ["i"], when: TAB_ASSETS, run: showInfo }
|
|
2569
2621
|
];
|
|
@@ -2591,8 +2643,8 @@ async function handleExitConfirm(key) {
|
|
|
2591
2643
|
}
|
|
2592
2644
|
async function run(projectDir) {
|
|
2593
2645
|
am = new AssetManager({ projectDir });
|
|
2594
|
-
loadAssets();
|
|
2595
|
-
await
|
|
2646
|
+
await loadAssets();
|
|
2647
|
+
await loadSourcesAndLibraries();
|
|
2596
2648
|
hideCursor();
|
|
2597
2649
|
process.stdin.setRawMode(true);
|
|
2598
2650
|
process.stdin.resume();
|
|
@@ -2610,7 +2662,7 @@ async function run(projectDir) {
|
|
|
2610
2662
|
clearScreen();
|
|
2611
2663
|
}
|
|
2612
2664
|
function makeManageCommand() {
|
|
2613
|
-
return new Command("manage").description("Interactive TUI for managing
|
|
2665
|
+
return new Command("manage").description("Interactive TUI for managing assets, sources, and libraries").option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
|
|
2614
2666
|
await run(path15__default.resolve(opts.projectDir));
|
|
2615
2667
|
});
|
|
2616
2668
|
}
|
|
@@ -2689,9 +2741,9 @@ function makeNpxCommand() {
|
|
|
2689
2741
|
});
|
|
2690
2742
|
}
|
|
2691
2743
|
spinner5.start("Syncing source");
|
|
2692
|
-
const { LocalCatalogSource } = await import('../library/index.js');
|
|
2744
|
+
const { LocalCatalogSource: LocalCatalogSource2 } = await import('../library/index.js');
|
|
2693
2745
|
const registry = createFullRegistry();
|
|
2694
|
-
const catalogSource = new
|
|
2746
|
+
const catalogSource = new LocalCatalogSource2(library, source.id, sourcePath, registry);
|
|
2695
2747
|
const result = await catalogSource.sync();
|
|
2696
2748
|
await library.syncSource(source.id);
|
|
2697
2749
|
spinner5.stop(`Indexed ${result.assetsUpdated} assets`);
|
|
@@ -3588,7 +3640,7 @@ function makeInstallCommand() {
|
|
|
3588
3640
|
const spinner6 = p5.spinner();
|
|
3589
3641
|
spinner6.start(`Installing ${ref}`);
|
|
3590
3642
|
try {
|
|
3591
|
-
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-
|
|
3643
|
+
const { openCatalogSource: openCatalogSource2, openLibrary: openLibrary2 } = await import('../open-library-T6RXQJTQ.js');
|
|
3592
3644
|
const catalog = await openCatalogSource2({ projectDir: path15__default.resolve(opts.projectDir) });
|
|
3593
3645
|
if (!supportsInstallManifest(catalog)) {
|
|
3594
3646
|
throw new Error(
|
|
@@ -3618,8 +3670,23 @@ function makeInstallCommand() {
|
|
|
3618
3670
|
}
|
|
3619
3671
|
return;
|
|
3620
3672
|
}
|
|
3673
|
+
const projectDir = path15__default.resolve(opts.projectDir);
|
|
3674
|
+
try {
|
|
3675
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-V26CZNJF.js');
|
|
3676
|
+
const hydrate = ensureSourcesCloned(projectDir, { quiet: true });
|
|
3677
|
+
if (hydrate.cloned.length > 0) {
|
|
3678
|
+
logOk(`Cloned source(s): ${hydrate.cloned.join(", ")}`);
|
|
3679
|
+
}
|
|
3680
|
+
if (hydrate.failed.length > 0) {
|
|
3681
|
+
logErr(`Failed to clone source(s): ${hydrate.failed.join(", ")}`);
|
|
3682
|
+
}
|
|
3683
|
+
} catch (err) {
|
|
3684
|
+
logWarn(
|
|
3685
|
+
`source hydration skipped: ${err instanceof Error ? err.message : String(err)}`
|
|
3686
|
+
);
|
|
3687
|
+
}
|
|
3621
3688
|
const am2 = new AssetManager({
|
|
3622
|
-
projectDir
|
|
3689
|
+
projectDir,
|
|
3623
3690
|
driverTarget: opts.target
|
|
3624
3691
|
});
|
|
3625
3692
|
const spinner5 = p5.spinner();
|
|
@@ -3988,11 +4055,11 @@ function makeClearCommand() {
|
|
|
3988
4055
|
}
|
|
3989
4056
|
function makeReplCommand() {
|
|
3990
4057
|
return new Command("repl").description("Start an interactive agent session").option("--project-dir <path>", "Project directory").option("--driver <name>", "Driver backend (claude-sdk, omp)").option("--provider <name>", "LLM provider").option("--model <name>", "Model override").option("--resume", "Resume last session").option("--resume-session <id>", "Resume specific session").action(async (opts) => {
|
|
3991
|
-
const { findWorkspaceRoot } = await import('../core/index.js');
|
|
4058
|
+
const { findWorkspaceRoot: findWorkspaceRoot2 } = await import('../core/index.js');
|
|
3992
4059
|
const { startRepl } = await import('../tui/index.js');
|
|
3993
4060
|
const os = await import('os');
|
|
3994
4061
|
const userCwd = path15__default.resolve(opts.projectDir ?? process.cwd());
|
|
3995
|
-
const workspaceRoot =
|
|
4062
|
+
const workspaceRoot = findWorkspaceRoot2(userCwd);
|
|
3996
4063
|
let projectDir;
|
|
3997
4064
|
let agentCwd;
|
|
3998
4065
|
let driverOverride = opts.driver;
|
|
@@ -4068,7 +4135,7 @@ async function runCompileTest(opts) {
|
|
|
4068
4135
|
const { tmpdir } = await import('os');
|
|
4069
4136
|
const { dirname: dirname3, join: join5, resolve: resolve4 } = await import('path');
|
|
4070
4137
|
const { fileURLToPath: fileURLToPath2 } = await import('url');
|
|
4071
|
-
const { unlinkSync, existsSync:
|
|
4138
|
+
const { unlinkSync, existsSync: existsSync12 } = await import('fs');
|
|
4072
4139
|
const { spawn } = await import('child_process');
|
|
4073
4140
|
const { portableSpawnSync: portableSpawnSync2 } = await import('../core/index.js');
|
|
4074
4141
|
const { MONOREPO_ROOT } = await import('../paths-FKKGS6BA.js');
|
|
@@ -4130,7 +4197,7 @@ async function runCompileTest(opts) {
|
|
|
4130
4197
|
} catch {
|
|
4131
4198
|
}
|
|
4132
4199
|
try {
|
|
4133
|
-
if (
|
|
4200
|
+
if (existsSync12(outfile)) unlinkSync(outfile);
|
|
4134
4201
|
} catch {
|
|
4135
4202
|
}
|
|
4136
4203
|
}
|
|
@@ -4900,102 +4967,193 @@ function addSourceManifestCommands(src) {
|
|
|
4900
4967
|
function sourcesDir() {
|
|
4901
4968
|
return path15.join(skaileHomeDir(), "sources");
|
|
4902
4969
|
}
|
|
4970
|
+
function sourceClonePath(name) {
|
|
4971
|
+
return path15.join(sourcesDir(), name);
|
|
4972
|
+
}
|
|
4903
4973
|
function deriveSlug(url) {
|
|
4904
4974
|
return url.replace(/\.git$/, "").split(/[/:]/).pop() ?? "source";
|
|
4905
4975
|
}
|
|
4906
|
-
function
|
|
4907
|
-
|
|
4976
|
+
function requireProjectYamlPath() {
|
|
4977
|
+
const root = findWorkspaceRoot(process.cwd());
|
|
4978
|
+
if (!root) {
|
|
4979
|
+
logErr(
|
|
4980
|
+
"No skaile.yaml found in the current directory or any parent. Run `skaile init` first."
|
|
4981
|
+
);
|
|
4982
|
+
process.exit(1);
|
|
4983
|
+
}
|
|
4984
|
+
return path15.join(root, workspaceConfigFilename());
|
|
4985
|
+
}
|
|
4986
|
+
function readProjectSources(yamlPath) {
|
|
4987
|
+
if (!existsSync(yamlPath)) return [];
|
|
4988
|
+
try {
|
|
4989
|
+
return WorkspaceYamlEditor.load(yamlPath).getSources();
|
|
4990
|
+
} catch (err) {
|
|
4991
|
+
logErr(`Could not read ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
4992
|
+
process.exit(1);
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4995
|
+
function ensureClone(entry, opts = {}) {
|
|
4996
|
+
const dest = sourceClonePath(entry.name);
|
|
4997
|
+
if (existsSync(dest)) {
|
|
4998
|
+
if (!opts.force) return false;
|
|
4999
|
+
rmSync(dest, { recursive: true, force: true });
|
|
5000
|
+
}
|
|
5001
|
+
const args = ["clone", entry.url, dest];
|
|
5002
|
+
if (entry.branch) args.splice(1, 0, "--branch", entry.branch);
|
|
5003
|
+
const clone = spawnSync("git", args, { stdio: "inherit" });
|
|
5004
|
+
if (clone.status !== 0) {
|
|
5005
|
+
logErr(`git clone failed for ${entry.url}`);
|
|
5006
|
+
process.exit(1);
|
|
5007
|
+
}
|
|
5008
|
+
return true;
|
|
5009
|
+
}
|
|
5010
|
+
async function refreshManifestCache(entry) {
|
|
5011
|
+
const { manager, library, close } = await openLibraryManager();
|
|
5012
|
+
try {
|
|
5013
|
+
const dest = sourceClonePath(entry.name);
|
|
5014
|
+
const existing = (await manager.listLibraries()).find((l) => l.name === entry.name);
|
|
5015
|
+
const lib = existing ?? await manager.addLibrary({
|
|
5016
|
+
name: entry.name,
|
|
5017
|
+
path: dest,
|
|
5018
|
+
backend: "git",
|
|
5019
|
+
backendConfig: { url: entry.url, branch: entry.branch ?? "main", authHint: "ssh" },
|
|
5020
|
+
ownership: "reader"
|
|
5021
|
+
});
|
|
5022
|
+
const catalog = new LocalCatalogSource(library, lib.id, dest, createFullRegistry());
|
|
5023
|
+
const result = await catalog.sync();
|
|
5024
|
+
await library.syncSource(lib.id);
|
|
5025
|
+
return result;
|
|
5026
|
+
} finally {
|
|
5027
|
+
close();
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
async function dropManifestCache(name, purgeClone) {
|
|
5031
|
+
const { manager, close } = await openLibraryManager();
|
|
5032
|
+
try {
|
|
5033
|
+
const existing = (await manager.listLibraries()).find((l) => l.name === name);
|
|
5034
|
+
if (existing) {
|
|
5035
|
+
await manager.removeLibrary(name, { purge: false });
|
|
5036
|
+
}
|
|
5037
|
+
} finally {
|
|
5038
|
+
close();
|
|
5039
|
+
}
|
|
5040
|
+
if (purgeClone) {
|
|
5041
|
+
const dest = sourceClonePath(name);
|
|
5042
|
+
if (existsSync(dest)) rmSync(dest, { recursive: true, force: true });
|
|
5043
|
+
}
|
|
4908
5044
|
}
|
|
4909
5045
|
function makeSourceCommand() {
|
|
4910
5046
|
const cmd = new Command("source").description(
|
|
4911
|
-
"Manage github sources
|
|
5047
|
+
"Manage github sources for the current project (recorded in skaile.yaml)"
|
|
4912
5048
|
);
|
|
4913
|
-
cmd.command("add <git-url>").description("Clone a github repo
|
|
5049
|
+
cmd.command("add <git-url>").description("Clone a github repo and register it in this project's skaile.yaml").option("--name <slug>", "Override the derived slug").option("--branch <branch>", "Branch to track (default: main)").option("--force", "Remove an existing clone and re-clone", false).action(async (url, opts) => {
|
|
5050
|
+
const yamlPath = requireProjectYamlPath();
|
|
4914
5051
|
const slug = opts.name ?? deriveSlug(url);
|
|
4915
|
-
const
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
5052
|
+
const entry = { name: slug, url };
|
|
5053
|
+
if (opts.branch) entry.branch = opts.branch;
|
|
5054
|
+
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
5055
|
+
const existing = editor.getSources().find((s) => s.name === slug);
|
|
5056
|
+
if (existing && existing.url !== url) {
|
|
5057
|
+
logErr(
|
|
5058
|
+
`A source named "${slug}" already exists in ${yamlPath} with a different url (${existing.url}). Pass --name to use a different slug.`
|
|
5059
|
+
);
|
|
4919
5060
|
process.exit(1);
|
|
4920
5061
|
}
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
});
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
close();
|
|
5062
|
+
editor.setSource(entry);
|
|
5063
|
+
editor.save();
|
|
5064
|
+
const dest = sourceClonePath(slug);
|
|
5065
|
+
const preexisting = existsSync(dest);
|
|
5066
|
+
const cloned = ensureClone(entry, { force: opts.force });
|
|
5067
|
+
if (!cloned) {
|
|
5068
|
+
logOk(`Reusing cached clone at ${dest}`);
|
|
5069
|
+
} else if (preexisting) {
|
|
5070
|
+
logOk(`Re-cloned ${url} \u2192 ${dest}`);
|
|
5071
|
+
} else {
|
|
5072
|
+
logOk(`Cloned ${url} \u2192 ${dest}`);
|
|
4933
5073
|
}
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
5074
|
+
const result = await refreshManifestCache(entry);
|
|
5075
|
+
logOk(
|
|
5076
|
+
`Indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s) from "${slug}".`
|
|
5077
|
+
);
|
|
5078
|
+
for (const err of result.errors) logWarn(err);
|
|
5079
|
+
logOk(`Source "${slug}" registered in ${path15.relative(process.cwd(), yamlPath)}.`);
|
|
5080
|
+
});
|
|
5081
|
+
cmd.command("list").description("List sources registered in this project's skaile.yaml").option("--json", "Output as JSON").action(async (opts) => {
|
|
5082
|
+
const yamlPath = requireProjectYamlPath();
|
|
5083
|
+
const sources = readProjectSources(yamlPath);
|
|
5084
|
+
if (opts.json) return console.log(JSON.stringify(sources, null, 2));
|
|
5085
|
+
if (sources.length === 0) {
|
|
5086
|
+
logInfo("No sources in skaile.yaml. Run `skaile source add <git-url>` to register one.");
|
|
5087
|
+
return;
|
|
5088
|
+
}
|
|
5089
|
+
console.log();
|
|
5090
|
+
console.log(S.heading(" Sources"));
|
|
5091
|
+
for (const s of sources) {
|
|
5092
|
+
const cached = existsSync(sourceClonePath(s.name)) ? "" : S.warn(" (not cached)");
|
|
5093
|
+
console.log(` ${S.cmd(s.name.padEnd(24))} ${S.dim(s.url)}${cached}`);
|
|
5094
|
+
}
|
|
5095
|
+
console.log(`
|
|
4951
5096
|
${S.dim(`${sources.length} source(s)`)}
|
|
4952
5097
|
`);
|
|
4953
|
-
} finally {
|
|
4954
|
-
close();
|
|
4955
|
-
}
|
|
4956
5098
|
});
|
|
4957
5099
|
cmd.command("show <name>").description("Show details for a source").action(async (name) => {
|
|
4958
|
-
const
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
process.exit(1);
|
|
4964
|
-
}
|
|
4965
|
-
console.log(JSON.stringify(s, null, 2));
|
|
4966
|
-
} finally {
|
|
4967
|
-
close();
|
|
5100
|
+
const yamlPath = requireProjectYamlPath();
|
|
5101
|
+
const entry = readProjectSources(yamlPath).find((s) => s.name === name);
|
|
5102
|
+
if (!entry) {
|
|
5103
|
+
logErr(`No source named "${name}" in ${yamlPath}.`);
|
|
5104
|
+
process.exit(1);
|
|
4968
5105
|
}
|
|
5106
|
+
console.log(
|
|
5107
|
+
JSON.stringify(
|
|
5108
|
+
{
|
|
5109
|
+
...entry,
|
|
5110
|
+
clonePath: sourceClonePath(entry.name),
|
|
5111
|
+
cached: existsSync(sourceClonePath(entry.name))
|
|
5112
|
+
},
|
|
5113
|
+
null,
|
|
5114
|
+
2
|
|
5115
|
+
)
|
|
5116
|
+
);
|
|
4969
5117
|
});
|
|
4970
|
-
cmd.command("remove <name>").description("
|
|
4971
|
-
const
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
}
|
|
4978
|
-
await manager.removeLibrary(name, { purge: opts.purge });
|
|
4979
|
-
logOk(`Removed source "${name}".`);
|
|
4980
|
-
} finally {
|
|
4981
|
-
close();
|
|
5118
|
+
cmd.command("remove <name>").description("Remove a source from this project's skaile.yaml").option("--purge", "Also delete the cached clone from ~/.skaile/sources/", false).action(async (name, opts) => {
|
|
5119
|
+
const yamlPath = requireProjectYamlPath();
|
|
5120
|
+
const editor = WorkspaceYamlEditor.load(yamlPath);
|
|
5121
|
+
const removed = editor.removeSource(name);
|
|
5122
|
+
if (!removed) {
|
|
5123
|
+
logErr(`No source named "${name}" in ${yamlPath}.`);
|
|
5124
|
+
process.exit(1);
|
|
4982
5125
|
}
|
|
5126
|
+
editor.save();
|
|
5127
|
+
await dropManifestCache(name, opts.purge);
|
|
5128
|
+
logOk(
|
|
5129
|
+
opts.purge ? `Removed source "${name}" and purged its clone.` : `Removed source "${name}" from skaile.yaml (clone left in ~/.skaile/sources/).`
|
|
5130
|
+
);
|
|
4983
5131
|
});
|
|
4984
|
-
cmd.command("sync [name]").description("
|
|
4985
|
-
const
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
5132
|
+
cmd.command("sync [name]").description("Pull upstream changes and refresh the manifest cache").action(async (name) => {
|
|
5133
|
+
const yamlPath = requireProjectYamlPath();
|
|
5134
|
+
const all = readProjectSources(yamlPath);
|
|
5135
|
+
const targets = name ? all.filter((s) => s.name === name) : all;
|
|
5136
|
+
if (targets.length === 0) {
|
|
5137
|
+
logInfo(name ? `No source named "${name}".` : "No sources in skaile.yaml.");
|
|
5138
|
+
return;
|
|
5139
|
+
}
|
|
5140
|
+
for (const entry of targets) {
|
|
5141
|
+
const dest = sourceClonePath(entry.name);
|
|
5142
|
+
if (!existsSync(dest)) {
|
|
5143
|
+
ensureClone(entry);
|
|
5144
|
+
logOk(`${entry.name}: cloned to ${dest}.`);
|
|
5145
|
+
} else {
|
|
5146
|
+
const pull = spawnSync("git", ["pull", "--ff-only"], { cwd: dest, stdio: "inherit" });
|
|
5147
|
+
if (pull.status !== 0) {
|
|
5148
|
+
logWarn(`${entry.name}: git pull failed, skipping manifest refresh.`);
|
|
5149
|
+
continue;
|
|
5150
|
+
}
|
|
4996
5151
|
}
|
|
4997
|
-
|
|
4998
|
-
|
|
5152
|
+
const result = await refreshManifestCache(entry);
|
|
5153
|
+
logOk(
|
|
5154
|
+
`${entry.name}: indexed ${result.assetsUpdated} of ${result.assetsFound} asset(s).`
|
|
5155
|
+
);
|
|
5156
|
+
for (const err of result.errors) logWarn(`${entry.name}: ${err}`);
|
|
4999
5157
|
}
|
|
5000
5158
|
});
|
|
5001
5159
|
cmd.command("patch <ref>").description("Extract an asset for editing against the source").action((_ref) => {
|
|
@@ -5761,7 +5919,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5761
5919
|
).option("--no-git", "Skip git init and .gitignore").action(
|
|
5762
5920
|
async (projectDir, opts) => {
|
|
5763
5921
|
const { execSync: execSync3 } = await import('child_process');
|
|
5764
|
-
const { existsSync:
|
|
5922
|
+
const { existsSync: existsSync12, mkdirSync: mkdirSync3, readFileSync: readFileSync5, writeFileSync: writeFileSync2 } = await import('fs');
|
|
5765
5923
|
const { stringify } = await import('yaml');
|
|
5766
5924
|
const { DRIVER_TARGETS, SUPPORTED_DRIVER_TARGETS: SUPPORTED_DRIVER_TARGETS2 } = await import('../core/index.js');
|
|
5767
5925
|
const backend = opts.backend;
|
|
@@ -5775,22 +5933,22 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5775
5933
|
const resolved = path15__default.resolve(projectDir ?? ".");
|
|
5776
5934
|
const projectName = path15__default.basename(resolved);
|
|
5777
5935
|
const created = [];
|
|
5778
|
-
if (!
|
|
5936
|
+
if (!existsSync12(resolved)) {
|
|
5779
5937
|
mkdirSync3(resolved, { recursive: true });
|
|
5780
5938
|
created.push(".");
|
|
5781
5939
|
}
|
|
5782
5940
|
const skaileDir = path15__default.join(resolved, ".skaile");
|
|
5783
|
-
if (!
|
|
5941
|
+
if (!existsSync12(skaileDir)) {
|
|
5784
5942
|
mkdirSync3(path15__default.join(skaileDir, "sessions"), { recursive: true });
|
|
5785
5943
|
created.push(".skaile/");
|
|
5786
5944
|
}
|
|
5787
5945
|
const settingsPath = path15__default.join(skaileDir, "settings.json");
|
|
5788
|
-
if (!
|
|
5946
|
+
if (!existsSync12(settingsPath)) {
|
|
5789
5947
|
writeFileSync2(settingsPath, "{}\n");
|
|
5790
5948
|
created.push(".skaile/settings.json");
|
|
5791
5949
|
}
|
|
5792
5950
|
const wsConfigPath = path15__default.join(resolved, "skaile.yaml");
|
|
5793
|
-
if (!
|
|
5951
|
+
if (!existsSync12(wsConfigPath)) {
|
|
5794
5952
|
writeFileSync2(
|
|
5795
5953
|
wsConfigPath,
|
|
5796
5954
|
stringify({
|
|
@@ -5812,7 +5970,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5812
5970
|
}
|
|
5813
5971
|
for (const dir of new Set(Object.values(DRIVER_TARGETS[backend].local))) {
|
|
5814
5972
|
const full = path15__default.join(resolved, dir);
|
|
5815
|
-
if (!
|
|
5973
|
+
if (!existsSync12(full)) {
|
|
5816
5974
|
mkdirSync3(full, { recursive: true });
|
|
5817
5975
|
created.push(`${dir}/`);
|
|
5818
5976
|
}
|
|
@@ -5820,7 +5978,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5820
5978
|
if (opts.git) {
|
|
5821
5979
|
const gitignorePath = path15__default.join(resolved, ".gitignore");
|
|
5822
5980
|
const entries = ["node_modules/", ".skaile/sessions/", "*.log", ".env", ".env.local"];
|
|
5823
|
-
const existing =
|
|
5981
|
+
const existing = existsSync12(gitignorePath) ? readFileSync5(gitignorePath, "utf-8") : "";
|
|
5824
5982
|
const have = new Set(existing.split("\n").map((l) => l.trim()));
|
|
5825
5983
|
const append = entries.filter((e) => !have.has(e));
|
|
5826
5984
|
if (append.length > 0) {
|
|
@@ -5829,7 +5987,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5829
5987
|
`);
|
|
5830
5988
|
if (!existing) created.push(".gitignore");
|
|
5831
5989
|
}
|
|
5832
|
-
if (!
|
|
5990
|
+
if (!existsSync12(path15__default.join(resolved, ".git"))) {
|
|
5833
5991
|
try {
|
|
5834
5992
|
execSync3("git init", { cwd: resolved, stdio: "pipe" });
|
|
5835
5993
|
created.push(".git/");
|
|
@@ -5855,6 +6013,17 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5855
6013
|
` ${S.dim(`\u26A0 could not bootstrap user config: ${err instanceof Error ? err.message : String(err)}`)}`
|
|
5856
6014
|
);
|
|
5857
6015
|
}
|
|
6016
|
+
try {
|
|
6017
|
+
const { ensureSourcesCloned } = await import('../ensure-sources-V26CZNJF.js');
|
|
6018
|
+
const hydrate = ensureSourcesCloned(resolved, { quiet: true });
|
|
6019
|
+
for (const n of hydrate.cloned) created.push(`~/.skaile/sources/${n}/`);
|
|
6020
|
+
if (hydrate.failed.length > 0) {
|
|
6021
|
+
logErr(`Failed to clone source(s): ${hydrate.failed.join(", ")}`);
|
|
6022
|
+
}
|
|
6023
|
+
} catch (err) {
|
|
6024
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6025
|
+
console.log(` ${S.dim(`\u26A0 source hydration skipped: ${msg}`)}`);
|
|
6026
|
+
}
|
|
5858
6027
|
for (const c of created) console.log(` ${S.dim(`+ ${c}`)}`);
|
|
5859
6028
|
logOk(`Initialized project at ${S.heading(resolved)}`);
|
|
5860
6029
|
console.log();
|
|
@@ -5872,7 +6041,7 @@ program.command("init [project-dir]").description("Initialize a project director
|
|
|
5872
6041
|
}
|
|
5873
6042
|
);
|
|
5874
6043
|
program.command("setup").description("Interactive provider setup wizard").action(async () => {
|
|
5875
|
-
const { cmdSetup } = await import('../setup-
|
|
6044
|
+
const { cmdSetup } = await import('../setup-R6VWIPLL.js');
|
|
5876
6045
|
await cmdSetup([], { projectDir: process.cwd() });
|
|
5877
6046
|
});
|
|
5878
6047
|
program.addCommand(makeInstallCommand());
|