@sporesec/arcana 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +120 -9
- package/dist/command-registry.d.ts +10 -0
- package/dist/command-registry.js +65 -0
- package/dist/commands/audit.d.ts +0 -1
- package/dist/commands/audit.js +16 -6
- package/dist/commands/benchmark.d.ts +4 -0
- package/dist/commands/benchmark.js +178 -0
- package/dist/commands/clean.d.ts +0 -1
- package/dist/commands/clean.js +19 -8
- package/dist/commands/compact.d.ts +2 -1
- package/dist/commands/compact.js +74 -14
- package/dist/commands/completions.d.ts +3 -0
- package/dist/commands/completions.js +104 -0
- package/dist/commands/config.d.ts +0 -1
- package/dist/commands/config.js +15 -6
- package/dist/commands/create.d.ts +0 -1
- package/dist/commands/create.js +1 -1
- package/dist/commands/diff.d.ts +4 -0
- package/dist/commands/diff.js +166 -0
- package/dist/commands/doctor.d.ts +0 -1
- package/dist/commands/doctor.js +64 -23
- package/dist/commands/export-cmd.d.ts +4 -0
- package/dist/commands/export-cmd.js +66 -0
- package/dist/commands/import-cmd.d.ts +4 -0
- package/dist/commands/import-cmd.js +131 -0
- package/dist/commands/info.d.ts +0 -1
- package/dist/commands/info.js +29 -4
- package/dist/commands/init.d.ts +0 -1
- package/dist/commands/init.js +26 -33
- package/dist/commands/install.d.ts +1 -1
- package/dist/commands/install.js +118 -205
- package/dist/commands/list.d.ts +0 -1
- package/dist/commands/list.js +12 -4
- package/dist/commands/lock.d.ts +4 -0
- package/dist/commands/lock.js +171 -0
- package/dist/commands/optimize.d.ts +0 -1
- package/dist/commands/optimize.js +111 -20
- package/dist/commands/outdated.d.ts +4 -0
- package/dist/commands/outdated.js +159 -0
- package/dist/commands/profile.d.ts +3 -0
- package/dist/commands/profile.js +274 -0
- package/dist/commands/providers.d.ts +0 -1
- package/dist/commands/providers.js +1 -4
- package/dist/commands/recommend.d.ts +5 -0
- package/dist/commands/recommend.js +96 -0
- package/dist/commands/scan.d.ts +0 -1
- package/dist/commands/scan.js +13 -7
- package/dist/commands/search.d.ts +2 -1
- package/dist/commands/search.js +32 -9
- package/dist/commands/stats.d.ts +0 -1
- package/dist/commands/stats.js +24 -20
- package/dist/commands/team.d.ts +3 -0
- package/dist/commands/team.js +291 -0
- package/dist/commands/uninstall.d.ts +0 -1
- package/dist/commands/uninstall.js +18 -4
- package/dist/commands/update.d.ts +0 -1
- package/dist/commands/update.js +155 -155
- package/dist/commands/validate.d.ts +0 -1
- package/dist/commands/validate.js +14 -6
- package/dist/commands/verify.d.ts +4 -0
- package/dist/commands/verify.js +116 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +13 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interactive/browse.d.ts +4 -0
- package/dist/interactive/browse.js +103 -0
- package/dist/interactive/categories.d.ts +4 -0
- package/dist/interactive/categories.js +87 -0
- package/dist/interactive/health.d.ts +1 -0
- package/dist/interactive/health.js +57 -0
- package/dist/interactive/helpers.d.ts +11 -0
- package/dist/interactive/helpers.js +66 -0
- package/dist/interactive/index.d.ts +1 -0
- package/dist/interactive/index.js +1 -0
- package/dist/interactive/manage.d.ts +2 -0
- package/dist/interactive/manage.js +187 -0
- package/dist/interactive/menu.d.ts +1 -0
- package/dist/interactive/menu.js +107 -0
- package/dist/interactive/search.d.ts +2 -0
- package/dist/interactive/search.js +66 -0
- package/dist/interactive/setup.d.ts +2 -0
- package/dist/interactive/setup.js +48 -0
- package/dist/interactive/skill-detail.d.ts +5 -0
- package/dist/interactive/skill-detail.js +126 -0
- package/dist/interactive.d.ts +0 -1
- package/dist/interactive.js +89 -66
- package/dist/providers/arcana.d.ts +0 -1
- package/dist/providers/arcana.js +0 -1
- package/dist/providers/base.d.ts +0 -1
- package/dist/providers/base.js +0 -1
- package/dist/providers/github.d.ts +0 -1
- package/dist/providers/github.js +8 -3
- package/dist/registry.d.ts +0 -1
- package/dist/registry.js +1 -4
- package/dist/types.d.ts +10 -1
- package/dist/types.js +0 -1
- package/dist/utils/atomic.d.ts +0 -1
- package/dist/utils/atomic.js +3 -2
- package/dist/utils/cache.d.ts +0 -1
- package/dist/utils/cache.js +3 -2
- package/dist/utils/config.d.ts +2 -1
- package/dist/utils/config.js +30 -5
- package/dist/utils/conflict-check.d.ts +8 -0
- package/dist/utils/conflict-check.js +72 -0
- package/dist/utils/errors.d.ts +0 -1
- package/dist/utils/errors.js +0 -1
- package/dist/utils/frontmatter.d.ts +0 -1
- package/dist/utils/frontmatter.js +37 -10
- package/dist/utils/fs.d.ts +0 -1
- package/dist/utils/fs.js +30 -11
- package/dist/utils/help.d.ts +0 -1
- package/dist/utils/help.js +15 -28
- package/dist/utils/history.d.ts +0 -1
- package/dist/utils/history.js +0 -1
- package/dist/utils/http.d.ts +0 -1
- package/dist/utils/http.js +14 -5
- package/dist/utils/install-core.d.ts +48 -0
- package/dist/utils/install-core.js +108 -0
- package/dist/utils/integrity.d.ts +17 -0
- package/dist/utils/integrity.js +84 -0
- package/dist/utils/parallel.d.ts +0 -1
- package/dist/utils/parallel.js +0 -1
- package/dist/utils/project-context.d.ts +19 -0
- package/dist/utils/project-context.js +283 -0
- package/dist/utils/scanner.d.ts +0 -1
- package/dist/utils/scanner.js +138 -10
- package/dist/utils/scoring.d.ts +10 -0
- package/dist/utils/scoring.js +84 -0
- package/dist/utils/ui.d.ts +0 -1
- package/dist/utils/ui.js +11 -4
- package/dist/utils/validate.d.ts +0 -1
- package/dist/utils/validate.js +4 -1
- package/package.json +74 -62
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/audit.d.ts.map +0 -1
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/audit.test.d.ts +0 -2
- package/dist/commands/audit.test.d.ts.map +0 -1
- package/dist/commands/audit.test.js +0 -217
- package/dist/commands/audit.test.js.map +0 -1
- package/dist/commands/clean.d.ts.map +0 -1
- package/dist/commands/clean.js.map +0 -1
- package/dist/commands/compact.d.ts.map +0 -1
- package/dist/commands/compact.js.map +0 -1
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/info.d.ts.map +0 -1
- package/dist/commands/info.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/install.d.ts.map +0 -1
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/list.d.ts.map +0 -1
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/optimize.d.ts.map +0 -1
- package/dist/commands/optimize.js.map +0 -1
- package/dist/commands/providers.d.ts.map +0 -1
- package/dist/commands/providers.js.map +0 -1
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/stats.d.ts.map +0 -1
- package/dist/commands/stats.js.map +0 -1
- package/dist/commands/uninstall.d.ts.map +0 -1
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/validate.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/interactive.d.ts.map +0 -1
- package/dist/interactive.js.map +0 -1
- package/dist/providers/arcana.d.ts.map +0 -1
- package/dist/providers/arcana.js.map +0 -1
- package/dist/providers/base.d.ts.map +0 -1
- package/dist/providers/base.js.map +0 -1
- package/dist/providers/github.d.ts.map +0 -1
- package/dist/providers/github.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/atomic.d.ts.map +0 -1
- package/dist/utils/atomic.js.map +0 -1
- package/dist/utils/atomic.test.d.ts +0 -2
- package/dist/utils/atomic.test.d.ts.map +0 -1
- package/dist/utils/atomic.test.js +0 -31
- package/dist/utils/atomic.test.js.map +0 -1
- package/dist/utils/cache.d.ts.map +0 -1
- package/dist/utils/cache.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/config.test.d.ts +0 -2
- package/dist/utils/config.test.d.ts.map +0 -1
- package/dist/utils/config.test.js +0 -38
- package/dist/utils/config.test.js.map +0 -1
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/frontmatter.d.ts.map +0 -1
- package/dist/utils/frontmatter.js.map +0 -1
- package/dist/utils/frontmatter.test.d.ts +0 -2
- package/dist/utils/frontmatter.test.d.ts.map +0 -1
- package/dist/utils/frontmatter.test.js +0 -152
- package/dist/utils/frontmatter.test.js.map +0 -1
- package/dist/utils/fs.d.ts.map +0 -1
- package/dist/utils/fs.js.map +0 -1
- package/dist/utils/fs.test.d.ts +0 -2
- package/dist/utils/fs.test.d.ts.map +0 -1
- package/dist/utils/fs.test.js +0 -145
- package/dist/utils/fs.test.js.map +0 -1
- package/dist/utils/help.d.ts.map +0 -1
- package/dist/utils/help.js.map +0 -1
- package/dist/utils/help.test.d.ts +0 -2
- package/dist/utils/help.test.d.ts.map +0 -1
- package/dist/utils/help.test.js +0 -66
- package/dist/utils/help.test.js.map +0 -1
- package/dist/utils/history.d.ts.map +0 -1
- package/dist/utils/history.js.map +0 -1
- package/dist/utils/http.d.ts.map +0 -1
- package/dist/utils/http.js.map +0 -1
- package/dist/utils/http.test.d.ts +0 -2
- package/dist/utils/http.test.d.ts.map +0 -1
- package/dist/utils/http.test.js +0 -55
- package/dist/utils/http.test.js.map +0 -1
- package/dist/utils/parallel.d.ts.map +0 -1
- package/dist/utils/parallel.js.map +0 -1
- package/dist/utils/scanner.d.ts.map +0 -1
- package/dist/utils/scanner.js.map +0 -1
- package/dist/utils/ui.d.ts.map +0 -1
- package/dist/utils/ui.js.map +0 -1
- package/dist/utils/ui.test.d.ts +0 -2
- package/dist/utils/ui.test.d.ts.map +0 -1
- package/dist/utils/ui.test.js +0 -31
- package/dist/utils/ui.test.js.map +0 -1
- package/dist/utils/validate.d.ts.map +0 -1
- package/dist/utils/validate.js.map +0 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { atomicWriteSync } from "../utils/atomic.js";
|
|
4
|
+
import { isSkillInstalled, readSkillMeta } from "../utils/fs.js";
|
|
5
|
+
import { validateSlug } from "../utils/validate.js";
|
|
6
|
+
const TEAM_DIR = ".arcana";
|
|
7
|
+
const TEAM_FILE = "team.json";
|
|
8
|
+
function getTeamConfigPath() {
|
|
9
|
+
return join(process.cwd(), TEAM_DIR, TEAM_FILE);
|
|
10
|
+
}
|
|
11
|
+
function readTeamConfig() {
|
|
12
|
+
const configPath = getTeamConfigPath();
|
|
13
|
+
if (!existsSync(configPath))
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function writeTeamConfig(config) {
|
|
24
|
+
const dir = join(process.cwd(), TEAM_DIR);
|
|
25
|
+
if (!existsSync(dir)) {
|
|
26
|
+
mkdirSync(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
atomicWriteSync(getTeamConfigPath(), JSON.stringify(config, null, 2) + "\n", 0o644);
|
|
29
|
+
}
|
|
30
|
+
function output(json, message) {
|
|
31
|
+
if (!json) {
|
|
32
|
+
console.log(message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function teamCommand(action, skill, opts) {
|
|
36
|
+
if (action === "init") {
|
|
37
|
+
return teamInit(opts);
|
|
38
|
+
}
|
|
39
|
+
if (action === "sync") {
|
|
40
|
+
return teamSync(opts);
|
|
41
|
+
}
|
|
42
|
+
if (action === "add") {
|
|
43
|
+
if (!skill) {
|
|
44
|
+
if (opts.json) {
|
|
45
|
+
console.log(JSON.stringify({ error: "Skill name required for add" }));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error("Error: Skill name required. Usage: arcana team add <skill>");
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
return teamAdd(skill, opts);
|
|
53
|
+
}
|
|
54
|
+
if (action === "remove") {
|
|
55
|
+
if (!skill) {
|
|
56
|
+
if (opts.json) {
|
|
57
|
+
console.log(JSON.stringify({ error: "Skill name required for remove" }));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error("Error: Skill name required. Usage: arcana team remove <skill>");
|
|
61
|
+
}
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
return teamRemove(skill, opts);
|
|
65
|
+
}
|
|
66
|
+
if (action === undefined) {
|
|
67
|
+
return teamList(opts);
|
|
68
|
+
}
|
|
69
|
+
if (opts.json) {
|
|
70
|
+
console.log(JSON.stringify({ error: `Unknown action: ${action}` }));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.error(`Error: Unknown action "${action}". Valid actions: init, sync, add, remove`);
|
|
74
|
+
}
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
function teamInit(opts) {
|
|
78
|
+
const configPath = getTeamConfigPath();
|
|
79
|
+
if (existsSync(configPath)) {
|
|
80
|
+
if (opts.json) {
|
|
81
|
+
console.log(JSON.stringify({ error: "Team config already exists", path: configPath }));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.error(`Error: ${configPath} already exists.`);
|
|
85
|
+
}
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const config = {
|
|
89
|
+
skills: [],
|
|
90
|
+
updatedAt: new Date().toISOString(),
|
|
91
|
+
};
|
|
92
|
+
writeTeamConfig(config);
|
|
93
|
+
if (opts.json) {
|
|
94
|
+
console.log(JSON.stringify({ created: configPath }));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log(`Created ${configPath}`);
|
|
98
|
+
console.log("Add skills with: arcana team add <skill-name>");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async function teamSync(opts) {
|
|
102
|
+
const config = readTeamConfig();
|
|
103
|
+
if (!config) {
|
|
104
|
+
if (opts.json) {
|
|
105
|
+
console.log(JSON.stringify({ error: "No team config found. Run: arcana team init" }));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.error("Error: No team config found. Run: arcana team init");
|
|
109
|
+
}
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
if (config.skills.length === 0) {
|
|
113
|
+
if (opts.json) {
|
|
114
|
+
console.log(JSON.stringify({ installed: [], skipped: [], message: "No skills in team config" }));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.log("No skills listed in team config.");
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { installSkill } = await import("../utils/fs.js");
|
|
122
|
+
const installed = [];
|
|
123
|
+
const skipped = [];
|
|
124
|
+
const failed = [];
|
|
125
|
+
for (const entry of config.skills) {
|
|
126
|
+
if (isSkillInstalled(entry.name)) {
|
|
127
|
+
skipped.push(entry.name);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
validateSlug(entry.name, "skill name");
|
|
132
|
+
}
|
|
133
|
+
catch (_err) {
|
|
134
|
+
output(opts.json, `Invalid skill name: ${entry.name}`);
|
|
135
|
+
failed.push(entry.name);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// installSkill requires files, but for sync we re-fetch from provider
|
|
139
|
+
// Lazy import the registry to avoid circular deps at module load
|
|
140
|
+
try {
|
|
141
|
+
const { getProvider } = await import("../registry.js");
|
|
142
|
+
const { loadConfig } = await import("../utils/config.js");
|
|
143
|
+
const { updateLockEntry } = await import("../utils/integrity.js");
|
|
144
|
+
const { writeSkillMeta } = await import("../utils/fs.js");
|
|
145
|
+
const providerName = entry.source ?? loadConfig().defaultProvider;
|
|
146
|
+
const provider = getProvider(providerName);
|
|
147
|
+
const files = await provider.fetch(entry.name);
|
|
148
|
+
installSkill(entry.name, files);
|
|
149
|
+
const remote = await provider.info(entry.name);
|
|
150
|
+
const version = remote?.version ?? entry.version ?? "0.0.0";
|
|
151
|
+
writeSkillMeta(entry.name, {
|
|
152
|
+
version,
|
|
153
|
+
installedAt: new Date().toISOString(),
|
|
154
|
+
source: provider.name,
|
|
155
|
+
description: remote?.description,
|
|
156
|
+
fileCount: files.length,
|
|
157
|
+
sizeBytes: files.reduce((s, f) => s + f.content.length, 0),
|
|
158
|
+
});
|
|
159
|
+
updateLockEntry(entry.name, version, provider.name, files);
|
|
160
|
+
installed.push(entry.name);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
const msg = err instanceof Error ? err.message : "unknown error";
|
|
164
|
+
output(opts.json, `Failed to install ${entry.name}: ${msg}`);
|
|
165
|
+
failed.push(entry.name);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (opts.json) {
|
|
169
|
+
console.log(JSON.stringify({ installed, skipped, failed }));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
console.log(`Sync complete: ${installed.length} installed, ${skipped.length} skipped, ${failed.length} failed`);
|
|
173
|
+
}
|
|
174
|
+
if (failed.length > 0)
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
function teamAdd(skill, opts) {
|
|
178
|
+
try {
|
|
179
|
+
validateSlug(skill, "skill name");
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
if (opts.json) {
|
|
183
|
+
console.log(JSON.stringify({ error: err instanceof Error ? err.message : "Invalid skill name" }));
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.error(err instanceof Error ? err.message : "Invalid skill name");
|
|
187
|
+
}
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
const config = readTeamConfig();
|
|
191
|
+
if (!config) {
|
|
192
|
+
if (opts.json) {
|
|
193
|
+
console.log(JSON.stringify({ error: "No team config found. Run: arcana team init" }));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.error("Error: No team config found. Run: arcana team init");
|
|
197
|
+
}
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
const exists = config.skills.find((s) => s.name === skill);
|
|
201
|
+
if (exists) {
|
|
202
|
+
if (opts.json) {
|
|
203
|
+
console.log(JSON.stringify({ error: `${skill} is already in team config` }));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
console.error(`Error: ${skill} is already in team config.`);
|
|
207
|
+
}
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
const entry = { name: skill };
|
|
211
|
+
// If skill is installed locally, read meta for version/source
|
|
212
|
+
const meta = readSkillMeta(skill);
|
|
213
|
+
if (meta) {
|
|
214
|
+
if (meta.version)
|
|
215
|
+
entry.version = meta.version;
|
|
216
|
+
if (meta.source)
|
|
217
|
+
entry.source = meta.source;
|
|
218
|
+
}
|
|
219
|
+
config.skills.push(entry);
|
|
220
|
+
config.updatedAt = new Date().toISOString();
|
|
221
|
+
writeTeamConfig(config);
|
|
222
|
+
if (opts.json) {
|
|
223
|
+
console.log(JSON.stringify({ added: entry }));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log(`Added ${skill} to team config.`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function teamRemove(skill, opts) {
|
|
230
|
+
const config = readTeamConfig();
|
|
231
|
+
if (!config) {
|
|
232
|
+
if (opts.json) {
|
|
233
|
+
console.log(JSON.stringify({ error: "No team config found. Run: arcana team init" }));
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.error("Error: No team config found. Run: arcana team init");
|
|
237
|
+
}
|
|
238
|
+
process.exit(1);
|
|
239
|
+
}
|
|
240
|
+
const idx = config.skills.findIndex((s) => s.name === skill);
|
|
241
|
+
if (idx < 0) {
|
|
242
|
+
if (opts.json) {
|
|
243
|
+
console.log(JSON.stringify({ error: `${skill} is not in team config` }));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
console.error(`Error: ${skill} is not in team config.`);
|
|
247
|
+
}
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
config.skills.splice(idx, 1);
|
|
251
|
+
config.updatedAt = new Date().toISOString();
|
|
252
|
+
writeTeamConfig(config);
|
|
253
|
+
if (opts.json) {
|
|
254
|
+
console.log(JSON.stringify({ removed: skill }));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
console.log(`Removed ${skill} from team config.`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function teamList(opts) {
|
|
261
|
+
const config = readTeamConfig();
|
|
262
|
+
if (!config) {
|
|
263
|
+
if (opts.json) {
|
|
264
|
+
console.log(JSON.stringify({ error: "No team config found. Run: arcana team init" }));
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
console.error("Error: No team config found. Run: arcana team init");
|
|
268
|
+
}
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
if (opts.json) {
|
|
272
|
+
console.log(JSON.stringify({ skills: config.skills, updatedAt: config.updatedAt }));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (config.skills.length === 0) {
|
|
276
|
+
console.log("No skills in team config. Add one with: arcana team add <skill>");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
console.log(`Team skills (${config.skills.length}):`);
|
|
280
|
+
for (const entry of config.skills) {
|
|
281
|
+
const parts = [entry.name];
|
|
282
|
+
if (entry.version)
|
|
283
|
+
parts.push(`v${entry.version}`);
|
|
284
|
+
if (entry.source)
|
|
285
|
+
parts.push(`(${entry.source})`);
|
|
286
|
+
const installed = isSkillInstalled(entry.name);
|
|
287
|
+
if (installed)
|
|
288
|
+
parts.push("[installed]");
|
|
289
|
+
console.log(` ${parts.join(" ")}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
@@ -125,7 +125,12 @@ function uninstallJson(skillNames) {
|
|
|
125
125
|
validateSlug(skillName, "skill name");
|
|
126
126
|
}
|
|
127
127
|
catch (err) {
|
|
128
|
-
results.push({
|
|
128
|
+
results.push({
|
|
129
|
+
name: skillName,
|
|
130
|
+
success: false,
|
|
131
|
+
error: err instanceof Error ? err.message : "Invalid name",
|
|
132
|
+
symlinksRemoved: 0,
|
|
133
|
+
});
|
|
129
134
|
continue;
|
|
130
135
|
}
|
|
131
136
|
const skillDir = getSkillDir(skillName);
|
|
@@ -139,7 +144,13 @@ function uninstallJson(skillNames) {
|
|
|
139
144
|
rmSync(skillDir, { recursive: true, force: true });
|
|
140
145
|
}
|
|
141
146
|
catch (err) {
|
|
142
|
-
results.push({
|
|
147
|
+
results.push({
|
|
148
|
+
name: skillName,
|
|
149
|
+
success: false,
|
|
150
|
+
version: meta?.version,
|
|
151
|
+
error: err instanceof Error ? err.message : "Failed to remove",
|
|
152
|
+
symlinksRemoved: 0,
|
|
153
|
+
});
|
|
143
154
|
continue;
|
|
144
155
|
}
|
|
145
156
|
const symlinksRemoved = removeSymlinksFor(skillName);
|
|
@@ -147,7 +158,11 @@ function uninstallJson(skillNames) {
|
|
|
147
158
|
}
|
|
148
159
|
if (results.length === 1) {
|
|
149
160
|
const r = results[0];
|
|
150
|
-
const output = {
|
|
161
|
+
const output = {
|
|
162
|
+
uninstalled: r.name,
|
|
163
|
+
success: r.success,
|
|
164
|
+
symlinksRemoved: r.symlinksRemoved,
|
|
165
|
+
};
|
|
151
166
|
if (r.version)
|
|
152
167
|
output.version = r.version;
|
|
153
168
|
if (r.error)
|
|
@@ -160,4 +175,3 @@ function uninstallJson(skillNames) {
|
|
|
160
175
|
if (results.some((r) => !r.success))
|
|
161
176
|
process.exit(1);
|
|
162
177
|
}
|
|
163
|
-
//# sourceMappingURL=uninstall.js.map
|