skilluse 0.1.0 → 0.1.3

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 (67) hide show
  1. package/dist/index.js +7291 -12079
  2. package/package.json +5 -5
  3. package/dist/app.d.ts +0 -6
  4. package/dist/app.js +0 -6
  5. package/dist/cli.d.ts +0 -3
  6. package/dist/cli.js +0 -167
  7. package/dist/commands/demo.d.ts +0 -14
  8. package/dist/commands/demo.js +0 -46
  9. package/dist/commands/index.d.ts +0 -8
  10. package/dist/commands/index.js +0 -77
  11. package/dist/commands/list.d.ts +0 -14
  12. package/dist/commands/list.js +0 -54
  13. package/dist/commands/login.d.ts +0 -14
  14. package/dist/commands/login.js +0 -153
  15. package/dist/commands/logout.d.ts +0 -8
  16. package/dist/commands/logout.js +0 -47
  17. package/dist/commands/repo/add.d.ts +0 -22
  18. package/dist/commands/repo/add.js +0 -139
  19. package/dist/commands/repo/edit.d.ts +0 -19
  20. package/dist/commands/repo/edit.js +0 -117
  21. package/dist/commands/repo/index.d.ts +0 -8
  22. package/dist/commands/repo/index.js +0 -47
  23. package/dist/commands/repo/list.d.ts +0 -8
  24. package/dist/commands/repo/list.js +0 -47
  25. package/dist/commands/repo/remove.d.ts +0 -16
  26. package/dist/commands/repo/remove.js +0 -83
  27. package/dist/commands/repo/sync.d.ts +0 -10
  28. package/dist/commands/repo/sync.js +0 -78
  29. package/dist/commands/repo/use.d.ts +0 -10
  30. package/dist/commands/repo/use.js +0 -56
  31. package/dist/commands/repos.d.ts +0 -11
  32. package/dist/commands/repos.js +0 -50
  33. package/dist/commands/search.d.ts +0 -16
  34. package/dist/commands/search.js +0 -199
  35. package/dist/commands/skills.d.ts +0 -11
  36. package/dist/commands/skills.js +0 -43
  37. package/dist/commands/whoami.d.ts +0 -8
  38. package/dist/commands/whoami.js +0 -69
  39. package/dist/components/CLIError.d.ts +0 -27
  40. package/dist/components/CLIError.js +0 -24
  41. package/dist/components/ProgressBar.d.ts +0 -7
  42. package/dist/components/ProgressBar.js +0 -9
  43. package/dist/components/Select.d.ts +0 -11
  44. package/dist/components/Select.js +0 -6
  45. package/dist/components/Spinner.d.ts +0 -6
  46. package/dist/components/Spinner.js +0 -7
  47. package/dist/components/StatusMessage.d.ts +0 -9
  48. package/dist/components/StatusMessage.js +0 -13
  49. package/dist/components/Table.d.ts +0 -9
  50. package/dist/components/Table.js +0 -27
  51. package/dist/components/TextInput.d.ts +0 -9
  52. package/dist/components/TextInput.js +0 -6
  53. package/dist/components/index.d.ts +0 -8
  54. package/dist/components/index.js +0 -8
  55. package/dist/index.d.ts +0 -3
  56. package/dist/services/credentials.d.ts +0 -69
  57. package/dist/services/credentials.js +0 -216
  58. package/dist/services/index.d.ts +0 -6
  59. package/dist/services/index.js +0 -10
  60. package/dist/services/oauth.d.ts +0 -106
  61. package/dist/services/oauth.js +0 -208
  62. package/dist/services/paths.d.ts +0 -19
  63. package/dist/services/paths.js +0 -21
  64. package/dist/services/store.d.ts +0 -64
  65. package/dist/services/store.js +0 -107
  66. package/dist/services/update.d.ts +0 -20
  67. package/dist/services/update.js +0 -93
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilluse",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "CLI tool for managing and installing AI Coding Agent Skills",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -13,12 +13,12 @@
13
13
  ],
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "git+https://github.com/jiweiyuan/skilluse.git",
16
+ "url": "git+https://github.com/skilluse/skilluse.git",
17
17
  "directory": "packages/cli"
18
18
  },
19
- "homepage": "https://github.com/jiweiyuan/skilluse",
19
+ "homepage": "https://github.com/skilluse/skilluse",
20
20
  "bugs": {
21
- "url": "https://github.com/jiweiyuan/skilluse/issues"
21
+ "url": "https://github.com/skilluse/skilluse/issues"
22
22
  },
23
23
  "publishConfig": {
24
24
  "access": "public"
@@ -52,7 +52,7 @@
52
52
  "ink-select-input": "^6.2.0",
53
53
  "ink-spinner": "^5.0.0",
54
54
  "ink-text-input": "^6.0.0",
55
- "pastel": "^2.0.0",
55
+ "pastel": "^4.0.0",
56
56
  "react": "^18.2.0",
57
57
  "zod": "^3.22.4"
58
58
  },
package/dist/app.d.ts DELETED
@@ -1,6 +0,0 @@
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 DELETED
@@ -1,6 +0,0 @@
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 DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bun
2
- export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js DELETED
@@ -1,167 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,46 +0,0 @@
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
@@ -1,8 +0,0 @@
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
@@ -1,77 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,54 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,153 +0,0 @@
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 { requestDeviceCode, pollUntilComplete, openBrowser, getCredentials, setCredentials, getUserInstallations, setInstallations, setDefaultInstallation, } from "../services/index.js";
7
- // GitHub App Client ID for Skilluse CLI
8
- // These are public values, safe to embed in client code
9
- // Override with SKILLUSE_GITHUB_CLIENT_ID env var for development
10
- const GITHUB_CLIENT_ID = process.env.SKILLUSE_GITHUB_CLIENT_ID || "Iv23liOOBSjdH2IRT6W2";
11
- export const options = z.object({
12
- force: z
13
- .boolean()
14
- .default(false)
15
- .describe("Force re-authentication even if already logged in"),
16
- });
17
- export default function Login({ options: opts }) {
18
- const { exit } = useApp();
19
- const [state, setState] = useState({ phase: "checking" });
20
- useEffect(() => {
21
- async function runLogin() {
22
- // Check if already logged in
23
- if (!opts.force) {
24
- const existing = await getCredentials();
25
- if (existing) {
26
- setState({ phase: "already_logged_in", username: existing.user });
27
- exit();
28
- return;
29
- }
30
- }
31
- // Request device code
32
- setState({ phase: "requesting_code" });
33
- let deviceCode;
34
- try {
35
- deviceCode = await requestDeviceCode(GITHUB_CLIENT_ID, "repo,user");
36
- }
37
- catch (err) {
38
- setState({
39
- phase: "error",
40
- message: err instanceof Error ? err.message : "Failed to start authentication",
41
- });
42
- exit();
43
- return;
44
- }
45
- // Show user code and open browser
46
- setState({
47
- phase: "waiting_for_auth",
48
- userCode: deviceCode.user_code,
49
- verificationUri: deviceCode.verification_uri,
50
- });
51
- // Try to open browser automatically
52
- try {
53
- await openBrowser(deviceCode.verification_uri);
54
- }
55
- catch {
56
- // Browser opening failed, user will need to open manually
57
- }
58
- // Poll for access token
59
- const result = await pollUntilComplete(GITHUB_CLIENT_ID, deviceCode.device_code, deviceCode.expires_in, deviceCode.interval);
60
- if (!result.success) {
61
- const messages = {
62
- expired: "Authentication timed out. Please try again.",
63
- denied: "Authentication was denied.",
64
- error: result.message || "Authentication failed.",
65
- };
66
- setState({ phase: "error", message: messages[result.reason] });
67
- exit();
68
- return;
69
- }
70
- // Fetch user info from GitHub
71
- let username;
72
- const accessToken = result.token.access_token;
73
- try {
74
- const userResponse = await fetch("https://api.github.com/user", {
75
- headers: {
76
- Authorization: `Bearer ${accessToken}`,
77
- Accept: "application/vnd.github+json",
78
- },
79
- });
80
- if (!userResponse.ok) {
81
- throw new Error("Failed to fetch user info");
82
- }
83
- const userData = (await userResponse.json());
84
- username = userData.login;
85
- }
86
- catch {
87
- setState({ phase: "error", message: "Failed to fetch user info from GitHub" });
88
- exit();
89
- return;
90
- }
91
- // Store credentials
92
- await setCredentials(accessToken, username);
93
- // Fetch GitHub App installations
94
- setState({ phase: "fetching_installations" });
95
- let installations;
96
- try {
97
- installations = await getUserInstallations(accessToken);
98
- }
99
- catch (err) {
100
- // If we can't fetch installations, show prompt to install
101
- setState({
102
- phase: "no_installation",
103
- installUrl: "https://github.com/apps/skilluse/installations/new",
104
- });
105
- exit();
106
- return;
107
- }
108
- if (installations.length === 0) {
109
- // No installations, prompt user to install
110
- setState({
111
- phase: "no_installation",
112
- installUrl: "https://github.com/apps/skilluse/installations/new",
113
- });
114
- exit();
115
- return;
116
- }
117
- // Convert to StoredInstallation and save
118
- const storedInstallations = installations.map((inst) => ({
119
- id: inst.id,
120
- account: inst.account.login,
121
- accountType: inst.account.type,
122
- repositorySelection: inst.repository_selection,
123
- }));
124
- await setInstallations(storedInstallations);
125
- // If single installation, set as default
126
- if (storedInstallations.length === 1) {
127
- await setDefaultInstallation(storedInstallations[0].id);
128
- }
129
- setState({ phase: "success", username, installations: storedInstallations });
130
- exit();
131
- }
132
- runLogin();
133
- }, [opts.force, exit]);
134
- switch (state.phase) {
135
- case "checking":
136
- return _jsx(Spinner, { text: "Checking authentication status..." });
137
- case "already_logged_in":
138
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(StatusMessage, { type: "success", children: ["Already logged in as ", state.username] }), _jsx(Text, { dimColor: true, children: "Use --force to re-authenticate" })] }));
139
- case "requesting_code":
140
- return _jsx(Spinner, { text: "Starting authentication..." });
141
- case "waiting_for_auth":
142
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { children: "Open " }), _jsx(Text, { color: "cyan", bold: true, children: state.verificationUri }), _jsx(Text, { children: " and enter code:" })] }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", bold: true, children: state.userCode }) }), _jsx(Spinner, { text: "Waiting for authentication..." })] }));
143
- case "fetching_installations":
144
- return _jsx(Spinner, { text: "Fetching GitHub App installations..." });
145
- case "no_installation":
146
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusMessage, { type: "warning", children: "You need to install Skilluse CLI on your GitHub account" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "Open: " }), _jsx(Text, { color: "cyan", bold: true, children: state.installUrl })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Then run 'skilluse login' again." }) })] }));
147
- case "success":
148
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(StatusMessage, { type: "success", children: ["Logged in as ", state.username] }), state.installations.length > 0 && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: [state.installations.length, " installation", state.installations.length > 1 ? "s" : "", " found:"] }), state.installations.map((inst) => (_jsxs(Text, { dimColor: true, children: ["\u2022 ", inst.account, " (", inst.accountType.toLowerCase(), ")"] }, inst.id)))] }))] }));
149
- case "error":
150
- return _jsx(StatusMessage, { type: "error", children: state.message });
151
- }
152
- }
153
- //# sourceMappingURL=login.js.map
@@ -1,8 +0,0 @@
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 Logout(_props: Props): import("react/jsx-runtime").JSX.Element;
7
- export {};
8
- //# sourceMappingURL=logout.d.ts.map