@skillkit/tui 1.4.0 → 1.5.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/dist/index.d.ts +27 -14
- package/dist/index.js +684 -142
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { render } from "ink";
|
|
3
3
|
|
|
4
4
|
// src/App.tsx
|
|
5
|
-
import { useState as
|
|
6
|
-
import { Box as
|
|
5
|
+
import { useState as useState19 } from "react";
|
|
6
|
+
import { Box as Box17, Text as Text17, useInput as useInput15, useApp, useStdout } from "ink";
|
|
7
7
|
|
|
8
8
|
// src/components/Sidebar.tsx
|
|
9
9
|
import { Box, Text } from "ink";
|
|
@@ -55,6 +55,9 @@ var NAV = [
|
|
|
55
55
|
{ id: "workflow", label: "Workflows", key: "w" },
|
|
56
56
|
{ id: "execute", label: "Execute", key: "x" },
|
|
57
57
|
{ id: "history", label: "History", key: "y" },
|
|
58
|
+
// Collaboration
|
|
59
|
+
{ id: "team", label: "Team", key: "a" },
|
|
60
|
+
{ id: "plugins", label: "Plugins", key: "p" },
|
|
58
61
|
// Tools
|
|
59
62
|
{ id: "recommend", label: "Recommend", key: "r" },
|
|
60
63
|
{ id: "translate", label: "Translate", key: "t" },
|
|
@@ -78,12 +81,17 @@ function Sidebar({ screen }) {
|
|
|
78
81
|
item.label
|
|
79
82
|
] }, item.id)),
|
|
80
83
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
81
|
-
NAV.slice(6,
|
|
84
|
+
NAV.slice(6, 8).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
82
85
|
screen === item.id ? symbols.bullet : " ",
|
|
83
86
|
item.label
|
|
84
87
|
] }, item.id)),
|
|
85
88
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
86
|
-
NAV.slice(
|
|
89
|
+
NAV.slice(8, 12).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
90
|
+
screen === item.id ? symbols.bullet : " ",
|
|
91
|
+
item.label
|
|
92
|
+
] }, item.id)),
|
|
93
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
94
|
+
NAV.slice(12).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
87
95
|
screen === item.id ? symbols.bullet : " ",
|
|
88
96
|
item.label
|
|
89
97
|
] }, item.id)),
|
|
@@ -174,14 +182,16 @@ function Home({ cols = 80, rows = 24 }) {
|
|
|
174
182
|
|
|
175
183
|
// src/screens/Browse.tsx
|
|
176
184
|
import { useState as useState3 } from "react";
|
|
177
|
-
import { existsSync, mkdirSync, cpSync, rmSync } from "fs";
|
|
178
|
-
import { join as
|
|
185
|
+
import { existsSync as existsSync2, mkdirSync, cpSync, rmSync } from "fs";
|
|
186
|
+
import { join as join3 } from "path";
|
|
179
187
|
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
180
188
|
|
|
181
189
|
// src/hooks/useMarketplace.ts
|
|
182
190
|
import { useState as useState2, useCallback, useEffect as useEffect2 } from "react";
|
|
183
|
-
import { detectProvider } from "@skillkit/core";
|
|
184
|
-
|
|
191
|
+
import { detectProvider, loadConfig, extractFrontmatter } from "@skillkit/core";
|
|
192
|
+
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
193
|
+
import { join as join2 } from "path";
|
|
194
|
+
var DEFAULT_REPOS = [
|
|
185
195
|
{ source: "anthropics/skills", name: "Anthropic Official" },
|
|
186
196
|
{ source: "vercel-labs/agent-skills", name: "Vercel Labs" },
|
|
187
197
|
{ source: "expo/skills", name: "Expo / React Native" },
|
|
@@ -213,6 +223,41 @@ var POPULAR_REPOS = [
|
|
|
213
223
|
{ source: "openrouterteam/agent-skills", name: "OpenRouter SDK" },
|
|
214
224
|
{ source: "intellectronica/agent-skills", name: "Context7" }
|
|
215
225
|
];
|
|
226
|
+
function getMarketplaceRepos() {
|
|
227
|
+
try {
|
|
228
|
+
const config = loadConfig();
|
|
229
|
+
if (config.marketplaceSources?.length) {
|
|
230
|
+
const configRepos = config.marketplaceSources.map((source) => ({
|
|
231
|
+
source,
|
|
232
|
+
name: source.split("/").pop() || source
|
|
233
|
+
}));
|
|
234
|
+
const existingSources = new Set(configRepos.map((r) => r.source));
|
|
235
|
+
for (const repo of DEFAULT_REPOS) {
|
|
236
|
+
if (!existingSources.has(repo.source)) {
|
|
237
|
+
configRepos.push(repo);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return configRepos;
|
|
241
|
+
}
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
return DEFAULT_REPOS;
|
|
245
|
+
}
|
|
246
|
+
function readSkillDescription(skillPath) {
|
|
247
|
+
const skillMdPath = join2(skillPath, "SKILL.md");
|
|
248
|
+
if (!existsSync(skillMdPath)) {
|
|
249
|
+
return void 0;
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
const content = readFileSync2(skillMdPath, "utf-8");
|
|
253
|
+
const frontmatter = extractFrontmatter(content);
|
|
254
|
+
if (frontmatter && typeof frontmatter.description === "string") {
|
|
255
|
+
return frontmatter.description;
|
|
256
|
+
}
|
|
257
|
+
} catch {
|
|
258
|
+
}
|
|
259
|
+
return void 0;
|
|
260
|
+
}
|
|
216
261
|
function useMarketplace() {
|
|
217
262
|
const [allSkills, setAllSkills] = useState2([]);
|
|
218
263
|
const [filteredSkills, setFilteredSkills] = useState2([]);
|
|
@@ -220,6 +265,8 @@ function useMarketplace() {
|
|
|
220
265
|
const [error, setError] = useState2(null);
|
|
221
266
|
const [currentRepo, setCurrentRepo] = useState2(null);
|
|
222
267
|
const [fetchedRepos, setFetchedRepos] = useState2(/* @__PURE__ */ new Set());
|
|
268
|
+
const [failedRepos, setFailedRepos] = useState2([]);
|
|
269
|
+
const [repos] = useState2(() => getMarketplaceRepos());
|
|
223
270
|
const fetchRepo = useCallback(async (source) => {
|
|
224
271
|
if (fetchedRepos.has(source)) return;
|
|
225
272
|
setLoading(true);
|
|
@@ -234,12 +281,13 @@ function useMarketplace() {
|
|
|
234
281
|
if (!result.success || !result.discoveredSkills) {
|
|
235
282
|
throw new Error(result.error || "Failed to fetch skills");
|
|
236
283
|
}
|
|
237
|
-
const repoName =
|
|
284
|
+
const repoName = repos.find((r) => r.source === source)?.name || source;
|
|
238
285
|
const newSkills = result.discoveredSkills.map((skill) => ({
|
|
239
286
|
name: skill.name,
|
|
240
287
|
source,
|
|
241
288
|
repoName,
|
|
242
|
-
description
|
|
289
|
+
// Try to read description from skill frontmatter
|
|
290
|
+
description: readSkillDescription(skill.path)
|
|
243
291
|
}));
|
|
244
292
|
setAllSkills((prev) => {
|
|
245
293
|
const updated = [...prev, ...newSkills];
|
|
@@ -251,27 +299,37 @@ function useMarketplace() {
|
|
|
251
299
|
rmSync3(result.tempRoot, { recursive: true, force: true });
|
|
252
300
|
}
|
|
253
301
|
} catch (err) {
|
|
254
|
-
|
|
302
|
+
const errorMsg = err instanceof Error ? err.message : "Failed to fetch repository";
|
|
303
|
+
setError(errorMsg);
|
|
304
|
+
setFailedRepos((prev) => prev.includes(source) ? prev : [...prev, source]);
|
|
255
305
|
} finally {
|
|
256
306
|
setLoading(false);
|
|
257
307
|
setCurrentRepo(null);
|
|
258
308
|
}
|
|
259
|
-
}, [fetchedRepos]);
|
|
309
|
+
}, [fetchedRepos, repos]);
|
|
260
310
|
const fetchAllRepos = useCallback(async () => {
|
|
261
311
|
setLoading(true);
|
|
262
312
|
setError(null);
|
|
263
|
-
|
|
313
|
+
const failures = [];
|
|
314
|
+
for (const repo of repos) {
|
|
264
315
|
if (!fetchedRepos.has(repo.source)) {
|
|
265
316
|
setCurrentRepo(repo.source);
|
|
266
317
|
try {
|
|
267
318
|
await fetchRepo(repo.source);
|
|
268
|
-
} catch {
|
|
319
|
+
} catch (err) {
|
|
320
|
+
failures.push(repo.source);
|
|
269
321
|
}
|
|
270
322
|
}
|
|
271
323
|
}
|
|
324
|
+
if (failures.length > 0) {
|
|
325
|
+
setFailedRepos((prev) => {
|
|
326
|
+
const combined = [...prev, ...failures];
|
|
327
|
+
return [...new Set(combined)];
|
|
328
|
+
});
|
|
329
|
+
}
|
|
272
330
|
setLoading(false);
|
|
273
331
|
setCurrentRepo(null);
|
|
274
|
-
}, [fetchRepo, fetchedRepos]);
|
|
332
|
+
}, [fetchRepo, fetchedRepos, repos]);
|
|
275
333
|
const search = useCallback((query) => {
|
|
276
334
|
if (!query.trim()) {
|
|
277
335
|
setFilteredSkills(allSkills);
|
|
@@ -288,6 +346,8 @@ function useMarketplace() {
|
|
|
288
346
|
setFetchedRepos(/* @__PURE__ */ new Set());
|
|
289
347
|
setAllSkills([]);
|
|
290
348
|
setFilteredSkills([]);
|
|
349
|
+
setFailedRepos([]);
|
|
350
|
+
setError(null);
|
|
291
351
|
}, []);
|
|
292
352
|
useEffect2(() => {
|
|
293
353
|
setFilteredSkills(allSkills);
|
|
@@ -302,8 +362,9 @@ function useMarketplace() {
|
|
|
302
362
|
loading,
|
|
303
363
|
error,
|
|
304
364
|
totalCount: allSkills.length,
|
|
305
|
-
repos
|
|
365
|
+
repos,
|
|
306
366
|
currentRepo,
|
|
367
|
+
failedRepos,
|
|
307
368
|
refresh,
|
|
308
369
|
search,
|
|
309
370
|
fetchRepo,
|
|
@@ -317,14 +378,14 @@ import { detectAgent, getAdapter as getAdapter2, getAllAdapters } from "@skillki
|
|
|
317
378
|
|
|
318
379
|
// src/helpers.ts
|
|
319
380
|
import {
|
|
320
|
-
loadConfig,
|
|
381
|
+
loadConfig as loadConfig2,
|
|
321
382
|
getSearchDirs as coreGetSearchDirs,
|
|
322
383
|
getInstallDir as coreGetInstallDir,
|
|
323
384
|
saveSkillMetadata as coreSaveSkillMetadata
|
|
324
385
|
} from "@skillkit/core";
|
|
325
386
|
import { getAdapter } from "@skillkit/agents";
|
|
326
387
|
function getSearchDirs(agentType) {
|
|
327
|
-
const type = agentType ||
|
|
388
|
+
const type = agentType || loadConfig2().agent;
|
|
328
389
|
const adapter = getAdapter(type);
|
|
329
390
|
const adapterInfo = {
|
|
330
391
|
type: adapter.type,
|
|
@@ -335,7 +396,7 @@ function getSearchDirs(agentType) {
|
|
|
335
396
|
return coreGetSearchDirs(adapterInfo);
|
|
336
397
|
}
|
|
337
398
|
function getInstallDir(global = false, agentType) {
|
|
338
|
-
const type = agentType ||
|
|
399
|
+
const type = agentType || loadConfig2().agent;
|
|
339
400
|
const adapter = getAdapter(type);
|
|
340
401
|
const adapterInfo = {
|
|
341
402
|
type: adapter.type,
|
|
@@ -400,11 +461,11 @@ function Browse({ rows = 24 }) {
|
|
|
400
461
|
const targetAgentType = agentType || await detectAgent();
|
|
401
462
|
const adapter = getAdapter2(targetAgentType);
|
|
402
463
|
const installDir = getInstallDir(false, targetAgentType);
|
|
403
|
-
if (!
|
|
464
|
+
if (!existsSync2(installDir)) {
|
|
404
465
|
mkdirSync(installDir, { recursive: true });
|
|
405
466
|
}
|
|
406
|
-
const targetPath =
|
|
407
|
-
if (
|
|
467
|
+
const targetPath = join3(installDir, skillName);
|
|
468
|
+
if (existsSync2(targetPath)) {
|
|
408
469
|
rmSync(targetPath, { recursive: true, force: true });
|
|
409
470
|
}
|
|
410
471
|
cpSync(skill.path, targetPath, { recursive: true, dereference: true });
|
|
@@ -710,44 +771,167 @@ function Sync({ rows = 24 }) {
|
|
|
710
771
|
}
|
|
711
772
|
|
|
712
773
|
// src/screens/Settings.tsx
|
|
713
|
-
import { useState as useState7 } from "react";
|
|
774
|
+
import { useState as useState7, useEffect as useEffect5 } from "react";
|
|
714
775
|
import { Box as Box6, Text as Text6, useInput as useInput4 } from "ink";
|
|
776
|
+
import TextInput from "ink-text-input";
|
|
777
|
+
import { loadConfig as loadConfig3, saveConfig, AgentType as AgentTypeSchema } from "@skillkit/core";
|
|
715
778
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
779
|
+
var ALL_AGENTS = AgentTypeSchema.options;
|
|
716
780
|
var SETTINGS = [
|
|
717
|
-
{ id: "agent", label: "Default Agent",
|
|
718
|
-
{ id: "
|
|
719
|
-
{ id: "
|
|
781
|
+
{ id: "agent", label: "Default Agent", type: "select", options: ["auto-detect", ...ALL_AGENTS] },
|
|
782
|
+
{ id: "autoSync", label: "Auto Sync", type: "toggle" },
|
|
783
|
+
{ id: "cacheDir", label: "Cache Dir", type: "text" }
|
|
720
784
|
];
|
|
721
|
-
function Settings(
|
|
785
|
+
function Settings(_props) {
|
|
786
|
+
const [config, setConfig] = useState7(null);
|
|
722
787
|
const [sel, setSel] = useState7(0);
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
788
|
+
const [editing, setEditing] = useState7(false);
|
|
789
|
+
const [editValue, setEditValue] = useState7("");
|
|
790
|
+
const [saved, setSaved] = useState7(false);
|
|
791
|
+
const [error, setError] = useState7(null);
|
|
792
|
+
useEffect5(() => {
|
|
793
|
+
try {
|
|
794
|
+
const loaded = loadConfig3();
|
|
795
|
+
setConfig(loaded);
|
|
796
|
+
} catch (err) {
|
|
797
|
+
setError(`Failed to load config: ${err}`);
|
|
798
|
+
}
|
|
799
|
+
}, []);
|
|
800
|
+
const getCurrentValue = (setting) => {
|
|
801
|
+
if (!config) return "";
|
|
802
|
+
switch (setting.id) {
|
|
803
|
+
case "agent":
|
|
804
|
+
return config.agent === "universal" ? "auto-detect" : config.agent || "auto-detect";
|
|
805
|
+
case "autoSync":
|
|
806
|
+
return config.autoSync ? "enabled" : "disabled";
|
|
807
|
+
case "cacheDir":
|
|
808
|
+
return config.cacheDir || "~/.skillkit/cache";
|
|
809
|
+
default:
|
|
810
|
+
return "";
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
const handleSave = (setting, value) => {
|
|
814
|
+
if (!config) return;
|
|
815
|
+
const newConfig = { ...config };
|
|
816
|
+
switch (setting.id) {
|
|
817
|
+
case "agent":
|
|
818
|
+
if (value === "auto-detect") {
|
|
819
|
+
newConfig.agent = "universal";
|
|
820
|
+
} else {
|
|
821
|
+
newConfig.agent = value;
|
|
822
|
+
}
|
|
823
|
+
break;
|
|
824
|
+
case "autoSync":
|
|
825
|
+
newConfig.autoSync = value === "enabled";
|
|
826
|
+
break;
|
|
827
|
+
case "cacheDir":
|
|
828
|
+
newConfig.cacheDir = value || void 0;
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
try {
|
|
832
|
+
saveConfig(newConfig, false);
|
|
833
|
+
setConfig(newConfig);
|
|
834
|
+
setSaved(true);
|
|
835
|
+
setTimeout(() => setSaved(false), 2e3);
|
|
836
|
+
} catch (err) {
|
|
837
|
+
setError(`Failed to save: ${err}`);
|
|
838
|
+
setTimeout(() => setError(null), 3e3);
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
useInput4((input, key) => {
|
|
842
|
+
if (editing) {
|
|
843
|
+
if (key.return) {
|
|
844
|
+
handleSave(SETTINGS[sel], editValue);
|
|
845
|
+
setEditing(false);
|
|
846
|
+
} else if (key.escape) {
|
|
847
|
+
setEditing(false);
|
|
848
|
+
}
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (key.upArrow) {
|
|
852
|
+
setSel((i) => Math.max(0, i - 1));
|
|
853
|
+
} else if (key.downArrow) {
|
|
854
|
+
setSel((i) => Math.min(SETTINGS.length - 1, i + 1));
|
|
855
|
+
} else if (key.return || input === " ") {
|
|
856
|
+
const setting = SETTINGS[sel];
|
|
857
|
+
if (setting.type === "toggle") {
|
|
858
|
+
const current = getCurrentValue(setting);
|
|
859
|
+
const newValue = current === "enabled" ? "disabled" : "enabled";
|
|
860
|
+
handleSave(setting, newValue);
|
|
861
|
+
} else if (setting.type === "select" && setting.options) {
|
|
862
|
+
const current = getCurrentValue(setting);
|
|
863
|
+
const idx = setting.options.indexOf(current);
|
|
864
|
+
const nextIdx = (idx + 1) % setting.options.length;
|
|
865
|
+
handleSave(setting, setting.options[nextIdx]);
|
|
866
|
+
} else if (setting.type === "text") {
|
|
867
|
+
setEditValue(getCurrentValue(setting));
|
|
868
|
+
setEditing(true);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
726
871
|
});
|
|
872
|
+
if (!config) {
|
|
873
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
874
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: colors.primary, children: "SETTINGS" }),
|
|
875
|
+
error ? /* @__PURE__ */ jsxs6(Text6, { color: colors.danger, children: [
|
|
876
|
+
symbols.error,
|
|
877
|
+
" ",
|
|
878
|
+
error
|
|
879
|
+
] }) : /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Loading..." })
|
|
880
|
+
] });
|
|
881
|
+
}
|
|
727
882
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
728
883
|
/* @__PURE__ */ jsx6(Text6, { bold: true, color: colors.primary, children: "SETTINGS" }),
|
|
729
|
-
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Configure SkillKit" }),
|
|
884
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Configure SkillKit (changes save automatically)" }),
|
|
730
885
|
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, flexDirection: "column", children: SETTINGS.map((s, i) => {
|
|
731
886
|
const isSel = i === sel;
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
887
|
+
const value = getCurrentValue(s);
|
|
888
|
+
const isEditing = editing && isSel;
|
|
889
|
+
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
890
|
+
/* @__PURE__ */ jsxs6(Text6, { inverse: isSel && !isEditing, children: [
|
|
891
|
+
isSel ? symbols.pointer : " ",
|
|
892
|
+
s.label.padEnd(16)
|
|
893
|
+
] }),
|
|
894
|
+
isEditing ? /* @__PURE__ */ jsx6(Box6, { marginLeft: 1, children: /* @__PURE__ */ jsx6(
|
|
895
|
+
TextInput,
|
|
896
|
+
{
|
|
897
|
+
value: editValue,
|
|
898
|
+
onChange: setEditValue,
|
|
899
|
+
onSubmit: () => {
|
|
900
|
+
handleSave(s, editValue);
|
|
901
|
+
setEditing(false);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
) }) : /* @__PURE__ */ jsxs6(Text6, { color: colors.secondaryDim, children: [
|
|
905
|
+
" ",
|
|
906
|
+
value
|
|
907
|
+
] }),
|
|
908
|
+
s.type === "toggle" && isSel && !isEditing && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " (space to toggle)" }),
|
|
909
|
+
s.type === "select" && isSel && !isEditing && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " (enter to cycle)" })
|
|
737
910
|
] }, s.id);
|
|
738
911
|
}) }),
|
|
739
|
-
/* @__PURE__ */
|
|
912
|
+
/* @__PURE__ */ jsxs6(Box6, { marginTop: 1, children: [
|
|
913
|
+
saved && /* @__PURE__ */ jsxs6(Text6, { color: colors.success, children: [
|
|
914
|
+
symbols.check,
|
|
915
|
+
" Settings saved"
|
|
916
|
+
] }),
|
|
917
|
+
error && /* @__PURE__ */ jsxs6(Text6, { color: colors.danger, children: [
|
|
918
|
+
symbols.error,
|
|
919
|
+
" ",
|
|
920
|
+
error
|
|
921
|
+
] }),
|
|
922
|
+
!saved && !error && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: editing ? "Enter=save Esc=cancel" : "Enter/Space=edit q=quit" })
|
|
923
|
+
] })
|
|
740
924
|
] });
|
|
741
925
|
}
|
|
742
926
|
|
|
743
927
|
// src/screens/Recommend.tsx
|
|
744
928
|
import { useState as useState9 } from "react";
|
|
745
|
-
import { existsSync as
|
|
746
|
-
import { join as
|
|
929
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, cpSync as cpSync2, rmSync as rmSync2 } from "fs";
|
|
930
|
+
import { join as join4 } from "path";
|
|
747
931
|
import { Box as Box7, Text as Text7, useInput as useInput5 } from "ink";
|
|
748
932
|
|
|
749
933
|
// src/hooks/useRecommend.ts
|
|
750
|
-
import { useState as useState8, useCallback as useCallback2, useEffect as
|
|
934
|
+
import { useState as useState8, useCallback as useCallback2, useEffect as useEffect6 } from "react";
|
|
751
935
|
import {
|
|
752
936
|
RecommendationEngine,
|
|
753
937
|
ContextManager,
|
|
@@ -875,7 +1059,7 @@ function useRecommend(projectPath = process.cwd()) {
|
|
|
875
1059
|
const refresh = useCallback2(() => {
|
|
876
1060
|
loadRecommendations();
|
|
877
1061
|
}, [loadRecommendations]);
|
|
878
|
-
|
|
1062
|
+
useEffect6(() => {
|
|
879
1063
|
loadRecommendations();
|
|
880
1064
|
}, [loadRecommendations]);
|
|
881
1065
|
return {
|
|
@@ -965,11 +1149,11 @@ function Recommend({ rows = 24 }) {
|
|
|
965
1149
|
const targetAgentType = agentType || await detectAgent2();
|
|
966
1150
|
const adapter = getAdapter3(targetAgentType);
|
|
967
1151
|
const installDir = getInstallDir(false, targetAgentType);
|
|
968
|
-
if (!
|
|
1152
|
+
if (!existsSync3(installDir)) {
|
|
969
1153
|
mkdirSync2(installDir, { recursive: true });
|
|
970
1154
|
}
|
|
971
|
-
const targetPath =
|
|
972
|
-
if (
|
|
1155
|
+
const targetPath = join4(installDir, skillName);
|
|
1156
|
+
if (existsSync3(targetPath)) {
|
|
973
1157
|
rmSync2(targetPath, { recursive: true, force: true });
|
|
974
1158
|
}
|
|
975
1159
|
cpSync2(skill.path, targetPath, { recursive: true, dereference: true });
|
|
@@ -1172,9 +1356,9 @@ function Recommend({ rows = 24 }) {
|
|
|
1172
1356
|
}
|
|
1173
1357
|
|
|
1174
1358
|
// src/screens/Translate.tsx
|
|
1175
|
-
import { useState as useState10, useEffect as
|
|
1176
|
-
import { existsSync as
|
|
1177
|
-
import { join as
|
|
1359
|
+
import { useState as useState10, useEffect as useEffect7 } from "react";
|
|
1360
|
+
import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync3, writeFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
1361
|
+
import { join as join5 } from "path";
|
|
1178
1362
|
import { Box as Box8, Text as Text8, useInput as useInput6 } from "ink";
|
|
1179
1363
|
import {
|
|
1180
1364
|
translateSkill,
|
|
@@ -1192,17 +1376,17 @@ function Translate({ rows = 24 }) {
|
|
|
1192
1376
|
const [preview, setPreview] = useState10("");
|
|
1193
1377
|
const [result, setResult] = useState10(null);
|
|
1194
1378
|
const [loading, setLoading] = useState10(false);
|
|
1195
|
-
|
|
1379
|
+
useEffect7(() => {
|
|
1196
1380
|
const loadSkills = () => {
|
|
1197
1381
|
const installDir = getInstallDir(false);
|
|
1198
1382
|
const foundSkills = [];
|
|
1199
|
-
if (
|
|
1383
|
+
if (existsSync4(installDir)) {
|
|
1200
1384
|
const dirs = readdirSync(installDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
1201
1385
|
for (const dir of dirs) {
|
|
1202
|
-
const skillPath =
|
|
1203
|
-
const skillMdPath =
|
|
1204
|
-
if (
|
|
1205
|
-
const content =
|
|
1386
|
+
const skillPath = join5(installDir, dir);
|
|
1387
|
+
const skillMdPath = join5(skillPath, "SKILL.md");
|
|
1388
|
+
if (existsSync4(skillMdPath)) {
|
|
1389
|
+
const content = readFileSync3(skillMdPath, "utf-8");
|
|
1206
1390
|
foundSkills.push({
|
|
1207
1391
|
name: dir,
|
|
1208
1392
|
path: skillPath,
|
|
@@ -1215,7 +1399,7 @@ function Translate({ rows = 24 }) {
|
|
|
1215
1399
|
};
|
|
1216
1400
|
loadSkills();
|
|
1217
1401
|
}, []);
|
|
1218
|
-
|
|
1402
|
+
useEffect7(() => {
|
|
1219
1403
|
const adapters = getAllAdapters4();
|
|
1220
1404
|
const supportedAgents = getSupportedTranslationAgents();
|
|
1221
1405
|
const agentList = adapters.filter((a) => supportedAgents.includes(a.type)).map((a) => ({
|
|
@@ -1252,12 +1436,12 @@ function Translate({ rows = 24 }) {
|
|
|
1252
1436
|
return;
|
|
1253
1437
|
}
|
|
1254
1438
|
const adapter = getAdapter4(selectedAgent.type);
|
|
1255
|
-
const targetDir = adapter?.skillsDir ?
|
|
1256
|
-
if (!
|
|
1439
|
+
const targetDir = adapter?.skillsDir ? join5(process.cwd(), adapter.skillsDir) : join5(process.cwd(), `.${selectedAgent.type}/skills/`);
|
|
1440
|
+
if (!existsSync4(targetDir)) {
|
|
1257
1441
|
mkdirSync3(targetDir, { recursive: true });
|
|
1258
1442
|
}
|
|
1259
1443
|
const filename = translationResult.filename || `${selectedSkill.name}.md`;
|
|
1260
|
-
const targetPath =
|
|
1444
|
+
const targetPath = join5(targetDir, filename);
|
|
1261
1445
|
writeFileSync(targetPath, translationResult.content, "utf-8");
|
|
1262
1446
|
setResult({
|
|
1263
1447
|
success: true,
|
|
@@ -1403,7 +1587,7 @@ function Translate({ rows = 24 }) {
|
|
|
1403
1587
|
}
|
|
1404
1588
|
|
|
1405
1589
|
// src/screens/Context.tsx
|
|
1406
|
-
import { useState as useState11, useEffect as
|
|
1590
|
+
import { useState as useState11, useEffect as useEffect8 } from "react";
|
|
1407
1591
|
import { Box as Box9, Text as Text9, useInput as useInput7 } from "ink";
|
|
1408
1592
|
import {
|
|
1409
1593
|
loadContext,
|
|
@@ -1423,7 +1607,7 @@ function Context({ rows = 24 }) {
|
|
|
1423
1607
|
const [message, setMessage] = useState11(null);
|
|
1424
1608
|
const [error, setError] = useState11(null);
|
|
1425
1609
|
const projectPath = process.cwd();
|
|
1426
|
-
|
|
1610
|
+
useEffect8(() => {
|
|
1427
1611
|
const load = async () => {
|
|
1428
1612
|
setLoading(true);
|
|
1429
1613
|
try {
|
|
@@ -1652,7 +1836,7 @@ function Context({ rows = 24 }) {
|
|
|
1652
1836
|
}
|
|
1653
1837
|
|
|
1654
1838
|
// src/screens/Workflow.tsx
|
|
1655
|
-
import { useState as useState12, useEffect as
|
|
1839
|
+
import { useState as useState12, useEffect as useEffect9 } from "react";
|
|
1656
1840
|
import { Box as Box10, Text as Text10, useInput as useInput8 } from "ink";
|
|
1657
1841
|
import { listWorkflows } from "@skillkit/core";
|
|
1658
1842
|
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
@@ -1665,7 +1849,7 @@ function Workflow({ rows = 24 }) {
|
|
|
1665
1849
|
const maxVisible = Math.max(5, rows - 8);
|
|
1666
1850
|
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), workflows.length - maxVisible));
|
|
1667
1851
|
const visible = workflows.slice(start, start + maxVisible);
|
|
1668
|
-
|
|
1852
|
+
useEffect9(() => {
|
|
1669
1853
|
loadWorkflows();
|
|
1670
1854
|
}, []);
|
|
1671
1855
|
const loadWorkflows = () => {
|
|
@@ -1745,7 +1929,7 @@ function Workflow({ rows = 24 }) {
|
|
|
1745
1929
|
}
|
|
1746
1930
|
|
|
1747
1931
|
// src/screens/Execute.tsx
|
|
1748
|
-
import { useState as useState13, useEffect as
|
|
1932
|
+
import { useState as useState13, useEffect as useEffect10 } from "react";
|
|
1749
1933
|
import { Box as Box11, Text as Text11, useInput as useInput9 } from "ink";
|
|
1750
1934
|
import { createSessionManager } from "@skillkit/core";
|
|
1751
1935
|
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
@@ -1753,7 +1937,7 @@ function Execute({ rows = 24 }) {
|
|
|
1753
1937
|
const [session, setSession] = useState13(null);
|
|
1754
1938
|
const [loading, setLoading] = useState13(true);
|
|
1755
1939
|
const maxVisible = Math.max(5, rows - 10);
|
|
1756
|
-
|
|
1940
|
+
useEffect10(() => {
|
|
1757
1941
|
loadSession();
|
|
1758
1942
|
const interval = setInterval(loadSession, 1e3);
|
|
1759
1943
|
return () => clearInterval(interval);
|
|
@@ -1858,7 +2042,7 @@ function Execute({ rows = 24 }) {
|
|
|
1858
2042
|
}
|
|
1859
2043
|
|
|
1860
2044
|
// src/screens/History.tsx
|
|
1861
|
-
import { useState as useState14, useEffect as
|
|
2045
|
+
import { useState as useState14, useEffect as useEffect11 } from "react";
|
|
1862
2046
|
import { Box as Box12, Text as Text12, useInput as useInput10 } from "ink";
|
|
1863
2047
|
import { createSessionManager as createSessionManager2 } from "@skillkit/core";
|
|
1864
2048
|
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -1870,7 +2054,7 @@ function History({ rows = 24 }) {
|
|
|
1870
2054
|
const maxVisible = Math.max(5, rows - 8);
|
|
1871
2055
|
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), history.length - maxVisible));
|
|
1872
2056
|
const visible = history.slice(start, start + maxVisible);
|
|
1873
|
-
|
|
2057
|
+
useEffect11(() => {
|
|
1874
2058
|
loadHistory();
|
|
1875
2059
|
}, []);
|
|
1876
2060
|
const loadHistory = () => {
|
|
@@ -1981,7 +2165,7 @@ function History({ rows = 24 }) {
|
|
|
1981
2165
|
}
|
|
1982
2166
|
|
|
1983
2167
|
// src/screens/Marketplace.tsx
|
|
1984
|
-
import { useState as useState15, useEffect as
|
|
2168
|
+
import { useState as useState15, useEffect as useEffect12 } from "react";
|
|
1985
2169
|
import { Box as Box13, Text as Text13, useInput as useInput11 } from "ink";
|
|
1986
2170
|
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1987
2171
|
var SKILL_SOURCES = [
|
|
@@ -2001,7 +2185,7 @@ function Marketplace({ rows = 24 }) {
|
|
|
2001
2185
|
const maxVisible = Math.max(5, rows - 10);
|
|
2002
2186
|
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), filtered.length - maxVisible));
|
|
2003
2187
|
const visible = filtered.slice(start, start + maxVisible);
|
|
2004
|
-
|
|
2188
|
+
useEffect12(() => {
|
|
2005
2189
|
loadMarketplace();
|
|
2006
2190
|
}, []);
|
|
2007
2191
|
const loadMarketplace = async () => {
|
|
@@ -2140,7 +2324,7 @@ function Marketplace({ rows = 24 }) {
|
|
|
2140
2324
|
}
|
|
2141
2325
|
|
|
2142
2326
|
// src/screens/Memory.tsx
|
|
2143
|
-
import { useState as useState16, useEffect as
|
|
2327
|
+
import { useState as useState16, useEffect as useEffect13 } from "react";
|
|
2144
2328
|
import { Box as Box14, Text as Text14, useInput as useInput12 } from "ink";
|
|
2145
2329
|
import {
|
|
2146
2330
|
ObservationStore,
|
|
@@ -2165,7 +2349,7 @@ function Memory({ rows = 24 }) {
|
|
|
2165
2349
|
const currentList = tab === "search" ? searchResults : learnings;
|
|
2166
2350
|
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), currentList.length - maxVisible));
|
|
2167
2351
|
const visible = currentList.slice(start, start + maxVisible);
|
|
2168
|
-
|
|
2352
|
+
useEffect13(() => {
|
|
2169
2353
|
loadMemory();
|
|
2170
2354
|
}, [isGlobal]);
|
|
2171
2355
|
const loadMemory = () => {
|
|
@@ -2400,10 +2584,360 @@ function Memory({ rows = 24 }) {
|
|
|
2400
2584
|
] });
|
|
2401
2585
|
}
|
|
2402
2586
|
|
|
2403
|
-
// src/
|
|
2587
|
+
// src/screens/Team.tsx
|
|
2588
|
+
import { useState as useState17, useEffect as useEffect14 } from "react";
|
|
2589
|
+
import { Box as Box15, Text as Text15, useInput as useInput13 } from "ink";
|
|
2404
2590
|
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2591
|
+
function Team({ rows = 24 }) {
|
|
2592
|
+
const [config, setConfig] = useState17(null);
|
|
2593
|
+
const [skills, setSkills] = useState17([]);
|
|
2594
|
+
const [loading, setLoading] = useState17(true);
|
|
2595
|
+
const [error, setError] = useState17(null);
|
|
2596
|
+
const [sel, setSel] = useState17(0);
|
|
2597
|
+
const [message, setMessage] = useState17(null);
|
|
2598
|
+
const maxVisible = Math.max(5, rows - 12);
|
|
2599
|
+
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), skills.length - maxVisible));
|
|
2600
|
+
const visible = skills.slice(start, start + maxVisible);
|
|
2601
|
+
useEffect14(() => {
|
|
2602
|
+
loadTeam();
|
|
2603
|
+
}, []);
|
|
2604
|
+
const loadTeam = async () => {
|
|
2605
|
+
setLoading(true);
|
|
2606
|
+
setError(null);
|
|
2607
|
+
try {
|
|
2608
|
+
const { createTeamManager } = await import("@skillkit/core");
|
|
2609
|
+
const manager = createTeamManager(process.cwd());
|
|
2610
|
+
const teamConfig = manager.load();
|
|
2611
|
+
if (!teamConfig) {
|
|
2612
|
+
setConfig(null);
|
|
2613
|
+
setSkills([]);
|
|
2614
|
+
setError("Team not initialized. Run `skillkit team init` first.");
|
|
2615
|
+
} else {
|
|
2616
|
+
setConfig(teamConfig);
|
|
2617
|
+
const sharedSkills = manager.listSharedSkills();
|
|
2618
|
+
setSkills(sharedSkills);
|
|
2619
|
+
setSel((s) => Math.min(s, Math.max(0, sharedSkills.length - 1)));
|
|
2620
|
+
}
|
|
2621
|
+
} catch (e) {
|
|
2622
|
+
setError(e instanceof Error ? e.message : "Failed to load team");
|
|
2623
|
+
}
|
|
2624
|
+
setLoading(false);
|
|
2625
|
+
};
|
|
2626
|
+
const syncTeam = async () => {
|
|
2627
|
+
if (!config) return;
|
|
2628
|
+
setLoading(true);
|
|
2629
|
+
setMessage(null);
|
|
2630
|
+
try {
|
|
2631
|
+
const { createTeamManager } = await import("@skillkit/core");
|
|
2632
|
+
const manager = createTeamManager(process.cwd());
|
|
2633
|
+
manager.load();
|
|
2634
|
+
const result = await manager.sync();
|
|
2635
|
+
const changes = [...result.added, ...result.updated];
|
|
2636
|
+
if (changes.length > 0) {
|
|
2637
|
+
setMessage(`Synced: ${changes.join(", ")}`);
|
|
2638
|
+
} else {
|
|
2639
|
+
setMessage("Already up to date");
|
|
2640
|
+
}
|
|
2641
|
+
const sharedSkills = manager.listSharedSkills();
|
|
2642
|
+
setSkills(sharedSkills);
|
|
2643
|
+
setSel((s) => Math.min(s, Math.max(0, sharedSkills.length - 1)));
|
|
2644
|
+
} catch (e) {
|
|
2645
|
+
setError(e instanceof Error ? e.message : "Sync failed");
|
|
2646
|
+
}
|
|
2647
|
+
setLoading(false);
|
|
2648
|
+
};
|
|
2649
|
+
const importSkill = async (skillName) => {
|
|
2650
|
+
if (!config) return;
|
|
2651
|
+
setLoading(true);
|
|
2652
|
+
setMessage(null);
|
|
2653
|
+
try {
|
|
2654
|
+
const { createTeamManager } = await import("@skillkit/core");
|
|
2655
|
+
const manager = createTeamManager(process.cwd());
|
|
2656
|
+
manager.load();
|
|
2657
|
+
const result = await manager.importSkill(skillName, { overwrite: false });
|
|
2658
|
+
if (result.success) {
|
|
2659
|
+
setMessage(`Imported: ${skillName}`);
|
|
2660
|
+
} else {
|
|
2661
|
+
setError(result.error || "Import failed");
|
|
2662
|
+
}
|
|
2663
|
+
} catch (e) {
|
|
2664
|
+
setError(e instanceof Error ? e.message : "Import failed");
|
|
2665
|
+
}
|
|
2666
|
+
setLoading(false);
|
|
2667
|
+
};
|
|
2668
|
+
useInput13((input, key) => {
|
|
2669
|
+
if (loading) return;
|
|
2670
|
+
if (skills.length === 0 && (key.upArrow || key.downArrow)) return;
|
|
2671
|
+
if (key.upArrow) setSel((i) => Math.max(0, i - 1));
|
|
2672
|
+
else if (key.downArrow) setSel((i) => Math.min(Math.max(0, skills.length - 1), i + 1));
|
|
2673
|
+
else if (input === "r") loadTeam();
|
|
2674
|
+
else if (input === "s") syncTeam();
|
|
2675
|
+
else if (key.return && skills[sel]) {
|
|
2676
|
+
importSkill(skills[sel].name);
|
|
2677
|
+
}
|
|
2678
|
+
});
|
|
2679
|
+
if (loading) {
|
|
2680
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
|
|
2681
|
+
/* @__PURE__ */ jsx15(Text15, { color: colors.primary, bold: true, children: "Team Collaboration" }),
|
|
2682
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { color: colors.secondaryDim, children: [
|
|
2683
|
+
symbols.spinner[0],
|
|
2684
|
+
" Loading..."
|
|
2685
|
+
] }) })
|
|
2686
|
+
] });
|
|
2687
|
+
}
|
|
2688
|
+
if (!config) {
|
|
2689
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
|
|
2690
|
+
/* @__PURE__ */ jsx15(Text15, { color: colors.primary, bold: true, children: "Team Collaboration" }),
|
|
2691
|
+
/* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "column", children: [
|
|
2692
|
+
/* @__PURE__ */ jsxs15(Text15, { color: colors.secondaryDim, children: [
|
|
2693
|
+
symbols.warning,
|
|
2694
|
+
" Team not initialized"
|
|
2695
|
+
] }),
|
|
2696
|
+
/* @__PURE__ */ jsx15(Text15, { color: colors.secondaryDim, dimColor: true, children: 'Run: skillkit team init --name "Team Name" --registry <url>' })
|
|
2697
|
+
] }),
|
|
2698
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: "[r] Refresh" }) })
|
|
2699
|
+
] });
|
|
2700
|
+
}
|
|
2701
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
|
|
2702
|
+
/* @__PURE__ */ jsxs15(Text15, { color: colors.primary, bold: true, children: [
|
|
2703
|
+
"Team: ",
|
|
2704
|
+
config.teamName
|
|
2705
|
+
] }),
|
|
2706
|
+
/* @__PURE__ */ jsxs15(Text15, { color: colors.secondaryDim, dimColor: true, children: [
|
|
2707
|
+
"Registry: ",
|
|
2708
|
+
config.registryUrl
|
|
2709
|
+
] }),
|
|
2710
|
+
error && /* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { color: "red", children: [
|
|
2711
|
+
symbols.error,
|
|
2712
|
+
" ",
|
|
2713
|
+
error
|
|
2714
|
+
] }) }),
|
|
2715
|
+
message && /* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { color: "green", children: [
|
|
2716
|
+
symbols.success,
|
|
2717
|
+
" ",
|
|
2718
|
+
message
|
|
2719
|
+
] }) }),
|
|
2720
|
+
/* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "column", children: [
|
|
2721
|
+
/* @__PURE__ */ jsxs15(Text15, { color: colors.secondaryDim, bold: true, children: [
|
|
2722
|
+
"Shared Skills (",
|
|
2723
|
+
skills.length,
|
|
2724
|
+
")"
|
|
2725
|
+
] }),
|
|
2726
|
+
skills.length === 0 ? /* @__PURE__ */ jsx15(Text15, { color: colors.secondaryDim, dimColor: true, children: "No shared skills. Use `skillkit team share --name <skill>` to share." }) : /* @__PURE__ */ jsx15(Box15, { flexDirection: "column", marginTop: 1, children: visible.map((skill, i) => {
|
|
2727
|
+
const actualIndex = start + i;
|
|
2728
|
+
const isSelected = actualIndex === sel;
|
|
2729
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
2730
|
+
/* @__PURE__ */ jsxs15(Text15, { children: [
|
|
2731
|
+
isSelected ? symbols.pointer : " ",
|
|
2732
|
+
" ",
|
|
2733
|
+
/* @__PURE__ */ jsx15(Text15, { color: isSelected ? colors.primary : colors.secondaryDim, bold: isSelected, children: skill.name }),
|
|
2734
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2735
|
+
" v",
|
|
2736
|
+
skill.version
|
|
2737
|
+
] }),
|
|
2738
|
+
/* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2739
|
+
" by ",
|
|
2740
|
+
skill.author
|
|
2741
|
+
] }),
|
|
2742
|
+
skill.downloads !== void 0 && /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
2743
|
+
" | ",
|
|
2744
|
+
skill.downloads,
|
|
2745
|
+
" downloads"
|
|
2746
|
+
] })
|
|
2747
|
+
] }),
|
|
2748
|
+
skill.description && isSelected && /* @__PURE__ */ jsxs15(Text15, { color: colors.secondaryDim, dimColor: true, children: [
|
|
2749
|
+
" ",
|
|
2750
|
+
skill.description
|
|
2751
|
+
] })
|
|
2752
|
+
] }, skill.name);
|
|
2753
|
+
}) })
|
|
2754
|
+
] }),
|
|
2755
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, borderStyle: "single", borderColor: colors.borderDim, paddingX: 1, children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: "[\u2191\u2193] Navigate [Enter] Import [s] Sync [r] Refresh" }) })
|
|
2756
|
+
] });
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
// src/screens/Plugins.tsx
|
|
2760
|
+
import { useState as useState18, useEffect as useEffect15 } from "react";
|
|
2761
|
+
import { Box as Box16, Text as Text16, useInput as useInput14 } from "ink";
|
|
2762
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2763
|
+
function Plugins({ rows = 24 }) {
|
|
2764
|
+
const [plugins, setPlugins] = useState18([]);
|
|
2765
|
+
const [loading, setLoading] = useState18(true);
|
|
2766
|
+
const [error, setError] = useState18(null);
|
|
2767
|
+
const [sel, setSel] = useState18(0);
|
|
2768
|
+
const [message, setMessage] = useState18(null);
|
|
2769
|
+
const maxVisible = Math.max(5, rows - 12);
|
|
2770
|
+
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), plugins.length - maxVisible));
|
|
2771
|
+
const visible = plugins.slice(start, start + maxVisible);
|
|
2772
|
+
useEffect15(() => {
|
|
2773
|
+
loadPlugins();
|
|
2774
|
+
}, []);
|
|
2775
|
+
const loadPlugins = async () => {
|
|
2776
|
+
setLoading(true);
|
|
2777
|
+
setError(null);
|
|
2778
|
+
try {
|
|
2779
|
+
const { createPluginManager, loadPluginsFromDirectory } = await import("@skillkit/core");
|
|
2780
|
+
const { join: join6 } = await import("path");
|
|
2781
|
+
const manager = createPluginManager(process.cwd());
|
|
2782
|
+
const pluginsDir = join6(process.cwd(), ".skillkit", "plugins");
|
|
2783
|
+
try {
|
|
2784
|
+
const loadedPlugins = await loadPluginsFromDirectory(pluginsDir);
|
|
2785
|
+
for (const plugin of loadedPlugins) {
|
|
2786
|
+
if (!manager.getPlugin(plugin.metadata.name)) {
|
|
2787
|
+
await manager.register(plugin);
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
} catch (err) {
|
|
2791
|
+
if (err && typeof err === "object" && "code" in err && err.code !== "ENOENT") {
|
|
2792
|
+
throw err;
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
const allPlugins = manager.listPlugins();
|
|
2796
|
+
const pluginInfos = allPlugins.map((p) => {
|
|
2797
|
+
const plugin = manager.getPlugin(p.name);
|
|
2798
|
+
return {
|
|
2799
|
+
name: p.name,
|
|
2800
|
+
version: p.version,
|
|
2801
|
+
description: p.description,
|
|
2802
|
+
author: p.author,
|
|
2803
|
+
enabled: manager.isPluginEnabled(p.name),
|
|
2804
|
+
translators: plugin?.translators?.map((t) => t.agentType),
|
|
2805
|
+
providers: plugin?.providers?.map((pr) => pr.providerName),
|
|
2806
|
+
commands: plugin?.commands?.map((c) => c.name)
|
|
2807
|
+
};
|
|
2808
|
+
});
|
|
2809
|
+
setPlugins(pluginInfos);
|
|
2810
|
+
} catch (e) {
|
|
2811
|
+
setError(e instanceof Error ? e.message : "Failed to load plugins");
|
|
2812
|
+
}
|
|
2813
|
+
setLoading(false);
|
|
2814
|
+
};
|
|
2815
|
+
const togglePlugin = async (pluginName, currentEnabled) => {
|
|
2816
|
+
setLoading(true);
|
|
2817
|
+
setMessage(null);
|
|
2818
|
+
try {
|
|
2819
|
+
const { createPluginManager, loadPluginsFromDirectory } = await import("@skillkit/core");
|
|
2820
|
+
const { join: join6 } = await import("path");
|
|
2821
|
+
const manager = createPluginManager(process.cwd());
|
|
2822
|
+
const pluginsDir = join6(process.cwd(), ".skillkit", "plugins");
|
|
2823
|
+
try {
|
|
2824
|
+
const loadedPlugins = await loadPluginsFromDirectory(pluginsDir);
|
|
2825
|
+
for (const plugin of loadedPlugins) {
|
|
2826
|
+
if (!manager.getPlugin(plugin.metadata.name)) {
|
|
2827
|
+
await manager.register(plugin);
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
} catch (err) {
|
|
2831
|
+
if (err && typeof err === "object" && "code" in err && err.code !== "ENOENT") {
|
|
2832
|
+
throw err;
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
if (currentEnabled) {
|
|
2836
|
+
manager.disablePlugin(pluginName);
|
|
2837
|
+
setMessage(`Disabled: ${pluginName}`);
|
|
2838
|
+
} else {
|
|
2839
|
+
manager.enablePlugin(pluginName);
|
|
2840
|
+
setMessage(`Enabled: ${pluginName}`);
|
|
2841
|
+
}
|
|
2842
|
+
await loadPlugins();
|
|
2843
|
+
} catch (e) {
|
|
2844
|
+
setError(e instanceof Error ? e.message : "Toggle failed");
|
|
2845
|
+
setLoading(false);
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
useInput14((input, key) => {
|
|
2849
|
+
if (loading) return;
|
|
2850
|
+
if (plugins.length === 0 && (key.upArrow || key.downArrow)) return;
|
|
2851
|
+
if (key.upArrow) setSel((i) => Math.max(0, i - 1));
|
|
2852
|
+
else if (key.downArrow) setSel((i) => Math.min(Math.max(0, plugins.length - 1), i + 1));
|
|
2853
|
+
else if (input === "r") loadPlugins();
|
|
2854
|
+
else if (input === "e" && plugins[sel]) {
|
|
2855
|
+
togglePlugin(plugins[sel].name, plugins[sel].enabled);
|
|
2856
|
+
} else if (key.return && plugins[sel]) {
|
|
2857
|
+
togglePlugin(plugins[sel].name, plugins[sel].enabled);
|
|
2858
|
+
}
|
|
2859
|
+
});
|
|
2860
|
+
if (loading) {
|
|
2861
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
|
|
2862
|
+
/* @__PURE__ */ jsx16(Text16, { color: colors.primary, bold: true, children: "Plugin Manager" }),
|
|
2863
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsxs16(Text16, { color: colors.secondaryDim, children: [
|
|
2864
|
+
symbols.spinner[0],
|
|
2865
|
+
" Loading..."
|
|
2866
|
+
] }) })
|
|
2867
|
+
] });
|
|
2868
|
+
}
|
|
2869
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
|
|
2870
|
+
/* @__PURE__ */ jsx16(Text16, { color: colors.primary, bold: true, children: "Plugin Manager" }),
|
|
2871
|
+
/* @__PURE__ */ jsx16(Text16, { color: colors.secondaryDim, dimColor: true, children: "Manage SkillKit extensions" }),
|
|
2872
|
+
error && /* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsxs16(Text16, { color: "red", children: [
|
|
2873
|
+
symbols.error,
|
|
2874
|
+
" ",
|
|
2875
|
+
error
|
|
2876
|
+
] }) }),
|
|
2877
|
+
message && /* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsxs16(Text16, { color: "green", children: [
|
|
2878
|
+
symbols.success,
|
|
2879
|
+
" ",
|
|
2880
|
+
message
|
|
2881
|
+
] }) }),
|
|
2882
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
2883
|
+
/* @__PURE__ */ jsxs16(Text16, { color: colors.secondaryDim, bold: true, children: [
|
|
2884
|
+
"Installed Plugins (",
|
|
2885
|
+
plugins.length,
|
|
2886
|
+
")"
|
|
2887
|
+
] }),
|
|
2888
|
+
plugins.length === 0 ? /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
2889
|
+
/* @__PURE__ */ jsx16(Text16, { color: colors.secondaryDim, dimColor: true, children: "No plugins installed." }),
|
|
2890
|
+
/* @__PURE__ */ jsx16(Text16, { color: colors.secondaryDim, dimColor: true, children: "Use: skillkit plugin install --source <path-or-package>" })
|
|
2891
|
+
] }) : /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", marginTop: 1, children: visible.map((plugin, i) => {
|
|
2892
|
+
const actualIndex = start + i;
|
|
2893
|
+
const isSelected = actualIndex === sel;
|
|
2894
|
+
const statusColor = plugin.enabled ? "green" : "gray";
|
|
2895
|
+
const statusText = plugin.enabled ? "enabled" : "disabled";
|
|
2896
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
2897
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
2898
|
+
isSelected ? symbols.pointer : " ",
|
|
2899
|
+
" ",
|
|
2900
|
+
/* @__PURE__ */ jsx16(Text16, { color: isSelected ? colors.primary : colors.secondaryDim, bold: isSelected, children: plugin.name }),
|
|
2901
|
+
/* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
2902
|
+
" v",
|
|
2903
|
+
plugin.version
|
|
2904
|
+
] }),
|
|
2905
|
+
/* @__PURE__ */ jsxs16(Text16, { color: statusColor, children: [
|
|
2906
|
+
" [",
|
|
2907
|
+
statusText,
|
|
2908
|
+
"]"
|
|
2909
|
+
] })
|
|
2910
|
+
] }),
|
|
2911
|
+
isSelected && /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginLeft: 3, children: [
|
|
2912
|
+
plugin.description && /* @__PURE__ */ jsx16(Text16, { color: colors.secondaryDim, dimColor: true, children: plugin.description }),
|
|
2913
|
+
plugin.author && /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
2914
|
+
"Author: ",
|
|
2915
|
+
plugin.author
|
|
2916
|
+
] }),
|
|
2917
|
+
plugin.translators && plugin.translators.length > 0 && /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
2918
|
+
"Translators: ",
|
|
2919
|
+
plugin.translators.join(", ")
|
|
2920
|
+
] }),
|
|
2921
|
+
plugin.providers && plugin.providers.length > 0 && /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
2922
|
+
"Providers: ",
|
|
2923
|
+
plugin.providers.join(", ")
|
|
2924
|
+
] }),
|
|
2925
|
+
plugin.commands && plugin.commands.length > 0 && /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
|
|
2926
|
+
"Commands: ",
|
|
2927
|
+
plugin.commands.join(", ")
|
|
2928
|
+
] })
|
|
2929
|
+
] })
|
|
2930
|
+
] }, plugin.name);
|
|
2931
|
+
}) })
|
|
2932
|
+
] }),
|
|
2933
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, borderStyle: "single", borderColor: colors.borderDim, paddingX: 1, children: /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "[\u2191\u2193] Navigate [e/Enter] Toggle Enable/Disable [r] Refresh" }) })
|
|
2934
|
+
] });
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
// src/App.tsx
|
|
2938
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2405
2939
|
function App() {
|
|
2406
|
-
const [screen, setScreen] =
|
|
2940
|
+
const [screen, setScreen] = useState19("home");
|
|
2407
2941
|
const { exit } = useApp();
|
|
2408
2942
|
const { stdout } = useStdout();
|
|
2409
2943
|
const cols = stdout?.columns || 80;
|
|
@@ -2422,9 +2956,11 @@ function App() {
|
|
|
2422
2956
|
e: "memory",
|
|
2423
2957
|
i: "installed",
|
|
2424
2958
|
s: "sync",
|
|
2959
|
+
a: "team",
|
|
2960
|
+
p: "plugins",
|
|
2425
2961
|
",": "settings"
|
|
2426
2962
|
};
|
|
2427
|
-
|
|
2963
|
+
useInput15((input, key) => {
|
|
2428
2964
|
if (input === "q") {
|
|
2429
2965
|
exit();
|
|
2430
2966
|
return;
|
|
@@ -2441,63 +2977,67 @@ function App() {
|
|
|
2441
2977
|
const renderScreen = () => {
|
|
2442
2978
|
switch (screen) {
|
|
2443
2979
|
case "home":
|
|
2444
|
-
return /* @__PURE__ */
|
|
2980
|
+
return /* @__PURE__ */ jsx17(Home, { onNavigate: setScreen, cols, rows });
|
|
2445
2981
|
case "browse":
|
|
2446
|
-
return /* @__PURE__ */
|
|
2982
|
+
return /* @__PURE__ */ jsx17(Browse, { cols, rows });
|
|
2447
2983
|
case "installed":
|
|
2448
|
-
return /* @__PURE__ */
|
|
2984
|
+
return /* @__PURE__ */ jsx17(Installed, { cols, rows });
|
|
2449
2985
|
case "sync":
|
|
2450
|
-
return /* @__PURE__ */
|
|
2986
|
+
return /* @__PURE__ */ jsx17(Sync, { cols, rows });
|
|
2451
2987
|
case "settings":
|
|
2452
|
-
return /* @__PURE__ */
|
|
2988
|
+
return /* @__PURE__ */ jsx17(Settings, { cols, rows });
|
|
2453
2989
|
case "recommend":
|
|
2454
|
-
return /* @__PURE__ */
|
|
2990
|
+
return /* @__PURE__ */ jsx17(Recommend, { cols, rows });
|
|
2455
2991
|
case "translate":
|
|
2456
|
-
return /* @__PURE__ */
|
|
2992
|
+
return /* @__PURE__ */ jsx17(Translate, { cols, rows });
|
|
2457
2993
|
case "context":
|
|
2458
|
-
return /* @__PURE__ */
|
|
2994
|
+
return /* @__PURE__ */ jsx17(Context, { cols, rows });
|
|
2459
2995
|
case "workflow":
|
|
2460
|
-
return /* @__PURE__ */
|
|
2996
|
+
return /* @__PURE__ */ jsx17(Workflow, { cols, rows });
|
|
2461
2997
|
case "execute":
|
|
2462
|
-
return /* @__PURE__ */
|
|
2998
|
+
return /* @__PURE__ */ jsx17(Execute, { cols, rows });
|
|
2463
2999
|
case "history":
|
|
2464
|
-
return /* @__PURE__ */
|
|
3000
|
+
return /* @__PURE__ */ jsx17(History, { cols, rows });
|
|
2465
3001
|
case "marketplace":
|
|
2466
|
-
return /* @__PURE__ */
|
|
3002
|
+
return /* @__PURE__ */ jsx17(Marketplace, { cols, rows });
|
|
2467
3003
|
case "memory":
|
|
2468
|
-
return /* @__PURE__ */
|
|
3004
|
+
return /* @__PURE__ */ jsx17(Memory, { cols, rows });
|
|
3005
|
+
case "team":
|
|
3006
|
+
return /* @__PURE__ */ jsx17(Team, { cols, rows });
|
|
3007
|
+
case "plugins":
|
|
3008
|
+
return /* @__PURE__ */ jsx17(Plugins, { cols, rows });
|
|
2469
3009
|
}
|
|
2470
3010
|
};
|
|
2471
3011
|
const contentHeight = rows - 2;
|
|
2472
|
-
return /* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2474
|
-
showSidebar && /* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
3012
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", height: rows, children: [
|
|
3013
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "row", height: contentHeight, children: [
|
|
3014
|
+
showSidebar && /* @__PURE__ */ jsx17(Sidebar, { screen, onNavigate: setScreen }),
|
|
3015
|
+
/* @__PURE__ */ jsx17(Box17, { flexDirection: "column", flexGrow: 1, marginLeft: 1, children: renderScreen() })
|
|
2476
3016
|
] }),
|
|
2477
|
-
/* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsx17(Box17, { children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "h Home m Market b Browse i Inst w Wflow x Exec a Team p Plug r Rec t Trans c Ctx e Mem s Sync , Cfg q Quit" }) })
|
|
2478
3018
|
] });
|
|
2479
3019
|
}
|
|
2480
3020
|
|
|
2481
3021
|
// src/components/Header.tsx
|
|
2482
|
-
import { Box as
|
|
2483
|
-
import { jsx as
|
|
3022
|
+
import { Box as Box18, Text as Text18 } from "ink";
|
|
3023
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2484
3024
|
function Header({ title, subtitle, count }) {
|
|
2485
|
-
return /* @__PURE__ */
|
|
2486
|
-
/* @__PURE__ */
|
|
2487
|
-
/* @__PURE__ */
|
|
2488
|
-
count !== void 0 && /* @__PURE__ */
|
|
3025
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginBottom: 1, children: [
|
|
3026
|
+
/* @__PURE__ */ jsxs18(Box18, { justifyContent: "space-between", children: [
|
|
3027
|
+
/* @__PURE__ */ jsx18(Text18, { color: colors.primary, bold: true, children: title.toUpperCase() }),
|
|
3028
|
+
count !== void 0 && /* @__PURE__ */ jsxs18(Text18, { color: colors.secondaryDim, children: [
|
|
2489
3029
|
symbols.star,
|
|
2490
3030
|
" ",
|
|
2491
3031
|
count
|
|
2492
3032
|
] })
|
|
2493
3033
|
] }),
|
|
2494
|
-
subtitle && /* @__PURE__ */
|
|
3034
|
+
subtitle && /* @__PURE__ */ jsx18(Text18, { color: colors.secondaryDim, dimColor: true, children: subtitle })
|
|
2495
3035
|
] });
|
|
2496
3036
|
}
|
|
2497
3037
|
|
|
2498
3038
|
// src/components/SkillList.tsx
|
|
2499
|
-
import { Box as
|
|
2500
|
-
import { jsx as
|
|
3039
|
+
import { Box as Box19, Text as Text19 } from "ink";
|
|
3040
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2501
3041
|
function formatInstalls(count) {
|
|
2502
3042
|
if (count >= 1e3) {
|
|
2503
3043
|
return `${(count / 1e3).toFixed(1)}K`;
|
|
@@ -2513,13 +3053,13 @@ function SkillList({
|
|
|
2513
3053
|
maxVisible = 10
|
|
2514
3054
|
}) {
|
|
2515
3055
|
if (skills.length === 0) {
|
|
2516
|
-
return /* @__PURE__ */
|
|
3056
|
+
return /* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsx19(Text19, { color: colors.secondaryDim, dimColor: true, children: "No skills found" }) });
|
|
2517
3057
|
}
|
|
2518
3058
|
const startIndex = Math.max(0, selectedIndex - Math.floor(maxVisible / 2));
|
|
2519
3059
|
const visibleSkills = skills.slice(startIndex, startIndex + maxVisible);
|
|
2520
3060
|
const actualStartIndex = startIndex;
|
|
2521
|
-
return /* @__PURE__ */
|
|
2522
|
-
showRank && /* @__PURE__ */
|
|
3061
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
3062
|
+
showRank && /* @__PURE__ */ jsx19(Box19, { marginBottom: 1, children: /* @__PURE__ */ jsxs19(Text19, { color: colors.secondaryDim, children: [
|
|
2523
3063
|
" # SKILL",
|
|
2524
3064
|
showSource && " SOURCE",
|
|
2525
3065
|
showInstalls && " INSTALLS"
|
|
@@ -2529,9 +3069,9 @@ function SkillList({
|
|
|
2529
3069
|
const isSelected = realIndex === selectedIndex;
|
|
2530
3070
|
const skillName = skill.name.padEnd(28).slice(0, 28);
|
|
2531
3071
|
const sourceName = skill.source ? skill.source.slice(0, 25) : "";
|
|
2532
|
-
return /* @__PURE__ */
|
|
2533
|
-
/* @__PURE__ */
|
|
2534
|
-
|
|
3072
|
+
return /* @__PURE__ */ jsxs19(Box19, { children: [
|
|
3073
|
+
/* @__PURE__ */ jsxs19(
|
|
3074
|
+
Text19,
|
|
2535
3075
|
{
|
|
2536
3076
|
color: isSelected ? colors.primary : colors.secondary,
|
|
2537
3077
|
bold: isSelected,
|
|
@@ -2544,14 +3084,14 @@ function SkillList({
|
|
|
2544
3084
|
]
|
|
2545
3085
|
}
|
|
2546
3086
|
),
|
|
2547
|
-
showSource && /* @__PURE__ */
|
|
3087
|
+
showSource && /* @__PURE__ */ jsxs19(Text19, { color: colors.secondaryDim, dimColor: !isSelected, children: [
|
|
2548
3088
|
" ",
|
|
2549
3089
|
sourceName
|
|
2550
3090
|
] }),
|
|
2551
|
-
showInstalls && skill.installs !== void 0 && /* @__PURE__ */
|
|
3091
|
+
showInstalls && skill.installs !== void 0 && /* @__PURE__ */ jsx19(Text19, { color: colors.secondaryDim, children: formatInstalls(skill.installs).padStart(8) })
|
|
2552
3092
|
] }, `${skill.source}-${skill.name}`);
|
|
2553
3093
|
}),
|
|
2554
|
-
skills.length > maxVisible && /* @__PURE__ */
|
|
3094
|
+
skills.length > maxVisible && /* @__PURE__ */ jsx19(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs19(Text19, { color: colors.secondaryDim, dimColor: true, children: [
|
|
2555
3095
|
"Showing ",
|
|
2556
3096
|
startIndex + 1,
|
|
2557
3097
|
"-",
|
|
@@ -2563,11 +3103,11 @@ function SkillList({
|
|
|
2563
3103
|
}
|
|
2564
3104
|
|
|
2565
3105
|
// src/components/StatusBar.tsx
|
|
2566
|
-
import { Box as
|
|
2567
|
-
import { jsx as
|
|
3106
|
+
import { Box as Box20, Text as Text20 } from "ink";
|
|
3107
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2568
3108
|
function StatusBar({ shortcuts, message }) {
|
|
2569
|
-
return /* @__PURE__ */
|
|
2570
|
-
|
|
3109
|
+
return /* @__PURE__ */ jsxs20(
|
|
3110
|
+
Box20,
|
|
2571
3111
|
{
|
|
2572
3112
|
borderStyle: "single",
|
|
2573
3113
|
borderColor: colors.borderDim,
|
|
@@ -2578,11 +3118,11 @@ function StatusBar({ shortcuts, message }) {
|
|
|
2578
3118
|
paddingX: 1,
|
|
2579
3119
|
justifyContent: "space-between",
|
|
2580
3120
|
children: [
|
|
2581
|
-
/* @__PURE__ */
|
|
2582
|
-
/* @__PURE__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
3121
|
+
/* @__PURE__ */ jsx20(Box20, { gap: 2, children: shortcuts.map((shortcut, idx) => /* @__PURE__ */ jsxs20(Box20, { gap: 1, children: [
|
|
3122
|
+
/* @__PURE__ */ jsx20(Text20, { color: colors.primary, bold: true, children: shortcut.key }),
|
|
3123
|
+
/* @__PURE__ */ jsx20(Text20, { color: colors.secondaryDim, children: shortcut.label })
|
|
2584
3124
|
] }, idx)) }),
|
|
2585
|
-
message && /* @__PURE__ */
|
|
3125
|
+
message && /* @__PURE__ */ jsxs20(Text20, { color: colors.success, children: [
|
|
2586
3126
|
symbols.check,
|
|
2587
3127
|
" ",
|
|
2588
3128
|
message
|
|
@@ -2593,44 +3133,44 @@ function StatusBar({ shortcuts, message }) {
|
|
|
2593
3133
|
}
|
|
2594
3134
|
|
|
2595
3135
|
// src/components/SearchInput.tsx
|
|
2596
|
-
import { Box as
|
|
2597
|
-
import
|
|
2598
|
-
import { jsx as
|
|
3136
|
+
import { Box as Box21, Text as Text21 } from "ink";
|
|
3137
|
+
import TextInput2 from "ink-text-input";
|
|
3138
|
+
import { jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2599
3139
|
function SearchInput({
|
|
2600
3140
|
value,
|
|
2601
3141
|
onChange,
|
|
2602
3142
|
placeholder = "Search skills...",
|
|
2603
3143
|
isFocused = false
|
|
2604
3144
|
}) {
|
|
2605
|
-
return /* @__PURE__ */
|
|
2606
|
-
|
|
3145
|
+
return /* @__PURE__ */ jsxs21(
|
|
3146
|
+
Box21,
|
|
2607
3147
|
{
|
|
2608
3148
|
borderStyle: "single",
|
|
2609
3149
|
borderColor: isFocused ? colors.primary : colors.borderDim,
|
|
2610
3150
|
paddingX: 1,
|
|
2611
3151
|
children: [
|
|
2612
|
-
/* @__PURE__ */
|
|
2613
|
-
isFocused ? /* @__PURE__ */
|
|
2614
|
-
|
|
3152
|
+
/* @__PURE__ */ jsx21(Text21, { color: colors.secondaryDim, children: "/ " }),
|
|
3153
|
+
isFocused ? /* @__PURE__ */ jsx21(
|
|
3154
|
+
TextInput2,
|
|
2615
3155
|
{
|
|
2616
3156
|
value,
|
|
2617
3157
|
onChange,
|
|
2618
3158
|
placeholder
|
|
2619
3159
|
}
|
|
2620
|
-
) : /* @__PURE__ */
|
|
2621
|
-
/* @__PURE__ */
|
|
2622
|
-
/* @__PURE__ */
|
|
3160
|
+
) : /* @__PURE__ */ jsx21(Text21, { color: value ? colors.secondary : colors.secondaryDim, children: value || placeholder }),
|
|
3161
|
+
/* @__PURE__ */ jsx21(Box21, { flexGrow: 1 }),
|
|
3162
|
+
/* @__PURE__ */ jsx21(Text21, { color: colors.secondaryDim, children: "/" })
|
|
2623
3163
|
]
|
|
2624
3164
|
}
|
|
2625
3165
|
);
|
|
2626
3166
|
}
|
|
2627
3167
|
|
|
2628
3168
|
// src/hooks/useKeyboard.ts
|
|
2629
|
-
import { useState as
|
|
2630
|
-
import { useInput as
|
|
3169
|
+
import { useState as useState20, useCallback as useCallback3, useEffect as useEffect16 } from "react";
|
|
3170
|
+
import { useInput as useInput16, useApp as useApp2 } from "ink";
|
|
2631
3171
|
function useKeyboard(options = {}) {
|
|
2632
3172
|
const { exit } = useApp2();
|
|
2633
|
-
|
|
3173
|
+
useInput16((input, key) => {
|
|
2634
3174
|
if (options.disabled) return;
|
|
2635
3175
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2636
3176
|
exit();
|
|
@@ -2674,8 +3214,8 @@ function useKeyboard(options = {}) {
|
|
|
2674
3214
|
});
|
|
2675
3215
|
}
|
|
2676
3216
|
function useListNavigation(listLength, initialIndex = 0) {
|
|
2677
|
-
const [selectedIndex, setSelectedIndex] =
|
|
2678
|
-
|
|
3217
|
+
const [selectedIndex, setSelectedIndex] = useState20(initialIndex);
|
|
3218
|
+
useEffect16(() => {
|
|
2679
3219
|
if (selectedIndex >= listLength && listLength > 0) {
|
|
2680
3220
|
setSelectedIndex(listLength - 1);
|
|
2681
3221
|
}
|
|
@@ -2693,7 +3233,7 @@ function useListNavigation(listLength, initialIndex = 0) {
|
|
|
2693
3233
|
}
|
|
2694
3234
|
|
|
2695
3235
|
// src/hooks/useMemory.ts
|
|
2696
|
-
import { useState as
|
|
3236
|
+
import { useState as useState21, useEffect as useEffect17, useCallback as useCallback4 } from "react";
|
|
2697
3237
|
import {
|
|
2698
3238
|
LearningStore as LearningStore2,
|
|
2699
3239
|
ObservationStore as ObservationStore2,
|
|
@@ -2701,12 +3241,12 @@ import {
|
|
|
2701
3241
|
createMemoryInjector as createMemoryInjector2
|
|
2702
3242
|
} from "@skillkit/core";
|
|
2703
3243
|
function useMemory() {
|
|
2704
|
-
const [learnings, setLearnings] =
|
|
2705
|
-
const [observations, setObservations] =
|
|
2706
|
-
const [status, setStatus] =
|
|
2707
|
-
const [loading, setLoading] =
|
|
2708
|
-
const [error, setError] =
|
|
2709
|
-
const [isGlobal, setIsGlobal] =
|
|
3244
|
+
const [learnings, setLearnings] = useState21([]);
|
|
3245
|
+
const [observations, setObservations] = useState21([]);
|
|
3246
|
+
const [status, setStatus] = useState21(null);
|
|
3247
|
+
const [loading, setLoading] = useState21(true);
|
|
3248
|
+
const [error, setError] = useState21(null);
|
|
3249
|
+
const [isGlobal, setIsGlobal] = useState21(false);
|
|
2710
3250
|
const projectPath = process.cwd();
|
|
2711
3251
|
const refresh = useCallback4(() => {
|
|
2712
3252
|
setLoading(true);
|
|
@@ -2785,7 +3325,7 @@ function useMemory() {
|
|
|
2785
3325
|
},
|
|
2786
3326
|
[projectPath, refresh]
|
|
2787
3327
|
);
|
|
2788
|
-
|
|
3328
|
+
useEffect17(() => {
|
|
2789
3329
|
refresh();
|
|
2790
3330
|
}, [refresh]);
|
|
2791
3331
|
return {
|
|
@@ -2804,10 +3344,10 @@ function useMemory() {
|
|
|
2804
3344
|
}
|
|
2805
3345
|
|
|
2806
3346
|
// src/index.tsx
|
|
2807
|
-
import { jsx as
|
|
3347
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2808
3348
|
function startTUI() {
|
|
2809
3349
|
process.stdout.write("\x1B[2J\x1B[0f");
|
|
2810
|
-
const { waitUntilExit, clear } = render(/* @__PURE__ */
|
|
3350
|
+
const { waitUntilExit, clear } = render(/* @__PURE__ */ jsx22(App, {}), {
|
|
2811
3351
|
exitOnCtrlC: true
|
|
2812
3352
|
});
|
|
2813
3353
|
return waitUntilExit().then(() => {
|
|
@@ -2825,6 +3365,7 @@ export {
|
|
|
2825
3365
|
Installed,
|
|
2826
3366
|
Marketplace,
|
|
2827
3367
|
Memory,
|
|
3368
|
+
Plugins,
|
|
2828
3369
|
Recommend,
|
|
2829
3370
|
SearchInput,
|
|
2830
3371
|
Settings,
|
|
@@ -2832,6 +3373,7 @@ export {
|
|
|
2832
3373
|
SkillList,
|
|
2833
3374
|
StatusBar,
|
|
2834
3375
|
Sync,
|
|
3376
|
+
Team,
|
|
2835
3377
|
Translate,
|
|
2836
3378
|
Workflow,
|
|
2837
3379
|
colors,
|