@skillkit/tui 1.5.0 → 1.6.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/README.md +68 -5
- package/dist/index.d.ts +28 -16
- package/dist/index.js +543 -81
- 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 useState21 } from "react";
|
|
6
|
+
import { Box as Box19, Text as Text19, useInput as useInput17, useApp, useStdout } from "ink";
|
|
7
7
|
|
|
8
8
|
// src/components/Sidebar.tsx
|
|
9
9
|
import { Box, Text } from "ink";
|
|
@@ -58,6 +58,9 @@ var NAV = [
|
|
|
58
58
|
// Collaboration
|
|
59
59
|
{ id: "team", label: "Team", key: "a" },
|
|
60
60
|
{ id: "plugins", label: "Plugins", key: "p" },
|
|
61
|
+
// Methodology
|
|
62
|
+
{ id: "methodology", label: "Methodology", key: "o" },
|
|
63
|
+
{ id: "plan", label: "Plans", key: "n" },
|
|
61
64
|
// Tools
|
|
62
65
|
{ id: "recommend", label: "Recommend", key: "r" },
|
|
63
66
|
{ id: "translate", label: "Translate", key: "t" },
|
|
@@ -86,12 +89,17 @@ function Sidebar({ screen }) {
|
|
|
86
89
|
item.label
|
|
87
90
|
] }, item.id)),
|
|
88
91
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
89
|
-
NAV.slice(8,
|
|
92
|
+
NAV.slice(8, 10).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
90
93
|
screen === item.id ? symbols.bullet : " ",
|
|
91
94
|
item.label
|
|
92
95
|
] }, item.id)),
|
|
93
96
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
94
|
-
NAV.slice(
|
|
97
|
+
NAV.slice(10, 14).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
98
|
+
screen === item.id ? symbols.bullet : " ",
|
|
99
|
+
item.label
|
|
100
|
+
] }, item.id)),
|
|
101
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
102
|
+
NAV.slice(14).map((item) => /* @__PURE__ */ jsxs(Text, { inverse: screen === item.id, children: [
|
|
95
103
|
screen === item.id ? symbols.bullet : " ",
|
|
96
104
|
item.label
|
|
97
105
|
] }, item.id)),
|
|
@@ -2777,9 +2785,9 @@ function Plugins({ rows = 24 }) {
|
|
|
2777
2785
|
setError(null);
|
|
2778
2786
|
try {
|
|
2779
2787
|
const { createPluginManager, loadPluginsFromDirectory } = await import("@skillkit/core");
|
|
2780
|
-
const { join:
|
|
2788
|
+
const { join: join7 } = await import("path");
|
|
2781
2789
|
const manager = createPluginManager(process.cwd());
|
|
2782
|
-
const pluginsDir =
|
|
2790
|
+
const pluginsDir = join7(process.cwd(), ".skillkit", "plugins");
|
|
2783
2791
|
try {
|
|
2784
2792
|
const loadedPlugins = await loadPluginsFromDirectory(pluginsDir);
|
|
2785
2793
|
for (const plugin of loadedPlugins) {
|
|
@@ -2817,9 +2825,9 @@ function Plugins({ rows = 24 }) {
|
|
|
2817
2825
|
setMessage(null);
|
|
2818
2826
|
try {
|
|
2819
2827
|
const { createPluginManager, loadPluginsFromDirectory } = await import("@skillkit/core");
|
|
2820
|
-
const { join:
|
|
2828
|
+
const { join: join7 } = await import("path");
|
|
2821
2829
|
const manager = createPluginManager(process.cwd());
|
|
2822
|
-
const pluginsDir =
|
|
2830
|
+
const pluginsDir = join7(process.cwd(), ".skillkit", "plugins");
|
|
2823
2831
|
try {
|
|
2824
2832
|
const loadedPlugins = await loadPluginsFromDirectory(pluginsDir);
|
|
2825
2833
|
for (const plugin of loadedPlugins) {
|
|
@@ -2934,10 +2942,456 @@ function Plugins({ rows = 24 }) {
|
|
|
2934
2942
|
] });
|
|
2935
2943
|
}
|
|
2936
2944
|
|
|
2945
|
+
// src/screens/Methodology.tsx
|
|
2946
|
+
import { useState as useState19, useEffect as useEffect16, useMemo } from "react";
|
|
2947
|
+
import { Box as Box17, Text as Text17, useInput as useInput15 } from "ink";
|
|
2948
|
+
import {
|
|
2949
|
+
MethodologyManager
|
|
2950
|
+
} from "@skillkit/core";
|
|
2951
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2952
|
+
function Methodology({ rows = 24 }) {
|
|
2953
|
+
const [packs, setPacks] = useState19([]);
|
|
2954
|
+
const [selectedPack, setSelectedPack] = useState19(null);
|
|
2955
|
+
const [skills, setSkills] = useState19([]);
|
|
2956
|
+
const [loading, setLoading] = useState19(true);
|
|
2957
|
+
const [view, setView] = useState19("packs");
|
|
2958
|
+
const [sel, setSel] = useState19(0);
|
|
2959
|
+
const [error, setError] = useState19(null);
|
|
2960
|
+
const [message, setMessage] = useState19(null);
|
|
2961
|
+
const manager = useMemo(() => new MethodologyManager({
|
|
2962
|
+
projectPath: process.cwd()
|
|
2963
|
+
}), []);
|
|
2964
|
+
const maxVisible = Math.max(5, rows - 10);
|
|
2965
|
+
useEffect16(() => {
|
|
2966
|
+
loadPacks();
|
|
2967
|
+
}, []);
|
|
2968
|
+
const loadPacks = async () => {
|
|
2969
|
+
setLoading(true);
|
|
2970
|
+
setError(null);
|
|
2971
|
+
try {
|
|
2972
|
+
const loadedPacks = await manager.listAvailablePacks();
|
|
2973
|
+
setPacks(loadedPacks);
|
|
2974
|
+
} catch (e) {
|
|
2975
|
+
setError(e instanceof Error ? e.message : "Failed to load methodology packs");
|
|
2976
|
+
}
|
|
2977
|
+
setLoading(false);
|
|
2978
|
+
};
|
|
2979
|
+
const loadSkills = async (pack) => {
|
|
2980
|
+
setLoading(true);
|
|
2981
|
+
setError(null);
|
|
2982
|
+
try {
|
|
2983
|
+
const loader = manager.getLoader();
|
|
2984
|
+
const loadedSkills = await loader.loadPackSkills(pack.name);
|
|
2985
|
+
setSkills(loadedSkills);
|
|
2986
|
+
setSelectedPack(pack);
|
|
2987
|
+
setView("skills");
|
|
2988
|
+
setSel(0);
|
|
2989
|
+
} catch (e) {
|
|
2990
|
+
setError(e instanceof Error ? e.message : "Failed to load skills");
|
|
2991
|
+
}
|
|
2992
|
+
setLoading(false);
|
|
2993
|
+
};
|
|
2994
|
+
const installPack = async (pack) => {
|
|
2995
|
+
setLoading(true);
|
|
2996
|
+
setMessage(null);
|
|
2997
|
+
try {
|
|
2998
|
+
await manager.installPack(pack.name);
|
|
2999
|
+
setMessage(`Installed ${pack.name} methodology pack`);
|
|
3000
|
+
await loadPacks();
|
|
3001
|
+
} catch (e) {
|
|
3002
|
+
setError(e instanceof Error ? e.message : "Failed to install pack");
|
|
3003
|
+
}
|
|
3004
|
+
setLoading(false);
|
|
3005
|
+
};
|
|
3006
|
+
const items = view === "packs" ? packs : skills;
|
|
3007
|
+
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
3008
|
+
const visible = items.slice(start, start + maxVisible);
|
|
3009
|
+
useInput15((input, key) => {
|
|
3010
|
+
if (loading) return;
|
|
3011
|
+
if (key.upArrow) setSel((i) => Math.max(0, i - 1));
|
|
3012
|
+
else if (key.downArrow) setSel((i) => Math.min(items.length - 1, i + 1));
|
|
3013
|
+
else if (input === "r") {
|
|
3014
|
+
if (view === "packs") loadPacks();
|
|
3015
|
+
else if (selectedPack) loadSkills(selectedPack);
|
|
3016
|
+
} else if (key.escape || input === "b") {
|
|
3017
|
+
if (view === "skills") {
|
|
3018
|
+
setView("packs");
|
|
3019
|
+
setSel(0);
|
|
3020
|
+
setSelectedPack(null);
|
|
3021
|
+
}
|
|
3022
|
+
} else if (key.return) {
|
|
3023
|
+
if (view === "packs" && packs[sel]) {
|
|
3024
|
+
loadSkills(packs[sel]);
|
|
3025
|
+
}
|
|
3026
|
+
} else if (input === "i" && view === "packs" && packs[sel]) {
|
|
3027
|
+
installPack(packs[sel]);
|
|
3028
|
+
}
|
|
3029
|
+
});
|
|
3030
|
+
const renderPackItem = (pack, idx) => {
|
|
3031
|
+
const isSel = idx === sel;
|
|
3032
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
3033
|
+
/* @__PURE__ */ jsxs17(Text17, { inverse: isSel, children: [
|
|
3034
|
+
isSel ? symbols.pointer : " ",
|
|
3035
|
+
" ",
|
|
3036
|
+
pack.name,
|
|
3037
|
+
" ",
|
|
3038
|
+
/* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3039
|
+
"v",
|
|
3040
|
+
pack.version
|
|
3041
|
+
] })
|
|
3042
|
+
] }),
|
|
3043
|
+
isSel && /* @__PURE__ */ jsxs17(Fragment2, { children: [
|
|
3044
|
+
/* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3045
|
+
" ",
|
|
3046
|
+
pack.description
|
|
3047
|
+
] }),
|
|
3048
|
+
/* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3049
|
+
" ",
|
|
3050
|
+
pack.skills.length,
|
|
3051
|
+
" skill(s) | Tags: ",
|
|
3052
|
+
pack.tags?.join(", ") || "none"
|
|
3053
|
+
] })
|
|
3054
|
+
] })
|
|
3055
|
+
] }, pack.name);
|
|
3056
|
+
};
|
|
3057
|
+
const renderSkillItem = (skill, idx) => {
|
|
3058
|
+
const isSel = idx === sel;
|
|
3059
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
3060
|
+
/* @__PURE__ */ jsxs17(Text17, { inverse: isSel, children: [
|
|
3061
|
+
isSel ? symbols.pointer : " ",
|
|
3062
|
+
" ",
|
|
3063
|
+
skill.name
|
|
3064
|
+
] }),
|
|
3065
|
+
isSel && skill.description && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3066
|
+
" ",
|
|
3067
|
+
skill.description
|
|
3068
|
+
] }),
|
|
3069
|
+
isSel && skill.tags && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3070
|
+
" Tags: ",
|
|
3071
|
+
skill.tags.join(", ")
|
|
3072
|
+
] })
|
|
3073
|
+
] }, skill.name);
|
|
3074
|
+
};
|
|
3075
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
3076
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: colors.primary, children: view === "packs" ? "METHODOLOGY PACKS" : `${selectedPack?.name.toUpperCase()} SKILLS` }),
|
|
3077
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: view === "packs" ? `${packs.length} pack(s) available` : `${skills.length} skill(s) in pack` }),
|
|
3078
|
+
loading && /* @__PURE__ */ jsx17(Text17, { color: "yellow", children: "Loading..." }),
|
|
3079
|
+
error && /* @__PURE__ */ jsxs17(Text17, { color: "red", children: [
|
|
3080
|
+
symbols.error,
|
|
3081
|
+
" ",
|
|
3082
|
+
error
|
|
3083
|
+
] }),
|
|
3084
|
+
message && /* @__PURE__ */ jsxs17(Text17, { color: "green", children: [
|
|
3085
|
+
symbols.success,
|
|
3086
|
+
" ",
|
|
3087
|
+
message
|
|
3088
|
+
] }),
|
|
3089
|
+
!loading && items.length === 0 && /* @__PURE__ */ jsx17(Box17, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3090
|
+
"No ",
|
|
3091
|
+
view === "packs" ? "methodology packs" : "skills",
|
|
3092
|
+
" found."
|
|
3093
|
+
] }) }),
|
|
3094
|
+
!loading && items.length > 0 && /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
|
|
3095
|
+
start > 0 && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3096
|
+
" ",
|
|
3097
|
+
symbols.arrowUp,
|
|
3098
|
+
" ",
|
|
3099
|
+
start,
|
|
3100
|
+
" more"
|
|
3101
|
+
] }),
|
|
3102
|
+
view === "packs" ? visible.map((pack, i) => renderPackItem(pack, start + i)) : visible.map((skill, i) => renderSkillItem(skill, start + i)),
|
|
3103
|
+
start + maxVisible < items.length && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
3104
|
+
" ",
|
|
3105
|
+
symbols.arrowDown,
|
|
3106
|
+
" ",
|
|
3107
|
+
items.length - start - maxVisible,
|
|
3108
|
+
" more"
|
|
3109
|
+
] })
|
|
3110
|
+
] }),
|
|
3111
|
+
/* @__PURE__ */ jsx17(Box17, { marginTop: 1, flexDirection: "column", children: view === "packs" ? /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Enter=view skills i=install r=refresh q=quit" }) : /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "b/Esc=back r=refresh q=quit" }) })
|
|
3112
|
+
] });
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
// src/screens/Plan.tsx
|
|
3116
|
+
import { useState as useState20, useEffect as useEffect17, useMemo as useMemo2 } from "react";
|
|
3117
|
+
import { Box as Box18, Text as Text18, useInput as useInput16 } from "ink";
|
|
3118
|
+
import {
|
|
3119
|
+
PlanParser,
|
|
3120
|
+
PlanValidator,
|
|
3121
|
+
PlanExecutor
|
|
3122
|
+
} from "@skillkit/core";
|
|
3123
|
+
import * as fs from "fs";
|
|
3124
|
+
import * as path from "path";
|
|
3125
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3126
|
+
function Plan({ rows = 24 }) {
|
|
3127
|
+
const [planFiles, setPlanFiles] = useState20([]);
|
|
3128
|
+
const [selectedPlan, setSelectedPlan] = useState20(null);
|
|
3129
|
+
const [selectedTask, setSelectedTask] = useState20(null);
|
|
3130
|
+
const [loading, setLoading] = useState20(true);
|
|
3131
|
+
const [view, setView] = useState20("plans");
|
|
3132
|
+
const [sel, setSel] = useState20(0);
|
|
3133
|
+
const [error, setError] = useState20(null);
|
|
3134
|
+
const [executing, setExecuting] = useState20(false);
|
|
3135
|
+
const [message, setMessage] = useState20(null);
|
|
3136
|
+
const parser = useMemo2(() => new PlanParser(), []);
|
|
3137
|
+
const validator = useMemo2(() => new PlanValidator(), []);
|
|
3138
|
+
const maxVisible = Math.max(5, rows - 10);
|
|
3139
|
+
useEffect17(() => {
|
|
3140
|
+
loadPlans();
|
|
3141
|
+
}, []);
|
|
3142
|
+
const loadPlans = async () => {
|
|
3143
|
+
setLoading(true);
|
|
3144
|
+
setError(null);
|
|
3145
|
+
try {
|
|
3146
|
+
const cwd = process.cwd();
|
|
3147
|
+
const files = [];
|
|
3148
|
+
const searchPaths = [
|
|
3149
|
+
cwd,
|
|
3150
|
+
path.join(cwd, "plans"),
|
|
3151
|
+
path.join(cwd, ".skillkit", "plans")
|
|
3152
|
+
];
|
|
3153
|
+
for (const searchPath of searchPaths) {
|
|
3154
|
+
if (fs.existsSync(searchPath)) {
|
|
3155
|
+
const entries = fs.readdirSync(searchPath, { withFileTypes: true });
|
|
3156
|
+
for (const entry of entries) {
|
|
3157
|
+
if (entry.isFile() && (entry.name.endsWith(".plan.md") || entry.name.endsWith("-plan.md"))) {
|
|
3158
|
+
const filePath = path.join(searchPath, entry.name);
|
|
3159
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
3160
|
+
try {
|
|
3161
|
+
const plan = parser.parse(content);
|
|
3162
|
+
const validation = validator.validate(plan);
|
|
3163
|
+
const errorIssue = validation.issues.find((i) => i.type === "error");
|
|
3164
|
+
files.push({
|
|
3165
|
+
name: entry.name,
|
|
3166
|
+
path: filePath,
|
|
3167
|
+
plan,
|
|
3168
|
+
valid: validation.valid,
|
|
3169
|
+
error: errorIssue?.message
|
|
3170
|
+
});
|
|
3171
|
+
} catch {
|
|
3172
|
+
files.push({
|
|
3173
|
+
name: entry.name,
|
|
3174
|
+
path: filePath,
|
|
3175
|
+
valid: false,
|
|
3176
|
+
error: "Failed to parse plan"
|
|
3177
|
+
});
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
setPlanFiles(files);
|
|
3184
|
+
} catch (e) {
|
|
3185
|
+
setError(e instanceof Error ? e.message : "Failed to load plans");
|
|
3186
|
+
}
|
|
3187
|
+
setLoading(false);
|
|
3188
|
+
};
|
|
3189
|
+
const selectPlan = (planFile) => {
|
|
3190
|
+
if (planFile.plan) {
|
|
3191
|
+
setSelectedPlan(planFile);
|
|
3192
|
+
setView("tasks");
|
|
3193
|
+
setSel(0);
|
|
3194
|
+
}
|
|
3195
|
+
};
|
|
3196
|
+
const selectTask = (task) => {
|
|
3197
|
+
setSelectedTask(task);
|
|
3198
|
+
setView("steps");
|
|
3199
|
+
setSel(0);
|
|
3200
|
+
};
|
|
3201
|
+
const executePlan = async (planFile) => {
|
|
3202
|
+
if (!planFile.plan) return;
|
|
3203
|
+
setExecuting(true);
|
|
3204
|
+
setMessage(null);
|
|
3205
|
+
try {
|
|
3206
|
+
const executor = new PlanExecutor();
|
|
3207
|
+
await executor.execute(planFile.plan, { dryRun: true });
|
|
3208
|
+
setMessage(`Executed plan: ${planFile.plan.name} (dry run)`);
|
|
3209
|
+
} catch (e) {
|
|
3210
|
+
setError(e instanceof Error ? e.message : "Failed to execute plan");
|
|
3211
|
+
}
|
|
3212
|
+
setExecuting(false);
|
|
3213
|
+
};
|
|
3214
|
+
const getItems = () => {
|
|
3215
|
+
if (view === "plans") return planFiles;
|
|
3216
|
+
if (view === "tasks" && selectedPlan?.plan) return selectedPlan.plan.tasks;
|
|
3217
|
+
if (view === "steps" && selectedTask) return selectedTask.steps;
|
|
3218
|
+
return [];
|
|
3219
|
+
};
|
|
3220
|
+
const items = getItems();
|
|
3221
|
+
const start = Math.max(0, Math.min(sel - Math.floor(maxVisible / 2), items.length - maxVisible));
|
|
3222
|
+
const visible = items.slice(start, start + maxVisible);
|
|
3223
|
+
useInput16((input, key) => {
|
|
3224
|
+
if (loading || executing) return;
|
|
3225
|
+
if (key.upArrow) setSel((i) => Math.max(0, i - 1));
|
|
3226
|
+
else if (key.downArrow) setSel((i) => Math.min(items.length - 1, i + 1));
|
|
3227
|
+
else if (input === "r") loadPlans();
|
|
3228
|
+
else if (key.escape || input === "b") {
|
|
3229
|
+
if (view === "steps") {
|
|
3230
|
+
setView("tasks");
|
|
3231
|
+
setSelectedTask(null);
|
|
3232
|
+
setSel(0);
|
|
3233
|
+
} else if (view === "tasks") {
|
|
3234
|
+
setView("plans");
|
|
3235
|
+
setSelectedPlan(null);
|
|
3236
|
+
setSel(0);
|
|
3237
|
+
}
|
|
3238
|
+
} else if (key.return) {
|
|
3239
|
+
if (view === "plans" && planFiles[sel]) {
|
|
3240
|
+
selectPlan(planFiles[sel]);
|
|
3241
|
+
} else if (view === "tasks" && selectedPlan?.plan?.tasks[sel]) {
|
|
3242
|
+
selectTask(selectedPlan.plan.tasks[sel]);
|
|
3243
|
+
}
|
|
3244
|
+
} else if (input === "x" && view === "plans" && planFiles[sel]?.plan) {
|
|
3245
|
+
executePlan(planFiles[sel]);
|
|
3246
|
+
}
|
|
3247
|
+
});
|
|
3248
|
+
const renderPlanItem = (planFile, idx) => {
|
|
3249
|
+
const isSel = idx === sel;
|
|
3250
|
+
const statusIcon = planFile.valid ? symbols.success : symbols.error;
|
|
3251
|
+
const statusColor = planFile.valid ? "green" : "red";
|
|
3252
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
3253
|
+
/* @__PURE__ */ jsxs18(Text18, { inverse: isSel, children: [
|
|
3254
|
+
isSel ? symbols.pointer : " ",
|
|
3255
|
+
" ",
|
|
3256
|
+
/* @__PURE__ */ jsx18(Text18, { color: statusColor, children: statusIcon }),
|
|
3257
|
+
" ",
|
|
3258
|
+
planFile.name
|
|
3259
|
+
] }),
|
|
3260
|
+
isSel && planFile.plan && /* @__PURE__ */ jsxs18(Fragment3, { children: [
|
|
3261
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3262
|
+
" ",
|
|
3263
|
+
planFile.plan.goal
|
|
3264
|
+
] }),
|
|
3265
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3266
|
+
" ",
|
|
3267
|
+
planFile.plan.tasks.length,
|
|
3268
|
+
" task(s) | ",
|
|
3269
|
+
planFile.plan.techStack?.join(", ") || "No stack"
|
|
3270
|
+
] })
|
|
3271
|
+
] }),
|
|
3272
|
+
isSel && planFile.error && /* @__PURE__ */ jsxs18(Text18, { color: "red", children: [
|
|
3273
|
+
" ",
|
|
3274
|
+
planFile.error
|
|
3275
|
+
] })
|
|
3276
|
+
] }, planFile.path);
|
|
3277
|
+
};
|
|
3278
|
+
const renderTaskItem = (task, idx) => {
|
|
3279
|
+
const isSel = idx === sel;
|
|
3280
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
3281
|
+
/* @__PURE__ */ jsxs18(Text18, { inverse: isSel, children: [
|
|
3282
|
+
isSel ? symbols.pointer : " ",
|
|
3283
|
+
" [",
|
|
3284
|
+
task.id,
|
|
3285
|
+
"] ",
|
|
3286
|
+
task.name
|
|
3287
|
+
] }),
|
|
3288
|
+
isSel && /* @__PURE__ */ jsxs18(Fragment3, { children: [
|
|
3289
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3290
|
+
" ",
|
|
3291
|
+
task.steps.length,
|
|
3292
|
+
" step(s)"
|
|
3293
|
+
] }),
|
|
3294
|
+
task.files?.create && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3295
|
+
" Create: ",
|
|
3296
|
+
task.files.create.join(", ")
|
|
3297
|
+
] }),
|
|
3298
|
+
task.files?.modify && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3299
|
+
" Modify: ",
|
|
3300
|
+
task.files.modify.join(", ")
|
|
3301
|
+
] }),
|
|
3302
|
+
task.files?.test && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3303
|
+
" Test: ",
|
|
3304
|
+
task.files.test.join(", ")
|
|
3305
|
+
] })
|
|
3306
|
+
] })
|
|
3307
|
+
] }, task.id);
|
|
3308
|
+
};
|
|
3309
|
+
const renderStepItem = (step, idx) => {
|
|
3310
|
+
const isSel = idx === sel;
|
|
3311
|
+
const typeColors = {
|
|
3312
|
+
test: "yellow",
|
|
3313
|
+
verify: "cyan",
|
|
3314
|
+
implement: "green",
|
|
3315
|
+
commit: "magenta"
|
|
3316
|
+
};
|
|
3317
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
3318
|
+
/* @__PURE__ */ jsxs18(Text18, { inverse: isSel, children: [
|
|
3319
|
+
isSel ? symbols.pointer : " ",
|
|
3320
|
+
" ",
|
|
3321
|
+
/* @__PURE__ */ jsxs18(Text18, { color: typeColors[step.type] || "white", children: [
|
|
3322
|
+
"[",
|
|
3323
|
+
step.type,
|
|
3324
|
+
"]"
|
|
3325
|
+
] }),
|
|
3326
|
+
" Step ",
|
|
3327
|
+
step.number
|
|
3328
|
+
] }),
|
|
3329
|
+
isSel && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3330
|
+
" ",
|
|
3331
|
+
step.description
|
|
3332
|
+
] })
|
|
3333
|
+
] }, step.number);
|
|
3334
|
+
};
|
|
3335
|
+
const getTitle = () => {
|
|
3336
|
+
if (view === "plans") return "PLANS";
|
|
3337
|
+
if (view === "tasks") return `TASKS: ${selectedPlan?.plan?.name || ""}`;
|
|
3338
|
+
if (view === "steps") return `STEPS: Task ${selectedTask?.id}`;
|
|
3339
|
+
return "PLANS";
|
|
3340
|
+
};
|
|
3341
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
3342
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, color: colors.primary, children: getTitle() }),
|
|
3343
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3344
|
+
view === "plans" && `${planFiles.length} plan(s) found`,
|
|
3345
|
+
view === "tasks" && selectedPlan?.plan && `${selectedPlan.plan.tasks.length} task(s)`,
|
|
3346
|
+
view === "steps" && selectedTask && `${selectedTask.steps.length} step(s)`
|
|
3347
|
+
] }),
|
|
3348
|
+
loading && /* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "Loading plans..." }),
|
|
3349
|
+
executing && /* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "Executing plan..." }),
|
|
3350
|
+
error && /* @__PURE__ */ jsxs18(Text18, { color: "red", children: [
|
|
3351
|
+
symbols.error,
|
|
3352
|
+
" ",
|
|
3353
|
+
error
|
|
3354
|
+
] }),
|
|
3355
|
+
message && /* @__PURE__ */ jsxs18(Text18, { color: "green", children: [
|
|
3356
|
+
symbols.success,
|
|
3357
|
+
" ",
|
|
3358
|
+
message
|
|
3359
|
+
] }),
|
|
3360
|
+
!loading && !executing && items.length === 0 && /* @__PURE__ */ jsxs18(Box18, { marginTop: 1, flexDirection: "column", children: [
|
|
3361
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3362
|
+
"No ",
|
|
3363
|
+
view,
|
|
3364
|
+
" found."
|
|
3365
|
+
] }),
|
|
3366
|
+
view === "plans" && /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Create a plan file: *.plan.md or *-plan.md" })
|
|
3367
|
+
] }),
|
|
3368
|
+
!loading && !executing && items.length > 0 && /* @__PURE__ */ jsxs18(Box18, { marginTop: 1, flexDirection: "column", children: [
|
|
3369
|
+
start > 0 && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3370
|
+
" \u2191 ",
|
|
3371
|
+
start,
|
|
3372
|
+
" more"
|
|
3373
|
+
] }),
|
|
3374
|
+
view === "plans" && visible.map((pf, i) => renderPlanItem(pf, start + i)),
|
|
3375
|
+
view === "tasks" && visible.map((t, i) => renderTaskItem(t, start + i)),
|
|
3376
|
+
view === "steps" && visible.map((s, i) => renderStepItem(s, start + i)),
|
|
3377
|
+
start + maxVisible < items.length && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
3378
|
+
" \u2193 ",
|
|
3379
|
+
items.length - start - maxVisible,
|
|
3380
|
+
" more"
|
|
3381
|
+
] })
|
|
3382
|
+
] }),
|
|
3383
|
+
/* @__PURE__ */ jsxs18(Box18, { marginTop: 1, children: [
|
|
3384
|
+
view === "plans" && /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Enter=view tasks x=execute (dry-run) r=refresh q=quit" }),
|
|
3385
|
+
view === "tasks" && /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Enter=view steps b/Esc=back q=quit" }),
|
|
3386
|
+
view === "steps" && /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "b/Esc=back q=quit" })
|
|
3387
|
+
] })
|
|
3388
|
+
] });
|
|
3389
|
+
}
|
|
3390
|
+
|
|
2937
3391
|
// src/App.tsx
|
|
2938
|
-
import { jsx as
|
|
3392
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2939
3393
|
function App() {
|
|
2940
|
-
const [screen, setScreen] =
|
|
3394
|
+
const [screen, setScreen] = useState21("home");
|
|
2941
3395
|
const { exit } = useApp();
|
|
2942
3396
|
const { stdout } = useStdout();
|
|
2943
3397
|
const cols = stdout?.columns || 80;
|
|
@@ -2958,9 +3412,11 @@ function App() {
|
|
|
2958
3412
|
s: "sync",
|
|
2959
3413
|
a: "team",
|
|
2960
3414
|
p: "plugins",
|
|
3415
|
+
o: "methodology",
|
|
3416
|
+
n: "plan",
|
|
2961
3417
|
",": "settings"
|
|
2962
3418
|
};
|
|
2963
|
-
|
|
3419
|
+
useInput17((input, key) => {
|
|
2964
3420
|
if (input === "q") {
|
|
2965
3421
|
exit();
|
|
2966
3422
|
return;
|
|
@@ -2977,67 +3433,71 @@ function App() {
|
|
|
2977
3433
|
const renderScreen = () => {
|
|
2978
3434
|
switch (screen) {
|
|
2979
3435
|
case "home":
|
|
2980
|
-
return /* @__PURE__ */
|
|
3436
|
+
return /* @__PURE__ */ jsx19(Home, { onNavigate: setScreen, cols, rows });
|
|
2981
3437
|
case "browse":
|
|
2982
|
-
return /* @__PURE__ */
|
|
3438
|
+
return /* @__PURE__ */ jsx19(Browse, { cols, rows });
|
|
2983
3439
|
case "installed":
|
|
2984
|
-
return /* @__PURE__ */
|
|
3440
|
+
return /* @__PURE__ */ jsx19(Installed, { cols, rows });
|
|
2985
3441
|
case "sync":
|
|
2986
|
-
return /* @__PURE__ */
|
|
3442
|
+
return /* @__PURE__ */ jsx19(Sync, { cols, rows });
|
|
2987
3443
|
case "settings":
|
|
2988
|
-
return /* @__PURE__ */
|
|
3444
|
+
return /* @__PURE__ */ jsx19(Settings, { cols, rows });
|
|
2989
3445
|
case "recommend":
|
|
2990
|
-
return /* @__PURE__ */
|
|
3446
|
+
return /* @__PURE__ */ jsx19(Recommend, { cols, rows });
|
|
2991
3447
|
case "translate":
|
|
2992
|
-
return /* @__PURE__ */
|
|
3448
|
+
return /* @__PURE__ */ jsx19(Translate, { cols, rows });
|
|
2993
3449
|
case "context":
|
|
2994
|
-
return /* @__PURE__ */
|
|
3450
|
+
return /* @__PURE__ */ jsx19(Context, { cols, rows });
|
|
2995
3451
|
case "workflow":
|
|
2996
|
-
return /* @__PURE__ */
|
|
3452
|
+
return /* @__PURE__ */ jsx19(Workflow, { cols, rows });
|
|
2997
3453
|
case "execute":
|
|
2998
|
-
return /* @__PURE__ */
|
|
3454
|
+
return /* @__PURE__ */ jsx19(Execute, { cols, rows });
|
|
2999
3455
|
case "history":
|
|
3000
|
-
return /* @__PURE__ */
|
|
3456
|
+
return /* @__PURE__ */ jsx19(History, { cols, rows });
|
|
3001
3457
|
case "marketplace":
|
|
3002
|
-
return /* @__PURE__ */
|
|
3458
|
+
return /* @__PURE__ */ jsx19(Marketplace, { cols, rows });
|
|
3003
3459
|
case "memory":
|
|
3004
|
-
return /* @__PURE__ */
|
|
3460
|
+
return /* @__PURE__ */ jsx19(Memory, { cols, rows });
|
|
3005
3461
|
case "team":
|
|
3006
|
-
return /* @__PURE__ */
|
|
3462
|
+
return /* @__PURE__ */ jsx19(Team, { cols, rows });
|
|
3007
3463
|
case "plugins":
|
|
3008
|
-
return /* @__PURE__ */
|
|
3464
|
+
return /* @__PURE__ */ jsx19(Plugins, { cols, rows });
|
|
3465
|
+
case "methodology":
|
|
3466
|
+
return /* @__PURE__ */ jsx19(Methodology, { cols, rows });
|
|
3467
|
+
case "plan":
|
|
3468
|
+
return /* @__PURE__ */ jsx19(Plan, { cols, rows });
|
|
3009
3469
|
}
|
|
3010
3470
|
};
|
|
3011
3471
|
const contentHeight = rows - 2;
|
|
3012
|
-
return /* @__PURE__ */
|
|
3013
|
-
/* @__PURE__ */
|
|
3014
|
-
showSidebar && /* @__PURE__ */
|
|
3015
|
-
/* @__PURE__ */
|
|
3472
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", height: rows, children: [
|
|
3473
|
+
/* @__PURE__ */ jsxs19(Box19, { flexDirection: "row", height: contentHeight, children: [
|
|
3474
|
+
showSidebar && /* @__PURE__ */ jsx19(Sidebar, { screen, onNavigate: setScreen }),
|
|
3475
|
+
/* @__PURE__ */ jsx19(Box19, { flexDirection: "column", flexGrow: 1, marginLeft: 1, children: renderScreen() })
|
|
3016
3476
|
] }),
|
|
3017
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "h Home m Market b Browse w Wflow x Exec a Team p Plug o Meth n Plan r Rec t Trans c Ctx e Mem i Inst s Sync q Quit" }) })
|
|
3018
3478
|
] });
|
|
3019
3479
|
}
|
|
3020
3480
|
|
|
3021
3481
|
// src/components/Header.tsx
|
|
3022
|
-
import { Box as
|
|
3023
|
-
import { jsx as
|
|
3482
|
+
import { Box as Box20, Text as Text20 } from "ink";
|
|
3483
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3024
3484
|
function Header({ title, subtitle, count }) {
|
|
3025
|
-
return /* @__PURE__ */
|
|
3026
|
-
/* @__PURE__ */
|
|
3027
|
-
/* @__PURE__ */
|
|
3028
|
-
count !== void 0 && /* @__PURE__ */
|
|
3485
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginBottom: 1, children: [
|
|
3486
|
+
/* @__PURE__ */ jsxs20(Box20, { justifyContent: "space-between", children: [
|
|
3487
|
+
/* @__PURE__ */ jsx20(Text20, { color: colors.primary, bold: true, children: title.toUpperCase() }),
|
|
3488
|
+
count !== void 0 && /* @__PURE__ */ jsxs20(Text20, { color: colors.secondaryDim, children: [
|
|
3029
3489
|
symbols.star,
|
|
3030
3490
|
" ",
|
|
3031
3491
|
count
|
|
3032
3492
|
] })
|
|
3033
3493
|
] }),
|
|
3034
|
-
subtitle && /* @__PURE__ */
|
|
3494
|
+
subtitle && /* @__PURE__ */ jsx20(Text20, { color: colors.secondaryDim, dimColor: true, children: subtitle })
|
|
3035
3495
|
] });
|
|
3036
3496
|
}
|
|
3037
3497
|
|
|
3038
3498
|
// src/components/SkillList.tsx
|
|
3039
|
-
import { Box as
|
|
3040
|
-
import { jsx as
|
|
3499
|
+
import { Box as Box21, Text as Text21 } from "ink";
|
|
3500
|
+
import { jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3041
3501
|
function formatInstalls(count) {
|
|
3042
3502
|
if (count >= 1e3) {
|
|
3043
3503
|
return `${(count / 1e3).toFixed(1)}K`;
|
|
@@ -3053,13 +3513,13 @@ function SkillList({
|
|
|
3053
3513
|
maxVisible = 10
|
|
3054
3514
|
}) {
|
|
3055
3515
|
if (skills.length === 0) {
|
|
3056
|
-
return /* @__PURE__ */
|
|
3516
|
+
return /* @__PURE__ */ jsx21(Box21, { children: /* @__PURE__ */ jsx21(Text21, { color: colors.secondaryDim, dimColor: true, children: "No skills found" }) });
|
|
3057
3517
|
}
|
|
3058
3518
|
const startIndex = Math.max(0, selectedIndex - Math.floor(maxVisible / 2));
|
|
3059
3519
|
const visibleSkills = skills.slice(startIndex, startIndex + maxVisible);
|
|
3060
3520
|
const actualStartIndex = startIndex;
|
|
3061
|
-
return /* @__PURE__ */
|
|
3062
|
-
showRank && /* @__PURE__ */
|
|
3521
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
3522
|
+
showRank && /* @__PURE__ */ jsx21(Box21, { marginBottom: 1, children: /* @__PURE__ */ jsxs21(Text21, { color: colors.secondaryDim, children: [
|
|
3063
3523
|
" # SKILL",
|
|
3064
3524
|
showSource && " SOURCE",
|
|
3065
3525
|
showInstalls && " INSTALLS"
|
|
@@ -3069,9 +3529,9 @@ function SkillList({
|
|
|
3069
3529
|
const isSelected = realIndex === selectedIndex;
|
|
3070
3530
|
const skillName = skill.name.padEnd(28).slice(0, 28);
|
|
3071
3531
|
const sourceName = skill.source ? skill.source.slice(0, 25) : "";
|
|
3072
|
-
return /* @__PURE__ */
|
|
3073
|
-
/* @__PURE__ */
|
|
3074
|
-
|
|
3532
|
+
return /* @__PURE__ */ jsxs21(Box21, { children: [
|
|
3533
|
+
/* @__PURE__ */ jsxs21(
|
|
3534
|
+
Text21,
|
|
3075
3535
|
{
|
|
3076
3536
|
color: isSelected ? colors.primary : colors.secondary,
|
|
3077
3537
|
bold: isSelected,
|
|
@@ -3084,14 +3544,14 @@ function SkillList({
|
|
|
3084
3544
|
]
|
|
3085
3545
|
}
|
|
3086
3546
|
),
|
|
3087
|
-
showSource && /* @__PURE__ */
|
|
3547
|
+
showSource && /* @__PURE__ */ jsxs21(Text21, { color: colors.secondaryDim, dimColor: !isSelected, children: [
|
|
3088
3548
|
" ",
|
|
3089
3549
|
sourceName
|
|
3090
3550
|
] }),
|
|
3091
|
-
showInstalls && skill.installs !== void 0 && /* @__PURE__ */
|
|
3551
|
+
showInstalls && skill.installs !== void 0 && /* @__PURE__ */ jsx21(Text21, { color: colors.secondaryDim, children: formatInstalls(skill.installs).padStart(8) })
|
|
3092
3552
|
] }, `${skill.source}-${skill.name}`);
|
|
3093
3553
|
}),
|
|
3094
|
-
skills.length > maxVisible && /* @__PURE__ */
|
|
3554
|
+
skills.length > maxVisible && /* @__PURE__ */ jsx21(Box21, { marginTop: 1, children: /* @__PURE__ */ jsxs21(Text21, { color: colors.secondaryDim, dimColor: true, children: [
|
|
3095
3555
|
"Showing ",
|
|
3096
3556
|
startIndex + 1,
|
|
3097
3557
|
"-",
|
|
@@ -3103,11 +3563,11 @@ function SkillList({
|
|
|
3103
3563
|
}
|
|
3104
3564
|
|
|
3105
3565
|
// src/components/StatusBar.tsx
|
|
3106
|
-
import { Box as
|
|
3107
|
-
import { jsx as
|
|
3566
|
+
import { Box as Box22, Text as Text22 } from "ink";
|
|
3567
|
+
import { jsx as jsx22, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3108
3568
|
function StatusBar({ shortcuts, message }) {
|
|
3109
|
-
return /* @__PURE__ */
|
|
3110
|
-
|
|
3569
|
+
return /* @__PURE__ */ jsxs22(
|
|
3570
|
+
Box22,
|
|
3111
3571
|
{
|
|
3112
3572
|
borderStyle: "single",
|
|
3113
3573
|
borderColor: colors.borderDim,
|
|
@@ -3118,11 +3578,11 @@ function StatusBar({ shortcuts, message }) {
|
|
|
3118
3578
|
paddingX: 1,
|
|
3119
3579
|
justifyContent: "space-between",
|
|
3120
3580
|
children: [
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
/* @__PURE__ */
|
|
3123
|
-
/* @__PURE__ */
|
|
3581
|
+
/* @__PURE__ */ jsx22(Box22, { gap: 2, children: shortcuts.map((shortcut, idx) => /* @__PURE__ */ jsxs22(Box22, { gap: 1, children: [
|
|
3582
|
+
/* @__PURE__ */ jsx22(Text22, { color: colors.primary, bold: true, children: shortcut.key }),
|
|
3583
|
+
/* @__PURE__ */ jsx22(Text22, { color: colors.secondaryDim, children: shortcut.label })
|
|
3124
3584
|
] }, idx)) }),
|
|
3125
|
-
message && /* @__PURE__ */
|
|
3585
|
+
message && /* @__PURE__ */ jsxs22(Text22, { color: colors.success, children: [
|
|
3126
3586
|
symbols.check,
|
|
3127
3587
|
" ",
|
|
3128
3588
|
message
|
|
@@ -3133,44 +3593,44 @@ function StatusBar({ shortcuts, message }) {
|
|
|
3133
3593
|
}
|
|
3134
3594
|
|
|
3135
3595
|
// src/components/SearchInput.tsx
|
|
3136
|
-
import { Box as
|
|
3596
|
+
import { Box as Box23, Text as Text23 } from "ink";
|
|
3137
3597
|
import TextInput2 from "ink-text-input";
|
|
3138
|
-
import { jsx as
|
|
3598
|
+
import { jsx as jsx23, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3139
3599
|
function SearchInput({
|
|
3140
3600
|
value,
|
|
3141
3601
|
onChange,
|
|
3142
3602
|
placeholder = "Search skills...",
|
|
3143
3603
|
isFocused = false
|
|
3144
3604
|
}) {
|
|
3145
|
-
return /* @__PURE__ */
|
|
3146
|
-
|
|
3605
|
+
return /* @__PURE__ */ jsxs23(
|
|
3606
|
+
Box23,
|
|
3147
3607
|
{
|
|
3148
3608
|
borderStyle: "single",
|
|
3149
3609
|
borderColor: isFocused ? colors.primary : colors.borderDim,
|
|
3150
3610
|
paddingX: 1,
|
|
3151
3611
|
children: [
|
|
3152
|
-
/* @__PURE__ */
|
|
3153
|
-
isFocused ? /* @__PURE__ */
|
|
3612
|
+
/* @__PURE__ */ jsx23(Text23, { color: colors.secondaryDim, children: "/ " }),
|
|
3613
|
+
isFocused ? /* @__PURE__ */ jsx23(
|
|
3154
3614
|
TextInput2,
|
|
3155
3615
|
{
|
|
3156
3616
|
value,
|
|
3157
3617
|
onChange,
|
|
3158
3618
|
placeholder
|
|
3159
3619
|
}
|
|
3160
|
-
) : /* @__PURE__ */
|
|
3161
|
-
/* @__PURE__ */
|
|
3162
|
-
/* @__PURE__ */
|
|
3620
|
+
) : /* @__PURE__ */ jsx23(Text23, { color: value ? colors.secondary : colors.secondaryDim, children: value || placeholder }),
|
|
3621
|
+
/* @__PURE__ */ jsx23(Box23, { flexGrow: 1 }),
|
|
3622
|
+
/* @__PURE__ */ jsx23(Text23, { color: colors.secondaryDim, children: "/" })
|
|
3163
3623
|
]
|
|
3164
3624
|
}
|
|
3165
3625
|
);
|
|
3166
3626
|
}
|
|
3167
3627
|
|
|
3168
3628
|
// src/hooks/useKeyboard.ts
|
|
3169
|
-
import { useState as
|
|
3170
|
-
import { useInput as
|
|
3629
|
+
import { useState as useState22, useCallback as useCallback3, useEffect as useEffect18 } from "react";
|
|
3630
|
+
import { useInput as useInput18, useApp as useApp2 } from "ink";
|
|
3171
3631
|
function useKeyboard(options = {}) {
|
|
3172
3632
|
const { exit } = useApp2();
|
|
3173
|
-
|
|
3633
|
+
useInput18((input, key) => {
|
|
3174
3634
|
if (options.disabled) return;
|
|
3175
3635
|
if (input === "q" || key.ctrl && input === "c") {
|
|
3176
3636
|
exit();
|
|
@@ -3214,8 +3674,8 @@ function useKeyboard(options = {}) {
|
|
|
3214
3674
|
});
|
|
3215
3675
|
}
|
|
3216
3676
|
function useListNavigation(listLength, initialIndex = 0) {
|
|
3217
|
-
const [selectedIndex, setSelectedIndex] =
|
|
3218
|
-
|
|
3677
|
+
const [selectedIndex, setSelectedIndex] = useState22(initialIndex);
|
|
3678
|
+
useEffect18(() => {
|
|
3219
3679
|
if (selectedIndex >= listLength && listLength > 0) {
|
|
3220
3680
|
setSelectedIndex(listLength - 1);
|
|
3221
3681
|
}
|
|
@@ -3233,7 +3693,7 @@ function useListNavigation(listLength, initialIndex = 0) {
|
|
|
3233
3693
|
}
|
|
3234
3694
|
|
|
3235
3695
|
// src/hooks/useMemory.ts
|
|
3236
|
-
import { useState as
|
|
3696
|
+
import { useState as useState23, useEffect as useEffect19, useCallback as useCallback4 } from "react";
|
|
3237
3697
|
import {
|
|
3238
3698
|
LearningStore as LearningStore2,
|
|
3239
3699
|
ObservationStore as ObservationStore2,
|
|
@@ -3241,12 +3701,12 @@ import {
|
|
|
3241
3701
|
createMemoryInjector as createMemoryInjector2
|
|
3242
3702
|
} from "@skillkit/core";
|
|
3243
3703
|
function useMemory() {
|
|
3244
|
-
const [learnings, setLearnings] =
|
|
3245
|
-
const [observations, setObservations] =
|
|
3246
|
-
const [status, setStatus] =
|
|
3247
|
-
const [loading, setLoading] =
|
|
3248
|
-
const [error, setError] =
|
|
3249
|
-
const [isGlobal, setIsGlobal] =
|
|
3704
|
+
const [learnings, setLearnings] = useState23([]);
|
|
3705
|
+
const [observations, setObservations] = useState23([]);
|
|
3706
|
+
const [status, setStatus] = useState23(null);
|
|
3707
|
+
const [loading, setLoading] = useState23(true);
|
|
3708
|
+
const [error, setError] = useState23(null);
|
|
3709
|
+
const [isGlobal, setIsGlobal] = useState23(false);
|
|
3250
3710
|
const projectPath = process.cwd();
|
|
3251
3711
|
const refresh = useCallback4(() => {
|
|
3252
3712
|
setLoading(true);
|
|
@@ -3325,7 +3785,7 @@ function useMemory() {
|
|
|
3325
3785
|
},
|
|
3326
3786
|
[projectPath, refresh]
|
|
3327
3787
|
);
|
|
3328
|
-
|
|
3788
|
+
useEffect19(() => {
|
|
3329
3789
|
refresh();
|
|
3330
3790
|
}, [refresh]);
|
|
3331
3791
|
return {
|
|
@@ -3344,10 +3804,10 @@ function useMemory() {
|
|
|
3344
3804
|
}
|
|
3345
3805
|
|
|
3346
3806
|
// src/index.tsx
|
|
3347
|
-
import { jsx as
|
|
3807
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3348
3808
|
function startTUI() {
|
|
3349
3809
|
process.stdout.write("\x1B[2J\x1B[0f");
|
|
3350
|
-
const { waitUntilExit, clear } = render(/* @__PURE__ */
|
|
3810
|
+
const { waitUntilExit, clear } = render(/* @__PURE__ */ jsx24(App, {}), {
|
|
3351
3811
|
exitOnCtrlC: true
|
|
3352
3812
|
});
|
|
3353
3813
|
return waitUntilExit().then(() => {
|
|
@@ -3365,6 +3825,8 @@ export {
|
|
|
3365
3825
|
Installed,
|
|
3366
3826
|
Marketplace,
|
|
3367
3827
|
Memory,
|
|
3828
|
+
Methodology,
|
|
3829
|
+
Plan,
|
|
3368
3830
|
Plugins,
|
|
3369
3831
|
Recommend,
|
|
3370
3832
|
SearchInput,
|