@spader/dotllm 1.2.6 → 1.3.1
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/package.json +1 -1
- package/src/cli/commands/add.js +2 -0
- package/src/cli/commands/completions.js +216 -0
- package/src/cli/commands/index.js +4 -2
- package/src/cli/commands/link.js +2 -0
- package/src/cli/commands/list.js +2 -0
- package/src/cli/commands/remove.js +2 -0
- package/src/cli/commands/sync.js +2 -0
- package/src/cli/commands/which.js +20 -6
- package/src/cli/index.js +3 -2
- package/src/cli/layout.js +2 -0
- package/src/cli/prompt.js +2 -0
- package/src/cli/theme.js +2 -0
- package/src/cli/yargs.js +6 -1
- package/src/core/add.js +2 -0
- package/src/core/config.js +30 -7
- package/src/core/index.js +2 -0
- package/src/core/link.js +3 -1
- package/src/core/remove.js +4 -2
- package/src/core/sync.js +2 -0
- package/src/core/unlink.js +6 -3
- package/src/cli/commands/cd.js +0 -45
package/package.json
CHANGED
package/src/cli/commands/add.js
CHANGED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/cli/commands/completions.ts
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import os from "os";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { Config } from "@spader/dotllm/core";
|
|
9
|
+
import { defaultTheme as t } from "@spader/dotllm/cli/theme";
|
|
10
|
+
var BASH = `_dotllm() {
|
|
11
|
+
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
12
|
+
|
|
13
|
+
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
14
|
+
COMPREPLY=( $(compgen -W "add remove list link sync which completions" -- "\${cur}") )
|
|
15
|
+
return
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
case "\${COMP_WORDS[1]}" in
|
|
19
|
+
which|link)
|
|
20
|
+
local repos
|
|
21
|
+
repos=$(dotllm completions --names 2>/dev/null)
|
|
22
|
+
COMPREPLY=( $(compgen -W "\${repos}" -- "\${cur}") )
|
|
23
|
+
;;
|
|
24
|
+
esac
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
complete -F _dotllm dotllm`;
|
|
28
|
+
var ZSH = `#compdef dotllm
|
|
29
|
+
|
|
30
|
+
_dotllm() {
|
|
31
|
+
local -a commands
|
|
32
|
+
commands=(
|
|
33
|
+
'add:Register a new repo'
|
|
34
|
+
'remove:Remove a repo from the registry'
|
|
35
|
+
'list:Show the registry'
|
|
36
|
+
'link:Link references'
|
|
37
|
+
'sync:Sync linked repos'
|
|
38
|
+
'which:Show repo store path'
|
|
39
|
+
'completions:Output shell completions'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
_arguments -C '1:command:->cmd' '*::arg:->args'
|
|
43
|
+
|
|
44
|
+
case "$state" in
|
|
45
|
+
cmd)
|
|
46
|
+
_describe 'command' commands
|
|
47
|
+
;;
|
|
48
|
+
args)
|
|
49
|
+
case "\${words[1]}" in
|
|
50
|
+
which|link)
|
|
51
|
+
local -a repos
|
|
52
|
+
repos=(\${(f)"$(dotllm completions --names 2>/dev/null)"})
|
|
53
|
+
_describe 'repo' repos
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_dotllm`;
|
|
61
|
+
var FISH = `complete -c dotllm -f
|
|
62
|
+
complete -c dotllm -n "__fish_use_subcommand" -a add -d "Register a new repo"
|
|
63
|
+
complete -c dotllm -n "__fish_use_subcommand" -a remove -d "Remove a repo from the registry"
|
|
64
|
+
complete -c dotllm -n "__fish_use_subcommand" -a list -d "Show the registry"
|
|
65
|
+
complete -c dotllm -n "__fish_use_subcommand" -a link -d "Link references"
|
|
66
|
+
complete -c dotllm -n "__fish_use_subcommand" -a sync -d "Sync linked repos"
|
|
67
|
+
complete -c dotllm -n "__fish_use_subcommand" -a which -d "Show repo store path"
|
|
68
|
+
complete -c dotllm -n "__fish_use_subcommand" -a completions -d "Output shell completions"
|
|
69
|
+
complete -c dotllm -n "__fish_seen_subcommand_from which link" -a "(dotllm completions --names 2>/dev/null)"`;
|
|
70
|
+
var CANARY = "@dotllm_completions";
|
|
71
|
+
function completionFile(shell) {
|
|
72
|
+
return path.join(path.dirname(Config.storeDir()), `completions.${shell}`);
|
|
73
|
+
}
|
|
74
|
+
function hookSnippet(shell) {
|
|
75
|
+
const file = completionFile(shell);
|
|
76
|
+
switch (shell) {
|
|
77
|
+
case "bash":
|
|
78
|
+
return `
|
|
79
|
+
# ${CANARY}
|
|
80
|
+
# Installed by the dotllm CLI
|
|
81
|
+
[ -f "${file}" ] && source "${file}"
|
|
82
|
+
`;
|
|
83
|
+
case "zsh":
|
|
84
|
+
return `
|
|
85
|
+
# ${CANARY}
|
|
86
|
+
# Installed by the dotllm CLI
|
|
87
|
+
[ -f "${file}" ] && source "${file}"
|
|
88
|
+
`;
|
|
89
|
+
case "fish":
|
|
90
|
+
return `
|
|
91
|
+
# ${CANARY}
|
|
92
|
+
# Installed by the dotllm CLI
|
|
93
|
+
test -f "${file}"; and source "${file}"
|
|
94
|
+
`;
|
|
95
|
+
default:
|
|
96
|
+
return "";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function rcPath(shell) {
|
|
100
|
+
const home = os.homedir();
|
|
101
|
+
switch (shell) {
|
|
102
|
+
case "bash": {
|
|
103
|
+
const bashrc = path.join(home, ".bashrc");
|
|
104
|
+
if (fs.existsSync(bashrc))
|
|
105
|
+
return bashrc;
|
|
106
|
+
return path.join(home, ".bash_profile");
|
|
107
|
+
}
|
|
108
|
+
case "zsh":
|
|
109
|
+
return path.join(home, ".zshrc");
|
|
110
|
+
case "fish":
|
|
111
|
+
return path.join(home, ".config", "fish", "config.fish");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
var install = {
|
|
115
|
+
description: "Add completions to your shell rc file",
|
|
116
|
+
summary: "Install completions",
|
|
117
|
+
handler: async (argv) => {
|
|
118
|
+
if (process.platform === "win32") {
|
|
119
|
+
console.log(t.dim("Shell completions are not supported on Windows."));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const shell = detectShell();
|
|
123
|
+
const rc = rcPath(shell);
|
|
124
|
+
if (!rc) {
|
|
125
|
+
console.error(t.error(`Could not determine rc file for shell: "${shell}"`));
|
|
126
|
+
process.exit(1);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const script = shellScript(shell);
|
|
130
|
+
if (!script) {
|
|
131
|
+
console.error(t.error(`Unknown shell: "${shell}"`));
|
|
132
|
+
process.exit(1);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const cached = completionFile(shell);
|
|
136
|
+
fs.mkdirSync(path.dirname(cached), { recursive: true });
|
|
137
|
+
fs.writeFileSync(cached, script + `
|
|
138
|
+
`);
|
|
139
|
+
const existing = fs.existsSync(rc) ? fs.readFileSync(rc, "utf-8") : "";
|
|
140
|
+
if (existing.includes(CANARY)) {
|
|
141
|
+
console.log(t.dim(`Updated ${cached}`));
|
|
142
|
+
console.log(t.dim(`Already sourced from ${rc}`));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
fs.appendFileSync(rc, hookSnippet(shell));
|
|
146
|
+
console.log(`Installed completions in ${t.link(rc)}`);
|
|
147
|
+
console.log(t.dim(`Restart your shell or run: source ${rc}`));
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var command = {
|
|
151
|
+
description: "Output shell completion script for bash, zsh, or fish",
|
|
152
|
+
summary: "Shell completions",
|
|
153
|
+
options: {
|
|
154
|
+
shell: {
|
|
155
|
+
alias: "s",
|
|
156
|
+
type: "string",
|
|
157
|
+
description: "Shell type: bash, zsh, or fish"
|
|
158
|
+
},
|
|
159
|
+
names: {
|
|
160
|
+
type: "boolean",
|
|
161
|
+
description: "Print repo names (used internally by completions)"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
commands: {
|
|
165
|
+
install
|
|
166
|
+
},
|
|
167
|
+
handler: async (argv) => {
|
|
168
|
+
if (process.platform === "win32") {
|
|
169
|
+
console.log(t.dim("Shell completions are not supported on Windows."));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (argv.names) {
|
|
173
|
+
const { Config: Config2 } = await import("@spader/dotllm/core");
|
|
174
|
+
const global = Config2.Global.read();
|
|
175
|
+
for (const r of global.repos)
|
|
176
|
+
console.log(r.name);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const shell = typeof argv.shell === "string" && argv.shell.length > 0 ? argv.shell : detectShell();
|
|
180
|
+
switch (shell) {
|
|
181
|
+
case "bash":
|
|
182
|
+
console.log(BASH);
|
|
183
|
+
break;
|
|
184
|
+
case "zsh":
|
|
185
|
+
console.log(ZSH);
|
|
186
|
+
break;
|
|
187
|
+
case "fish":
|
|
188
|
+
console.log(FISH);
|
|
189
|
+
break;
|
|
190
|
+
default:
|
|
191
|
+
console.error(t.error(`Unknown shell: "${shell}". Use bash, zsh, or fish.`));
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
function shellScript(shell) {
|
|
197
|
+
switch (shell) {
|
|
198
|
+
case "bash":
|
|
199
|
+
return BASH;
|
|
200
|
+
case "zsh":
|
|
201
|
+
return ZSH;
|
|
202
|
+
case "fish":
|
|
203
|
+
return FISH;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function detectShell() {
|
|
207
|
+
const login = process.env.SHELL ?? "";
|
|
208
|
+
if (login.endsWith("/fish"))
|
|
209
|
+
return "fish";
|
|
210
|
+
if (login.endsWith("/zsh"))
|
|
211
|
+
return "zsh";
|
|
212
|
+
return "bash";
|
|
213
|
+
}
|
|
214
|
+
export {
|
|
215
|
+
command
|
|
216
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/cli/commands/index.ts
|
|
3
5
|
import { command } from "@spader/dotllm/cli/commands/add";
|
|
4
6
|
import { command as command2 } from "@spader/dotllm/cli/commands/remove";
|
|
@@ -6,13 +8,13 @@ import { command as command3 } from "@spader/dotllm/cli/commands/list";
|
|
|
6
8
|
import { command as command4 } from "@spader/dotllm/cli/commands/link";
|
|
7
9
|
import { command as command5 } from "@spader/dotllm/cli/commands/sync";
|
|
8
10
|
import { command as command6 } from "@spader/dotllm/cli/commands/which";
|
|
9
|
-
import { command as command7 } from "@spader/dotllm/cli/commands/
|
|
11
|
+
import { command as command7 } from "@spader/dotllm/cli/commands/completions";
|
|
10
12
|
export {
|
|
11
13
|
command6 as which,
|
|
12
14
|
command5 as sync,
|
|
13
15
|
command2 as remove,
|
|
14
16
|
command3 as list,
|
|
15
17
|
command4 as link,
|
|
16
|
-
command7 as
|
|
18
|
+
command7 as completions,
|
|
17
19
|
command as add
|
|
18
20
|
};
|
package/src/cli/commands/link.js
CHANGED
package/src/cli/commands/list.js
CHANGED
package/src/cli/commands/sync.js
CHANGED
|
@@ -1,28 +1,42 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/cli/commands/which.ts
|
|
3
5
|
import path from "path";
|
|
4
6
|
import { Config } from "@spader/dotllm/core";
|
|
5
7
|
import { defaultTheme as t } from "@spader/dotllm/cli/theme";
|
|
6
8
|
var command = {
|
|
7
|
-
description: "Print the absolute path to a repo in the store",
|
|
9
|
+
description: "Print the absolute path to a repo in the store (prefix match, shortest wins)",
|
|
8
10
|
summary: "Show repo store path",
|
|
9
11
|
positionals: {
|
|
10
12
|
name: {
|
|
11
13
|
type: "string",
|
|
12
|
-
description: "Name of the repo",
|
|
14
|
+
description: "Name (or prefix) of the repo",
|
|
13
15
|
required: true
|
|
14
16
|
}
|
|
15
17
|
},
|
|
16
18
|
handler: (argv) => {
|
|
17
19
|
const name = String(argv.name);
|
|
18
20
|
const global = Config.Global.read();
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
console.
|
|
21
|
+
const exact = Config.Global.find(global, name);
|
|
22
|
+
if (exact) {
|
|
23
|
+
console.log(path.join(Config.storeDir(), exact.name));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const lower = name.toLowerCase();
|
|
27
|
+
const matches = global.repos.filter((r) => r.name.toLowerCase().startsWith(lower)).sort((a, b) => a.name.length - b.name.length);
|
|
28
|
+
if (matches.length === 0) {
|
|
29
|
+
console.error(t.error(`No repo matching "${name}" in registry`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (matches.length > 1 && matches[0].name.length === matches[1].name.length) {
|
|
34
|
+
const names = matches.filter((m) => m.name.length === matches[0].name.length).map((m) => m.name);
|
|
35
|
+
console.error(t.error(`Ambiguous prefix "${name}": ${names.join(", ")}`));
|
|
22
36
|
process.exit(1);
|
|
23
37
|
return;
|
|
24
38
|
}
|
|
25
|
-
console.log(path.join(Config.storeDir(), name));
|
|
39
|
+
console.log(path.join(Config.storeDir(), matches[0].name));
|
|
26
40
|
}
|
|
27
41
|
};
|
|
28
42
|
export {
|
package/src/cli/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __require = import.meta.require;
|
|
3
4
|
|
|
4
5
|
// src/cli/index.ts
|
|
5
6
|
import { build } from "@spader/dotllm/cli/yargs";
|
|
6
|
-
import { add, remove, list, link, sync, which,
|
|
7
|
+
import { add, remove, list, link, sync, which, completions } from "@spader/dotllm/cli/commands/index";
|
|
7
8
|
var DotLlmCli;
|
|
8
9
|
((DotLlmCli) => {
|
|
9
10
|
async function run() {
|
|
@@ -20,7 +21,7 @@ var DotLlmCli;
|
|
|
20
21
|
link,
|
|
21
22
|
sync,
|
|
22
23
|
which,
|
|
23
|
-
|
|
24
|
+
completions
|
|
24
25
|
}
|
|
25
26
|
};
|
|
26
27
|
build(def).parse();
|
package/src/cli/layout.js
CHANGED
package/src/cli/prompt.js
CHANGED
package/src/cli/theme.js
CHANGED
package/src/cli/yargs.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/cli/yargs.ts
|
|
3
5
|
import yargs from "yargs";
|
|
4
6
|
import { hideBin } from "yargs/helpers";
|
|
@@ -145,7 +147,10 @@ function configure(y, def, root, path) {
|
|
|
145
147
|
for (const [k, v] of Object.entries(def.commands)) {
|
|
146
148
|
command(y, k, v, root, path);
|
|
147
149
|
}
|
|
148
|
-
|
|
150
|
+
const hasHandler = "handler" in def && typeof def.handler === "function";
|
|
151
|
+
if (!hasHandler) {
|
|
152
|
+
y.demandCommand(1, "You must specify a command");
|
|
153
|
+
}
|
|
149
154
|
}
|
|
150
155
|
y.help(false).option("help", { alias: "h", type: "boolean", describe: "Show help" }).check(check(def, root, path)).fail(fail(def, root, path));
|
|
151
156
|
if (path.length === 0 && "version" in def && def.version) {
|
package/src/core/add.js
CHANGED
package/src/core/config.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/core/config.ts
|
|
3
5
|
import fs from "fs";
|
|
6
|
+
import os from "os";
|
|
4
7
|
import path from "path";
|
|
5
8
|
import { z } from "zod";
|
|
6
9
|
var LOCAL_DIR = ".llm";
|
|
7
10
|
var LOCAL_FILE = path.join(LOCAL_DIR, "dotllm.json");
|
|
8
11
|
var REF_DIR = path.join(LOCAL_DIR, "reference");
|
|
9
12
|
function home() {
|
|
10
|
-
|
|
13
|
+
if (process.platform === "win32") {
|
|
14
|
+
const appData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local");
|
|
15
|
+
return path.join(appData, "dotllm");
|
|
16
|
+
}
|
|
17
|
+
return path.join(process.env.HOME ?? os.homedir(), ".local", "share", "dotllm");
|
|
11
18
|
}
|
|
12
19
|
var RepoEntry = z.object({
|
|
13
20
|
kind: z.enum(["url", "file"]),
|
|
@@ -51,16 +58,19 @@ var Config;
|
|
|
51
58
|
}
|
|
52
59
|
Global.write = write;
|
|
53
60
|
function find(config, name) {
|
|
54
|
-
|
|
61
|
+
const lower = name.toLowerCase();
|
|
62
|
+
return config.repos.find((r) => r.name.toLowerCase() === lower);
|
|
55
63
|
}
|
|
56
64
|
Global.find = find;
|
|
57
65
|
function add(config, entry) {
|
|
58
|
-
const
|
|
66
|
+
const lower = entry.name.toLowerCase();
|
|
67
|
+
const filtered = config.repos.filter((r) => r.name.toLowerCase() !== lower);
|
|
59
68
|
return { repos: [...filtered, entry] };
|
|
60
69
|
}
|
|
61
70
|
Global.add = add;
|
|
62
71
|
function remove(config, name) {
|
|
63
|
-
|
|
72
|
+
const lower = name.toLowerCase();
|
|
73
|
+
return { repos: config.repos.filter((r) => r.name.toLowerCase() !== lower) };
|
|
64
74
|
}
|
|
65
75
|
Global.remove = remove;
|
|
66
76
|
})(Global = Config.Global ||= {});
|
|
@@ -82,16 +92,29 @@ var Config;
|
|
|
82
92
|
`);
|
|
83
93
|
}
|
|
84
94
|
Local.write = write;
|
|
95
|
+
function find(config, name) {
|
|
96
|
+
const lower = name.toLowerCase();
|
|
97
|
+
for (const [key, value] of Object.entries(config.refs)) {
|
|
98
|
+
if (key.toLowerCase() === lower)
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
Local.find = find;
|
|
85
104
|
function has(config, name) {
|
|
86
|
-
return
|
|
105
|
+
return find(config, name) !== undefined;
|
|
87
106
|
}
|
|
88
107
|
Local.has = has;
|
|
89
108
|
function add(config, repo) {
|
|
90
|
-
|
|
109
|
+
const lower = repo.name.toLowerCase();
|
|
110
|
+
const refs = Object.fromEntries(Object.entries(config.refs).filter(([key]) => key.toLowerCase() !== lower));
|
|
111
|
+
refs[repo.name] = repo;
|
|
112
|
+
return { refs };
|
|
91
113
|
}
|
|
92
114
|
Local.add = add;
|
|
93
115
|
function remove(config, name) {
|
|
94
|
-
const
|
|
116
|
+
const lower = name.toLowerCase();
|
|
117
|
+
const refs = Object.fromEntries(Object.entries(config.refs).filter(([key]) => key.toLowerCase() !== lower));
|
|
95
118
|
return { refs };
|
|
96
119
|
}
|
|
97
120
|
Local.remove = remove;
|
package/src/core/index.js
CHANGED
package/src/core/link.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/core/link.ts
|
|
3
5
|
import { Config } from "@spader/dotllm/core/config";
|
|
4
6
|
import { sync } from "@spader/dotllm/core/sync";
|
|
@@ -8,7 +10,7 @@ function link(names) {
|
|
|
8
10
|
const repo = Config.Global.find(global, name);
|
|
9
11
|
if (!repo)
|
|
10
12
|
return null;
|
|
11
|
-
return [name, repo];
|
|
13
|
+
return [repo.name, repo];
|
|
12
14
|
}).filter((row) => row !== null);
|
|
13
15
|
Config.Local.write({ refs: Object.fromEntries(rows) });
|
|
14
16
|
return sync();
|
package/src/core/remove.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/core/remove.ts
|
|
3
5
|
import fs from "fs";
|
|
4
6
|
import path from "path";
|
|
@@ -9,7 +11,7 @@ function remove(name) {
|
|
|
9
11
|
if (!found) {
|
|
10
12
|
return { ok: false, error: `No repo named "${name}" in registry` };
|
|
11
13
|
}
|
|
12
|
-
const target = path.join(Config.storeDir(), name);
|
|
14
|
+
const target = path.join(Config.storeDir(), found.name);
|
|
13
15
|
if (fs.existsSync(target)) {
|
|
14
16
|
const stat = fs.lstatSync(target);
|
|
15
17
|
if (stat.isSymbolicLink()) {
|
|
@@ -19,7 +21,7 @@ function remove(name) {
|
|
|
19
21
|
fs.rmSync(target, { recursive: true, force: true });
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
|
-
Config.Global.write(Config.Global.remove(global, name));
|
|
24
|
+
Config.Global.write(Config.Global.remove(global, found.name));
|
|
23
25
|
return { ok: true };
|
|
24
26
|
}
|
|
25
27
|
export {
|
package/src/core/sync.js
CHANGED
package/src/core/unlink.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/core/unlink.ts
|
|
3
5
|
import fs from "fs";
|
|
4
6
|
import path from "path";
|
|
5
7
|
import { Config } from "@spader/dotllm/core/config";
|
|
6
8
|
function unlink(name) {
|
|
7
9
|
const local = Config.Local.read();
|
|
8
|
-
|
|
10
|
+
const found = Config.Local.find(local, name);
|
|
11
|
+
if (!found) {
|
|
9
12
|
return { ok: false, error: `"${name}" is not linked in local config` };
|
|
10
13
|
}
|
|
11
|
-
const target = path.join(Config.refDir(), name);
|
|
14
|
+
const target = path.join(Config.refDir(), found.name);
|
|
12
15
|
if (fs.existsSync(target)) {
|
|
13
16
|
fs.unlinkSync(target);
|
|
14
17
|
}
|
|
15
|
-
Config.Local.write(Config.Local.remove(local, name));
|
|
18
|
+
Config.Local.write(Config.Local.remove(local, found.name));
|
|
16
19
|
return { ok: true };
|
|
17
20
|
}
|
|
18
21
|
export {
|
package/src/cli/commands/cd.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// src/cli/commands/cd.ts
|
|
3
|
-
import path from "path";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import { Config } from "@spader/dotllm/core";
|
|
6
|
-
import { defaultTheme as t } from "@spader/dotllm/cli/theme";
|
|
7
|
-
var command = {
|
|
8
|
-
description: "Open a subshell in a repo's store directory",
|
|
9
|
-
summary: "cd into a repo",
|
|
10
|
-
positionals: {
|
|
11
|
-
name: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "Name of the repo",
|
|
14
|
-
required: true
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
handler: async (argv) => {
|
|
18
|
-
const name = String(argv.name);
|
|
19
|
-
const global = Config.Global.read();
|
|
20
|
-
const repo = Config.Global.find(global, name);
|
|
21
|
-
if (!repo) {
|
|
22
|
-
console.error(t.error(`No repo named "${name}" in registry`));
|
|
23
|
-
process.exit(1);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const dir = path.join(Config.storeDir(), name);
|
|
27
|
-
if (!fs.existsSync(dir)) {
|
|
28
|
-
console.error(t.error(`Store path does not exist: ${dir}`));
|
|
29
|
-
process.exit(1);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const shell = process.env.SHELL ?? "/bin/sh";
|
|
33
|
-
const proc = Bun.spawn([shell], {
|
|
34
|
-
cwd: dir,
|
|
35
|
-
stdin: "inherit",
|
|
36
|
-
stdout: "inherit",
|
|
37
|
-
stderr: "inherit"
|
|
38
|
-
});
|
|
39
|
-
const code = await proc.exited;
|
|
40
|
-
process.exit(code);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
export {
|
|
44
|
-
command
|
|
45
|
-
};
|