skilluse 0.1.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.
Files changed (68) hide show
  1. package/README.md +100 -0
  2. package/dist/app.d.ts +6 -0
  3. package/dist/app.js +6 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.js +167 -0
  6. package/dist/commands/demo.d.ts +14 -0
  7. package/dist/commands/demo.js +46 -0
  8. package/dist/commands/index.d.ts +8 -0
  9. package/dist/commands/index.js +77 -0
  10. package/dist/commands/list.d.ts +14 -0
  11. package/dist/commands/list.js +54 -0
  12. package/dist/commands/login.d.ts +14 -0
  13. package/dist/commands/login.js +153 -0
  14. package/dist/commands/logout.d.ts +8 -0
  15. package/dist/commands/logout.js +47 -0
  16. package/dist/commands/repo/add.d.ts +22 -0
  17. package/dist/commands/repo/add.js +139 -0
  18. package/dist/commands/repo/edit.d.ts +19 -0
  19. package/dist/commands/repo/edit.js +117 -0
  20. package/dist/commands/repo/index.d.ts +8 -0
  21. package/dist/commands/repo/index.js +47 -0
  22. package/dist/commands/repo/list.d.ts +8 -0
  23. package/dist/commands/repo/list.js +47 -0
  24. package/dist/commands/repo/remove.d.ts +16 -0
  25. package/dist/commands/repo/remove.js +83 -0
  26. package/dist/commands/repo/sync.d.ts +10 -0
  27. package/dist/commands/repo/sync.js +78 -0
  28. package/dist/commands/repo/use.d.ts +10 -0
  29. package/dist/commands/repo/use.js +56 -0
  30. package/dist/commands/repos.d.ts +11 -0
  31. package/dist/commands/repos.js +50 -0
  32. package/dist/commands/search.d.ts +16 -0
  33. package/dist/commands/search.js +199 -0
  34. package/dist/commands/skills.d.ts +11 -0
  35. package/dist/commands/skills.js +43 -0
  36. package/dist/commands/whoami.d.ts +8 -0
  37. package/dist/commands/whoami.js +69 -0
  38. package/dist/components/CLIError.d.ts +27 -0
  39. package/dist/components/CLIError.js +24 -0
  40. package/dist/components/ProgressBar.d.ts +7 -0
  41. package/dist/components/ProgressBar.js +9 -0
  42. package/dist/components/Select.d.ts +11 -0
  43. package/dist/components/Select.js +6 -0
  44. package/dist/components/Spinner.d.ts +6 -0
  45. package/dist/components/Spinner.js +7 -0
  46. package/dist/components/StatusMessage.d.ts +9 -0
  47. package/dist/components/StatusMessage.js +13 -0
  48. package/dist/components/Table.d.ts +9 -0
  49. package/dist/components/Table.js +27 -0
  50. package/dist/components/TextInput.d.ts +9 -0
  51. package/dist/components/TextInput.js +6 -0
  52. package/dist/components/index.d.ts +8 -0
  53. package/dist/components/index.js +8 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.js +43815 -0
  56. package/dist/services/credentials.d.ts +69 -0
  57. package/dist/services/credentials.js +216 -0
  58. package/dist/services/index.d.ts +6 -0
  59. package/dist/services/index.js +10 -0
  60. package/dist/services/oauth.d.ts +106 -0
  61. package/dist/services/oauth.js +208 -0
  62. package/dist/services/paths.d.ts +19 -0
  63. package/dist/services/paths.js +21 -0
  64. package/dist/services/store.d.ts +64 -0
  65. package/dist/services/store.js +107 -0
  66. package/dist/services/update.d.ts +20 -0
  67. package/dist/services/update.js +93 -0
  68. package/package.json +70 -0
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Skilluse CLI
2
+
3
+ CLI tool for managing and installing AI Coding Agent Skills.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g skilluse
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Login to GitHub
15
+ skilluse login
16
+
17
+ # Add a skill repository
18
+ skilluse repo add owner/skill-repo
19
+
20
+ # Search for skills
21
+ skilluse search code-review
22
+
23
+ # Install a skill
24
+ skilluse install code-review
25
+
26
+ # List installed skills
27
+ skilluse list
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ ### Authentication
33
+
34
+ | Command | Description |
35
+ |---------|-------------|
36
+ | `skilluse` | Show status (user, repos, installed count) |
37
+ | `skilluse login` | Authenticate with GitHub |
38
+ | `skilluse logout` | Clear stored credentials |
39
+
40
+ ### Repository Management
41
+
42
+ | Command | Description |
43
+ |---------|-------------|
44
+ | `skilluse repo list` | List configured repositories |
45
+ | `skilluse repo add <repo>` | Add a skill repository |
46
+ | `skilluse repo remove <name>` | Remove a repository |
47
+ | `skilluse repo use <name>` | Set default repository |
48
+ | `skilluse repo edit <name>` | Edit repository settings |
49
+
50
+ ### Skill Management
51
+
52
+ | Command | Description |
53
+ |---------|-------------|
54
+ | `skilluse search <keyword>` | Search for skills |
55
+ | `skilluse install <skill>` | Install skill locally |
56
+ | `skilluse install <skill> --global` | Install globally |
57
+ | `skilluse uninstall <skill>` | Remove installed skill |
58
+ | `skilluse upgrade [skill]` | Upgrade skill(s) to latest |
59
+ | `skilluse list` | List installed skills |
60
+ | `skilluse list --outdated` | Show skills with updates |
61
+ | `skilluse info <skill>` | Show skill details |
62
+
63
+ ## Authentication
64
+
65
+ Skilluse uses GitHub App OAuth for authentication.
66
+
67
+ ### First-Time Login
68
+
69
+ 1. Run `skilluse login`
70
+ 2. Enter the code shown in your browser
71
+ 3. Install the GitHub App when prompted
72
+ 4. Select repository access (all or specific repos)
73
+
74
+ ### Managing Repository Access
75
+
76
+ Modify access at: https://github.com/settings/installations
77
+
78
+ ### Logging Out
79
+
80
+ ```bash
81
+ skilluse logout
82
+ ```
83
+
84
+ ## Install Locations
85
+
86
+ | Scope | Path |
87
+ |-------|------|
88
+ | Local | `./.claude/skills/<name>/` |
89
+ | Global | `~/.claude/skills/<name>/` |
90
+
91
+ ## Security
92
+
93
+ - **User tokens** stored in system keychain (macOS/Windows/Linux)
94
+ - **Fallback** to encrypted file if keychain unavailable
95
+
96
+ ## Environment Variables
97
+
98
+ | Variable | Description |
99
+ |----------|-------------|
100
+ | `SKILLUSE_GITHUB_CLIENT_ID` | Override GitHub App client ID (dev only) |
package/dist/app.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ interface AppProps {
2
+ name?: string;
3
+ }
4
+ export default function App({ name }: AppProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=app.d.ts.map
package/dist/app.js ADDED
@@ -0,0 +1,6 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ export default function App({ name = "skilluse" }) {
4
+ return (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { color: "green", children: [name, " - AI Coding Agent Skills Manager"] }) }));
5
+ }
6
+ //# sourceMappingURL=app.js.map
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env bun
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Static CLI entry point for compiled binaries.
5
+ * This file imports all commands statically to work with Bun's single-file compilation.
6
+ *
7
+ * For development, use src/index.tsx which uses Pastel's dynamic command discovery.
8
+ */
9
+ import { Command } from "commander";
10
+ import { render } from "ink";
11
+ // Import all commands statically
12
+ import Demo, { options as demoOptions } from "./commands/demo.js";
13
+ import Login, { options as loginOptions } from "./commands/login.js";
14
+ import Logout from "./commands/logout.js";
15
+ import Whoami from "./commands/whoami.js";
16
+ import Repos from "./commands/repos.js";
17
+ import Skills from "./commands/skills.js";
18
+ import List, { options as listOptions } from "./commands/list.js";
19
+ import Search, { args as searchArgs, options as searchOptions } from "./commands/search.js";
20
+ // Import repo subcommands
21
+ import RepoIndex from "./commands/repo/index.js";
22
+ import RepoList from "./commands/repo/list.js";
23
+ import RepoAdd, { args as repoAddArgs, options as repoAddOptions } from "./commands/repo/add.js";
24
+ import RepoRemove, { args as repoRemoveArgs, options as repoRemoveOptions } from "./commands/repo/remove.js";
25
+ import RepoEdit, { args as repoEditArgs, options as repoEditOptions } from "./commands/repo/edit.js";
26
+ import RepoSync, { args as repoSyncArgs, options as repoSyncOptions } from "./commands/repo/sync.js";
27
+ import RepoUse, { args as repoUseArgs } from "./commands/repo/use.js";
28
+ // Version injected via --define at build time, fallback to package.json
29
+ const VERSION = process.env.VERSION || "0.1.0";
30
+ const BUILD_TIME = process.env.BUILD_TIME || new Date().toISOString();
31
+ const program = new Command();
32
+ program
33
+ .name("skilluse")
34
+ .description("CLI tool for managing and installing AI Coding Agent Skills")
35
+ .version(VERSION, "-v, --version", "Show version number")
36
+ .option("--version-verbose", "Show version with build info")
37
+ .on("option:version-verbose", () => {
38
+ console.log(`skilluse ${VERSION}`);
39
+ console.log(`Built: ${BUILD_TIME}`);
40
+ process.exit(0);
41
+ });
42
+ // demo command
43
+ program
44
+ .command("demo")
45
+ .description("Demo UI components")
46
+ .option("-a, --all", "Show all components")
47
+ .action((opts) => {
48
+ const options = demoOptions.parse(opts);
49
+ render(_jsx(Demo, { options: options }));
50
+ });
51
+ // login command
52
+ program
53
+ .command("login")
54
+ .description("Authenticate with GitHub")
55
+ .option("-f, --force", "Force re-authentication")
56
+ .action((opts) => {
57
+ const options = loginOptions.parse(opts);
58
+ render(_jsx(Login, { options: options }));
59
+ });
60
+ // logout command
61
+ program
62
+ .command("logout")
63
+ .description("Clear stored credentials")
64
+ .action(() => {
65
+ render(_jsx(Logout, { options: {} }));
66
+ });
67
+ // whoami command
68
+ program
69
+ .command("whoami")
70
+ .description("Show current user info")
71
+ .action(() => {
72
+ render(_jsx(Whoami, { options: {} }));
73
+ });
74
+ // repos command
75
+ program
76
+ .command("repos")
77
+ .description("List accessible GitHub repositories")
78
+ .action(() => {
79
+ render(_jsx(Repos, { options: {} }));
80
+ });
81
+ // skills command
82
+ program
83
+ .command("skills")
84
+ .description("List installed skills")
85
+ .action(() => {
86
+ render(_jsx(Skills, { options: {} }));
87
+ });
88
+ // list command
89
+ program
90
+ .command("list")
91
+ .description("List skills from a repository")
92
+ .option("-r, --repo <repo>", "Repository to list skills from")
93
+ .action((opts) => {
94
+ const options = listOptions.parse(opts);
95
+ render(_jsx(List, { options: options }));
96
+ });
97
+ // search command
98
+ program
99
+ .command("search <keyword>")
100
+ .description("Search for skills")
101
+ .option("-a, --all", "Search in all configured repos")
102
+ .action((keyword, opts) => {
103
+ const args = searchArgs.parse([keyword]);
104
+ const options = searchOptions.parse(opts);
105
+ render(_jsx(Search, { args: args, options: options }));
106
+ });
107
+ // repo command group
108
+ const repoCmd = program
109
+ .command("repo")
110
+ .description("Manage skill repositories");
111
+ repoCmd
112
+ .command("list")
113
+ .description("List configured repositories")
114
+ .action(() => {
115
+ render(_jsx(RepoList, { options: {} }));
116
+ });
117
+ repoCmd
118
+ .command("add <url>")
119
+ .description("Add a skill repository")
120
+ .option("-p, --path <path>", "Skill path within the repo")
121
+ .option("-b, --branch <branch>", "Branch to use")
122
+ .option("-d, --default", "Set as default repository")
123
+ .action((url, opts) => {
124
+ const args = repoAddArgs.parse([url]);
125
+ const options = repoAddOptions.parse(opts);
126
+ render(_jsx(RepoAdd, { args: args, options: options }));
127
+ });
128
+ repoCmd
129
+ .command("remove <name>")
130
+ .description("Remove a repository")
131
+ .option("-f, --force", "Skip confirmation")
132
+ .action((name, opts) => {
133
+ const args = repoRemoveArgs.parse([name]);
134
+ const options = repoRemoveOptions.parse(opts);
135
+ render(_jsx(RepoRemove, { args: args, options: options }));
136
+ });
137
+ repoCmd
138
+ .command("edit <name>")
139
+ .description("Edit repository settings")
140
+ .option("-p, --path <path>", "New skill path")
141
+ .option("-b, --branch <branch>", "New branch")
142
+ .action((name, opts) => {
143
+ const args = repoEditArgs.parse([name]);
144
+ const options = repoEditOptions.parse(opts);
145
+ render(_jsx(RepoEdit, { args: args, options: options }));
146
+ });
147
+ repoCmd
148
+ .command("sync [name]")
149
+ .description("Sync repository metadata")
150
+ .action((name, _opts) => {
151
+ const args = repoSyncArgs.parse([name || undefined]);
152
+ const options = repoSyncOptions.parse({});
153
+ render(_jsx(RepoSync, { args: args, options: options }));
154
+ });
155
+ repoCmd
156
+ .command("use <name>")
157
+ .description("Set default repository")
158
+ .action((name, _opts) => {
159
+ const args = repoUseArgs.parse([name]);
160
+ render(_jsx(RepoUse, { args: args, options: {} }));
161
+ });
162
+ // Default action shows help when just 'repo' is called
163
+ repoCmd.action(() => {
164
+ render(_jsx(RepoIndex, { options: {} }));
165
+ });
166
+ program.parse();
167
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ export declare const options: z.ZodObject<{
3
+ component: z.ZodDefault<z.ZodEnum<["spinner", "select", "table", "progress", "status", "input", "all"]>>;
4
+ }, "strip", z.ZodTypeAny, {
5
+ component: "spinner" | "select" | "table" | "progress" | "status" | "input" | "all";
6
+ }, {
7
+ component?: "spinner" | "select" | "table" | "progress" | "status" | "input" | "all" | undefined;
8
+ }>;
9
+ interface Props {
10
+ options: z.infer<typeof options>;
11
+ }
12
+ export default function Demo({ options: opts }: Props): import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { z } from "zod";
5
+ import { Spinner, Select, Table, ProgressBar, StatusMessage, TextInput, } from "../components/index.js";
6
+ export const options = z.object({
7
+ component: z
8
+ .enum(["spinner", "select", "table", "progress", "status", "input", "all"])
9
+ .default("all")
10
+ .describe("Component to demo"),
11
+ });
12
+ function SpinnerDemo() {
13
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "Spinner Component:" }), _jsx(Spinner, { text: "Loading..." })] }));
14
+ }
15
+ function SelectDemo() {
16
+ const [selected, setSelected] = useState(null);
17
+ const items = [
18
+ { label: "Option 1", value: "1" },
19
+ { label: "Option 2", value: "2" },
20
+ { label: "Option 3", value: "3" },
21
+ ];
22
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "Select Component:" }), selected ? (_jsxs(Text, { children: ["Selected: ", selected] })) : (_jsx(Select, { items: items, onSelect: (item) => setSelected(item.value) }))] }));
23
+ }
24
+ function TableDemo() {
25
+ const data = [
26
+ { name: "skill-1", version: "1.0.0", status: "installed" },
27
+ { name: "skill-2", version: "2.1.0", status: "available" },
28
+ { name: "skill-3", version: "0.5.0", status: "installed" },
29
+ ];
30
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "Table Component:" }), _jsx(Table, { data: data, columns: ["name", "version", "status"] })] }));
31
+ }
32
+ function ProgressDemo() {
33
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "ProgressBar Component:" }), _jsx(ProgressBar, { percent: 0, width: 20 }), _jsx(ProgressBar, { percent: 50, width: 20 }), _jsx(ProgressBar, { percent: 100, width: 20 })] }));
34
+ }
35
+ function StatusDemo() {
36
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "StatusMessage Component:" }), _jsx(StatusMessage, { type: "success", children: "Operation completed" }), _jsx(StatusMessage, { type: "error", children: "Something went wrong" }), _jsx(StatusMessage, { type: "warning", children: "Proceed with caution" })] }));
37
+ }
38
+ function TextInputDemo() {
39
+ const [value, setValue] = useState("");
40
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { bold: true, children: "TextInput Component:" }), _jsxs(Box, { children: [_jsx(Text, { children: "Enter text: " }), _jsx(TextInput, { value: value, onChange: setValue, placeholder: "Type something..." })] }), value && _jsxs(Text, { dimColor: true, children: ["You typed: ", value] })] }));
41
+ }
42
+ export default function Demo({ options: opts }) {
43
+ const { component } = opts;
44
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "green", bold: true, children: "UI Components Demo" }), (component === "all" || component === "spinner") && _jsx(SpinnerDemo, {}), (component === "all" || component === "select") && _jsx(SelectDemo, {}), (component === "all" || component === "table") && _jsx(TableDemo, {}), (component === "all" || component === "progress") && _jsx(ProgressDemo, {}), (component === "all" || component === "status") && _jsx(StatusDemo, {}), (component === "all" || component === "input") && _jsx(TextInputDemo, {})] }));
45
+ }
46
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+ export declare const options: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
3
+ interface Props {
4
+ options: z.infer<typeof options>;
5
+ }
6
+ export default function Index(_props: Props): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Box, Text, useApp } from "ink";
4
+ import { z } from "zod";
5
+ import { Spinner, StatusMessage } from "../components/index.js";
6
+ import { getCredentials, getConfig, getInstallations, checkForUpdate, getCurrentVersion, } from "../services/index.js";
7
+ export const options = z.object({});
8
+ export default function Index(_props) {
9
+ const { exit } = useApp();
10
+ const [state, setState] = useState({ phase: "checking" });
11
+ useEffect(() => {
12
+ async function checkStatus() {
13
+ // Check if logged in
14
+ const credentials = await getCredentials();
15
+ if (!credentials) {
16
+ setState({ phase: "not_logged_in" });
17
+ exit();
18
+ return;
19
+ }
20
+ // Fetch user info from GitHub
21
+ try {
22
+ const response = await fetch("https://api.github.com/user", {
23
+ headers: {
24
+ Authorization: `Bearer ${credentials.token}`,
25
+ Accept: "application/vnd.github+json",
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ if (response.status === 401) {
30
+ setState({ phase: "not_logged_in" });
31
+ }
32
+ else {
33
+ setState({
34
+ phase: "error",
35
+ message: `GitHub API error: ${response.status}`,
36
+ });
37
+ }
38
+ exit();
39
+ return;
40
+ }
41
+ const userData = (await response.json());
42
+ const config = getConfig();
43
+ const installations = getInstallations();
44
+ // Check for updates (non-blocking, uses cache)
45
+ const updateInfo = await checkForUpdate();
46
+ setState({
47
+ phase: "logged_in",
48
+ user: userData,
49
+ defaultRepo: config.defaultRepo,
50
+ installedCount: config.installed.length,
51
+ repoCount: config.repos.length,
52
+ installations,
53
+ updateInfo,
54
+ });
55
+ }
56
+ catch (err) {
57
+ setState({
58
+ phase: "error",
59
+ message: err instanceof Error ? err.message : "Failed to fetch status",
60
+ });
61
+ }
62
+ exit();
63
+ }
64
+ checkStatus();
65
+ }, [exit]);
66
+ switch (state.phase) {
67
+ case "checking":
68
+ return _jsx(Spinner, { text: "Loading..." });
69
+ case "not_logged_in":
70
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "green", bold: true, children: "Welcome to skilluse!" }) }), _jsx(Text, { dimColor: true, children: "Let's get you set up:" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: " 1. " }), _jsx(Text, { children: "skilluse login " }), _jsx(Text, { dimColor: true, children: "Connect to GitHub" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: " 2. " }), _jsx(Text, { children: "skilluse repo add " }), _jsx(Text, { dimColor: true, children: "Add a skill repository" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: " 3. " }), _jsx(Text, { children: "skilluse search " }), _jsx(Text, { dimColor: true, children: "Find skills to install" })] })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "Run " }), _jsx(Text, { color: "green", children: "skilluse login" }), _jsx(Text, { children: " to get started." })] })] }));
71
+ case "logged_in":
72
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "green", bold: true, children: "skilluse" }), _jsxs(Text, { dimColor: true, children: [" v", getCurrentVersion()] }), state.updateInfo?.hasUpdate && (_jsxs(Text, { color: "yellow", children: [" ", "(update available: v", state.updateInfo.latestVersion, " - run 'npm update -g skilluse')"] }))] }), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: _jsxs(Box, { children: [_jsx(Text, { children: "Logged in as " }), _jsx(Text, { color: "green", bold: true, children: state.user.login }), state.user.name && _jsxs(Text, { dimColor: true, children: [" (", state.user.name, ")"] })] }) }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { children: "Default repo: " }), state.defaultRepo ? (_jsx(Text, { color: "cyan", children: state.defaultRepo })) : (_jsx(Text, { dimColor: true, children: "(not set)" }))] }), _jsxs(Box, { children: [_jsx(Text, { children: "Configured repos: " }), _jsx(Text, { children: state.repoCount })] }), _jsxs(Box, { children: [_jsx(Text, { children: "Installed skills: " }), _jsx(Text, { children: state.installedCount })] })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Quick Actions:" }), _jsx(Text, { dimColor: true, children: " skilluse repo add owner/repo Add a skill repository" }), _jsx(Text, { dimColor: true, children: " skilluse list Browse available skills" }), _jsx(Text, { dimColor: true, children: " skilluse install skill-name Install a skill" }), _jsx(Text, { dimColor: true, children: " skilluse --help Show all commands" })] })] }));
73
+ case "error":
74
+ return _jsx(StatusMessage, { type: "error", children: state.message });
75
+ }
76
+ }
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ export declare const options: z.ZodObject<{
3
+ outdated: z.ZodDefault<z.ZodBoolean>;
4
+ }, "strip", z.ZodTypeAny, {
5
+ outdated: boolean;
6
+ }, {
7
+ outdated?: boolean | undefined;
8
+ }>;
9
+ interface Props {
10
+ options: z.infer<typeof options>;
11
+ }
12
+ export default function List({ options: opts }: Props): import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Box, Text, useApp } from "ink";
4
+ import { z } from "zod";
5
+ import { Spinner, StatusMessage } from "../components/index.js";
6
+ import { getCredentials, getConfig, } from "../services/index.js";
7
+ export const options = z.object({
8
+ outdated: z
9
+ .boolean()
10
+ .default(false)
11
+ .describe("Show only outdated skills"),
12
+ });
13
+ export default function List({ options: opts }) {
14
+ const { exit } = useApp();
15
+ const [state, setState] = useState({ phase: "checking" });
16
+ useEffect(() => {
17
+ async function loadSkills() {
18
+ // Check if logged in
19
+ const credentials = await getCredentials();
20
+ if (!credentials) {
21
+ setState({ phase: "not_logged_in" });
22
+ exit();
23
+ return;
24
+ }
25
+ const config = getConfig();
26
+ let skills = config.installed;
27
+ // Filter for outdated if requested (placeholder - would need version checking)
28
+ if (opts.outdated) {
29
+ // TODO: Implement actual outdated check against remote versions
30
+ skills = [];
31
+ }
32
+ setState({ phase: "success", skills });
33
+ exit();
34
+ }
35
+ loadSkills();
36
+ }, [opts.outdated, exit]);
37
+ switch (state.phase) {
38
+ case "checking":
39
+ return _jsx(Spinner, { text: "Loading..." });
40
+ case "not_logged_in":
41
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusMessage, { type: "error", children: "Not authenticated" }), _jsx(Text, { dimColor: true, children: "Run 'skilluse login' to authenticate with GitHub" })] }));
42
+ case "success":
43
+ if (state.skills.length === 0) {
44
+ if (opts.outdated) {
45
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(StatusMessage, { type: "success", children: "All skills are up to date" }) }));
46
+ }
47
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Installed Skills" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "(no skills installed)" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Run 'skilluse install skill-name' to install one." }) })] }));
48
+ }
49
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Installed Skills" }), _jsx(Text, { children: " " }), state.skills.map((skill) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: skill.name }), _jsxs(Text, { dimColor: true, children: [" v", skill.version] }), _jsxs(Text, { dimColor: true, children: [" (", skill.scope, ")"] })] }), _jsx(Box, { marginLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["From: ", skill.repo, " | Path: ", skill.installedPath] }) })] }, skill.name)))] }));
50
+ case "error":
51
+ return _jsx(StatusMessage, { type: "error", children: state.message });
52
+ }
53
+ }
54
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ export declare const options: z.ZodObject<{
3
+ force: z.ZodDefault<z.ZodBoolean>;
4
+ }, "strip", z.ZodTypeAny, {
5
+ force: boolean;
6
+ }, {
7
+ force?: boolean | undefined;
8
+ }>;
9
+ interface Props {
10
+ options: z.infer<typeof options>;
11
+ }
12
+ export default function Login({ options: opts }: Props): import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=login.d.ts.map