@oh-my-pi/cli 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -84
- package/dist/cli.js +5025 -1016
- package/dist/commands/config.d.ts +27 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/features.d.ts.map +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/install.d.ts +6 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/link.d.ts +1 -0
- package/dist/commands/link.d.ts.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/outdated.d.ts.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/uninstall.d.ts +3 -0
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/why.d.ts.map +1 -1
- package/dist/conflicts.d.ts +7 -2
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lock.d.ts.map +1 -1
- package/dist/lockfile.d.ts +24 -3
- package/dist/lockfile.d.ts.map +1 -1
- package/dist/manifest.d.ts +12 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/npm.d.ts +11 -0
- package/dist/npm.d.ts.map +1 -1
- package/dist/output.d.ts +51 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/progress.d.ts +78 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/symlinks.d.ts +1 -0
- package/dist/symlinks.d.ts.map +1 -1
- package/package.json +24 -10
- package/.github/icon.png +0 -0
- package/.github/logo.png +0 -0
- package/.github/workflows/ci.yml +0 -32
- package/.github/workflows/publish.yml +0 -42
- package/biome.json +0 -29
- package/bun.lock +0 -109
- package/plugins/exa/README.md +0 -153
- package/plugins/exa/package.json +0 -56
- package/plugins/exa/tools/exa/company.ts +0 -35
- package/plugins/exa/tools/exa/index.ts +0 -66
- package/plugins/exa/tools/exa/linkedin.ts +0 -35
- package/plugins/exa/tools/exa/researcher.ts +0 -40
- package/plugins/exa/tools/exa/runtime.json +0 -4
- package/plugins/exa/tools/exa/search.ts +0 -46
- package/plugins/exa/tools/exa/shared.ts +0 -230
- package/plugins/exa/tools/exa/websets.ts +0 -62
- package/plugins/metal-theme/README.md +0 -13
- package/plugins/metal-theme/omp.json +0 -8
- package/plugins/metal-theme/package.json +0 -19
- package/plugins/metal-theme/themes/metal.json +0 -79
- package/plugins/subagents/README.md +0 -25
- package/plugins/subagents/agents/explore.md +0 -71
- package/plugins/subagents/agents/planner.md +0 -51
- package/plugins/subagents/agents/reviewer.md +0 -53
- package/plugins/subagents/agents/task.md +0 -46
- package/plugins/subagents/commands/architect-plan.md +0 -9
- package/plugins/subagents/commands/implement-with-critic.md +0 -10
- package/plugins/subagents/commands/implement.md +0 -10
- package/plugins/subagents/omp.json +0 -15
- package/plugins/subagents/package.json +0 -26
- package/plugins/subagents/tools/task/index.ts +0 -1019
- package/plugins/user-prompt/README.md +0 -130
- package/plugins/user-prompt/package.json +0 -19
- package/plugins/user-prompt/tools/user-prompt/index.ts +0 -235
- package/scripts/bump-version.sh +0 -52
- package/scripts/publish.sh +0 -35
- package/src/cli.ts +0 -242
- package/src/commands/config.ts +0 -384
- package/src/commands/create.ts +0 -203
- package/src/commands/doctor.ts +0 -305
- package/src/commands/enable.ts +0 -122
- package/src/commands/env.ts +0 -38
- package/src/commands/features.ts +0 -295
- package/src/commands/info.ts +0 -120
- package/src/commands/init.ts +0 -60
- package/src/commands/install.ts +0 -700
- package/src/commands/link.ts +0 -159
- package/src/commands/list.ts +0 -186
- package/src/commands/outdated.ts +0 -87
- package/src/commands/search.ts +0 -77
- package/src/commands/uninstall.ts +0 -124
- package/src/commands/update.ts +0 -170
- package/src/commands/why.ts +0 -136
- package/src/conflicts.ts +0 -116
- package/src/errors.ts +0 -22
- package/src/index.ts +0 -46
- package/src/lock.ts +0 -46
- package/src/lockfile.ts +0 -132
- package/src/manifest.ts +0 -360
- package/src/npm.ts +0 -206
- package/src/paths.ts +0 -137
- package/src/runtime.ts +0 -116
- package/src/symlinks.ts +0 -455
- package/tsconfig.json +0 -28
package/src/commands/features.ts
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import { checkbox } from "@inquirer/prompts";
|
|
2
|
-
import { loadPluginsJson, readPluginPackageJson, savePluginsJson } from "@omp/manifest";
|
|
3
|
-
import { resolveScope } from "@omp/paths";
|
|
4
|
-
import { getDefaultFeatures, getRuntimeConfigPath, readRuntimeConfig, writeRuntimeConfig } from "@omp/symlinks";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
|
|
7
|
-
export interface FeaturesOptions {
|
|
8
|
-
global?: boolean;
|
|
9
|
-
local?: boolean;
|
|
10
|
-
json?: boolean;
|
|
11
|
-
enable?: string[];
|
|
12
|
-
disable?: string[];
|
|
13
|
-
set?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Interactive feature selection for a plugin
|
|
18
|
-
* omp features @oh-my-pi/exa
|
|
19
|
-
*/
|
|
20
|
-
export async function interactiveFeatures(name: string, options: FeaturesOptions = {}): Promise<void> {
|
|
21
|
-
const isGlobal = resolveScope(options);
|
|
22
|
-
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
23
|
-
|
|
24
|
-
// Check if plugin exists
|
|
25
|
-
if (!pluginsJson.plugins[name]) {
|
|
26
|
-
console.log(chalk.yellow(`Plugin "${name}" is not installed.`));
|
|
27
|
-
process.exitCode = 1;
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
32
|
-
if (!pkgJson) {
|
|
33
|
-
console.log(chalk.red(`Could not read package.json for ${name}`));
|
|
34
|
-
process.exitCode = 1;
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const features = pkgJson.omp?.features;
|
|
39
|
-
if (!features || Object.keys(features).length === 0) {
|
|
40
|
-
console.log(chalk.yellow(`Plugin "${name}" has no configurable features.`));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Get runtime config path and current enabled features
|
|
45
|
-
const runtimePath = getRuntimeConfigPath(pkgJson, isGlobal);
|
|
46
|
-
if (!runtimePath) {
|
|
47
|
-
console.log(chalk.yellow(`Plugin "${name}" does not have a runtime.json config file.`));
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const runtimeConfig = readRuntimeConfig(runtimePath);
|
|
52
|
-
const enabledFeatures = runtimeConfig.features ?? getDefaultFeatures(features);
|
|
53
|
-
|
|
54
|
-
// JSON output mode - just list
|
|
55
|
-
if (options.json) {
|
|
56
|
-
console.log(
|
|
57
|
-
JSON.stringify(
|
|
58
|
-
{
|
|
59
|
-
plugin: name,
|
|
60
|
-
features: Object.entries(features).map(([fname, fdef]) => ({
|
|
61
|
-
name: fname,
|
|
62
|
-
enabled: enabledFeatures.includes(fname),
|
|
63
|
-
default: fdef.default !== false,
|
|
64
|
-
description: fdef.description,
|
|
65
|
-
variables: fdef.variables ? Object.keys(fdef.variables) : [],
|
|
66
|
-
})),
|
|
67
|
-
},
|
|
68
|
-
null,
|
|
69
|
-
2,
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Non-interactive mode - just list
|
|
76
|
-
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
77
|
-
listFeaturesNonInteractive(name, features, enabledFeatures);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Interactive mode - checkbox prompt
|
|
82
|
-
console.log(chalk.bold(`\nConfigure features for ${name}:\n`));
|
|
83
|
-
|
|
84
|
-
const choices = Object.entries(features).map(([fname, fdef]) => {
|
|
85
|
-
const optIn = fdef.default === false ? chalk.dim(" (opt-in)") : "";
|
|
86
|
-
const desc = fdef.description ? chalk.dim(` - ${fdef.description}`) : "";
|
|
87
|
-
return {
|
|
88
|
-
name: `${fname}${optIn}${desc}`,
|
|
89
|
-
value: fname,
|
|
90
|
-
checked: enabledFeatures.includes(fname),
|
|
91
|
-
};
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
const selected = await checkbox({
|
|
96
|
-
message: "Select features to enable:",
|
|
97
|
-
choices,
|
|
98
|
-
pageSize: 15,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Apply changes
|
|
102
|
-
await applyFeatureChanges(name, runtimePath, features, enabledFeatures, selected);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
// User cancelled (Ctrl+C)
|
|
105
|
-
console.log(chalk.dim("\nCancelled."));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Non-interactive feature listing
|
|
111
|
-
*/
|
|
112
|
-
function listFeaturesNonInteractive(
|
|
113
|
-
name: string,
|
|
114
|
-
features: Record<string, { description?: string; default?: boolean; variables?: Record<string, unknown> }>,
|
|
115
|
-
enabledFeatures: string[],
|
|
116
|
-
): void {
|
|
117
|
-
console.log(chalk.bold(`\nFeatures for ${name}:\n`));
|
|
118
|
-
|
|
119
|
-
for (const [fname, fdef] of Object.entries(features)) {
|
|
120
|
-
const isEnabled = enabledFeatures.includes(fname);
|
|
121
|
-
const icon = isEnabled ? chalk.green("✓") : chalk.gray("○");
|
|
122
|
-
const defaultStr = fdef.default === false ? chalk.dim(" (opt-in)") : "";
|
|
123
|
-
|
|
124
|
-
console.log(`${icon} ${chalk.bold(fname)}${defaultStr}`);
|
|
125
|
-
if (fdef.description) {
|
|
126
|
-
console.log(chalk.dim(` ${fdef.description}`));
|
|
127
|
-
}
|
|
128
|
-
if (fdef.variables && Object.keys(fdef.variables).length > 0) {
|
|
129
|
-
console.log(chalk.dim(` Variables: ${Object.keys(fdef.variables).join(", ")}`));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
console.log();
|
|
134
|
-
console.log(chalk.dim(`Configure with: omp features ${name} --enable <feature> --disable <feature>`));
|
|
135
|
-
console.log(chalk.dim(`Or set exactly: omp features ${name} --set feature1,feature2`));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Apply feature changes - update both plugins.json (for config/env) and runtime.json (for runtime)
|
|
140
|
-
*/
|
|
141
|
-
async function applyFeatureChanges(
|
|
142
|
-
name: string,
|
|
143
|
-
runtimePath: string,
|
|
144
|
-
features: Record<string, { description?: string; default?: boolean; variables?: Record<string, unknown> }>,
|
|
145
|
-
currentlyEnabled: string[],
|
|
146
|
-
newEnabled: string[],
|
|
147
|
-
isGlobal: boolean,
|
|
148
|
-
): Promise<void> {
|
|
149
|
-
// Compute what changed
|
|
150
|
-
const toDisable = currentlyEnabled.filter((f) => !newEnabled.includes(f));
|
|
151
|
-
const toEnable = newEnabled.filter((f) => !currentlyEnabled.includes(f));
|
|
152
|
-
|
|
153
|
-
if (toDisable.length === 0 && toEnable.length === 0) {
|
|
154
|
-
console.log(chalk.yellow("\nNo changes to feature configuration."));
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
console.log(chalk.blue(`\nApplying changes...`));
|
|
159
|
-
|
|
160
|
-
if (toDisable.length > 0) {
|
|
161
|
-
console.log(chalk.dim(` Disabling: ${toDisable.join(", ")}`));
|
|
162
|
-
}
|
|
163
|
-
if (toEnable.length > 0) {
|
|
164
|
-
console.log(chalk.dim(` Enabling: ${toEnable.join(", ")}`));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Update plugins.json (source of truth for config/env commands)
|
|
168
|
-
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
169
|
-
if (!pluginsJson.config) pluginsJson.config = {};
|
|
170
|
-
if (!pluginsJson.config[name]) pluginsJson.config[name] = {};
|
|
171
|
-
pluginsJson.config[name].features = newEnabled;
|
|
172
|
-
await savePluginsJson(pluginsJson, isGlobal);
|
|
173
|
-
|
|
174
|
-
// Also write to runtime.json (for runtime feature detection)
|
|
175
|
-
await writeRuntimeConfig(runtimePath, { features: newEnabled });
|
|
176
|
-
|
|
177
|
-
console.log(chalk.green(`\n✓ Features updated`));
|
|
178
|
-
if (newEnabled.length > 0) {
|
|
179
|
-
console.log(chalk.dim(` Enabled: ${newEnabled.join(", ")}`));
|
|
180
|
-
} else {
|
|
181
|
-
console.log(chalk.dim(` Enabled: none`));
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Configure features for an installed plugin via CLI flags
|
|
187
|
-
* omp features @oh-my-pi/exa --enable websets --disable search
|
|
188
|
-
* omp features @oh-my-pi/exa --set search,websets
|
|
189
|
-
*/
|
|
190
|
-
export async function configureFeatures(name: string, options: FeaturesOptions = {}): Promise<void> {
|
|
191
|
-
const isGlobal = resolveScope(options);
|
|
192
|
-
const pluginsJson = await loadPluginsJson(isGlobal);
|
|
193
|
-
|
|
194
|
-
// Check if plugin exists
|
|
195
|
-
if (!pluginsJson.plugins[name]) {
|
|
196
|
-
console.log(chalk.yellow(`Plugin "${name}" is not installed.`));
|
|
197
|
-
process.exitCode = 1;
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const pkgJson = await readPluginPackageJson(name, isGlobal);
|
|
202
|
-
if (!pkgJson) {
|
|
203
|
-
console.log(chalk.red(`Could not read package.json for ${name}`));
|
|
204
|
-
process.exitCode = 1;
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const features = pkgJson.omp?.features;
|
|
209
|
-
if (!features || Object.keys(features).length === 0) {
|
|
210
|
-
console.log(chalk.yellow(`Plugin "${name}" has no configurable features.`));
|
|
211
|
-
process.exitCode = 1;
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const allFeatureNames = Object.keys(features);
|
|
216
|
-
|
|
217
|
-
// Get runtime config
|
|
218
|
-
const runtimePath = getRuntimeConfigPath(pkgJson, isGlobal);
|
|
219
|
-
if (!runtimePath) {
|
|
220
|
-
console.log(chalk.yellow(`Plugin "${name}" does not have a runtime.json config file.`));
|
|
221
|
-
process.exitCode = 1;
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const runtimeConfig = readRuntimeConfig(runtimePath);
|
|
226
|
-
const currentlyEnabled = runtimeConfig.features ?? getDefaultFeatures(features);
|
|
227
|
-
|
|
228
|
-
let newEnabled: string[];
|
|
229
|
-
|
|
230
|
-
// Handle --set (explicit list)
|
|
231
|
-
if (options.set !== undefined) {
|
|
232
|
-
if (options.set === "*") {
|
|
233
|
-
newEnabled = allFeatureNames;
|
|
234
|
-
} else if (options.set === "") {
|
|
235
|
-
newEnabled = [];
|
|
236
|
-
} else {
|
|
237
|
-
newEnabled = options.set.split(",").map((f) => f.trim()).filter(Boolean);
|
|
238
|
-
// Validate
|
|
239
|
-
for (const f of newEnabled) {
|
|
240
|
-
if (!features[f]) {
|
|
241
|
-
console.log(chalk.red(`Unknown feature "${f}". Available: ${allFeatureNames.join(", ")}`));
|
|
242
|
-
process.exitCode = 1;
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
} else {
|
|
248
|
-
// Handle --enable and --disable
|
|
249
|
-
newEnabled = [...currentlyEnabled];
|
|
250
|
-
|
|
251
|
-
if (options.enable) {
|
|
252
|
-
for (const f of options.enable) {
|
|
253
|
-
if (!features[f]) {
|
|
254
|
-
console.log(chalk.red(`Unknown feature "${f}". Available: ${allFeatureNames.join(", ")}`));
|
|
255
|
-
process.exitCode = 1;
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
if (!newEnabled.includes(f)) {
|
|
259
|
-
newEnabled.push(f);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (options.disable) {
|
|
265
|
-
for (const f of options.disable) {
|
|
266
|
-
if (!features[f]) {
|
|
267
|
-
console.log(chalk.red(`Unknown feature "${f}". Available: ${allFeatureNames.join(", ")}`));
|
|
268
|
-
process.exitCode = 1;
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
newEnabled = newEnabled.filter((e) => e !== f);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
await applyFeatureChanges(name, runtimePath, features, currentlyEnabled, newEnabled);
|
|
277
|
-
|
|
278
|
-
if (options.json) {
|
|
279
|
-
console.log(JSON.stringify({ plugin: name, enabled: newEnabled }, null, 2));
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Main features command handler
|
|
285
|
-
* Routes to interactive or configure based on options
|
|
286
|
-
*/
|
|
287
|
-
export async function featuresCommand(name: string, options: FeaturesOptions = {}): Promise<void> {
|
|
288
|
-
// If any modification options are passed, configure via CLI
|
|
289
|
-
if (options.enable || options.disable || options.set !== undefined) {
|
|
290
|
-
await configureFeatures(name, options);
|
|
291
|
-
} else {
|
|
292
|
-
// Otherwise, show interactive UI (or list in non-TTY mode)
|
|
293
|
-
await interactiveFeatures(name, options);
|
|
294
|
-
}
|
|
295
|
-
}
|
package/src/commands/info.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { npmInfo } from "@omp/npm";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
|
|
4
|
-
export interface InfoOptions {
|
|
5
|
-
json?: boolean;
|
|
6
|
-
versions?: boolean;
|
|
7
|
-
allVersions?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Show detailed info about a package before install
|
|
12
|
-
*/
|
|
13
|
-
export async function showInfo(packageName: string, options: InfoOptions = {}): Promise<void> {
|
|
14
|
-
console.log(chalk.blue(`Fetching info for ${packageName}...`));
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const info = await npmInfo(packageName);
|
|
18
|
-
|
|
19
|
-
if (!info) {
|
|
20
|
-
console.log(chalk.red(`Package not found: ${packageName}`));
|
|
21
|
-
process.exitCode = 1;
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (options.json) {
|
|
26
|
-
console.log(JSON.stringify(info, null, 2));
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log();
|
|
31
|
-
console.log(chalk.bold.green(info.name) + chalk.dim(` v${info.version}`));
|
|
32
|
-
console.log();
|
|
33
|
-
|
|
34
|
-
if (info.description) {
|
|
35
|
-
console.log(chalk.white(info.description));
|
|
36
|
-
console.log();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Author
|
|
40
|
-
if (info.author) {
|
|
41
|
-
const authorStr =
|
|
42
|
-
typeof info.author === "string"
|
|
43
|
-
? info.author
|
|
44
|
-
: `${info.author.name}${info.author.email ? ` <${info.author.email}>` : ""}`;
|
|
45
|
-
console.log(chalk.dim("author: ") + authorStr);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Homepage
|
|
49
|
-
if (info.homepage) {
|
|
50
|
-
console.log(chalk.dim("homepage: ") + info.homepage);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Repository
|
|
54
|
-
if (info.repository) {
|
|
55
|
-
const repoUrl = typeof info.repository === "string" ? info.repository : info.repository.url;
|
|
56
|
-
console.log(chalk.dim("repo: ") + repoUrl);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Keywords
|
|
60
|
-
if (info.keywords?.length) {
|
|
61
|
-
console.log(chalk.dim("keywords: ") + info.keywords.join(", "));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Dependencies
|
|
65
|
-
if (info.dependencies && Object.keys(info.dependencies).length > 0) {
|
|
66
|
-
console.log(chalk.dim("\ndependencies:"));
|
|
67
|
-
for (const [depName, depVersion] of Object.entries(info.dependencies)) {
|
|
68
|
-
console.log(chalk.dim(` ${depName}: ${depVersion}`));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Is it an omp plugin?
|
|
73
|
-
const isOmpPlugin = info.keywords?.includes("omp-plugin");
|
|
74
|
-
if (isOmpPlugin) {
|
|
75
|
-
console.log(chalk.green("\n✓ This is an omp plugin"));
|
|
76
|
-
} else {
|
|
77
|
-
console.log(chalk.yellow("\n⚠ This package does not have the omp-plugin keyword"));
|
|
78
|
-
console.log(chalk.dim(" It may work, but might not have omp.install configuration"));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Show what files will be installed
|
|
82
|
-
if (info.omp?.install?.length) {
|
|
83
|
-
console.log(chalk.dim("\nFiles to install:"));
|
|
84
|
-
for (const entry of info.omp.install) {
|
|
85
|
-
console.log(chalk.dim(` ${entry.src} → ${entry.dest}`));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Versions
|
|
90
|
-
if (options.versions || options.allVersions) {
|
|
91
|
-
if (info["dist-tags"]) {
|
|
92
|
-
console.log(chalk.dim("\ndist-tags:"));
|
|
93
|
-
for (const [tag, version] of Object.entries(info["dist-tags"])) {
|
|
94
|
-
console.log(chalk.dim(` ${tag}: `) + version);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (info.versions?.length) {
|
|
99
|
-
console.log(chalk.dim("\nall versions:"));
|
|
100
|
-
if (options.allVersions) {
|
|
101
|
-
// Show all versions
|
|
102
|
-
console.log(chalk.dim(` ${info.versions.join(", ")}`));
|
|
103
|
-
} else {
|
|
104
|
-
// Show last 10
|
|
105
|
-
const versionsToShow = info.versions.slice(-10);
|
|
106
|
-
console.log(chalk.dim(` ${versionsToShow.join(", ")}`));
|
|
107
|
-
if (info.versions.length > 10) {
|
|
108
|
-
console.log(chalk.dim(` ... and ${info.versions.length - 10} more (use --all-versions to see all)`));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
console.log();
|
|
115
|
-
console.log(chalk.dim(`Install with: omp install ${packageName}`));
|
|
116
|
-
} catch (err) {
|
|
117
|
-
console.log(chalk.red(`Error fetching info: ${(err as Error).message}`));
|
|
118
|
-
process.exitCode = 1;
|
|
119
|
-
}
|
|
120
|
-
}
|
package/src/commands/init.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
-
import { PROJECT_PI_DIR, PROJECT_PLUGINS_JSON } from "@omp/paths";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Format permission-related errors with actionable guidance
|
|
8
|
-
*/
|
|
9
|
-
function formatPermissionError(err: NodeJS.ErrnoException, path: string): string {
|
|
10
|
-
if (err.code === "EACCES" || err.code === "EPERM") {
|
|
11
|
-
return `Permission denied: Cannot write to ${path}. Check directory permissions or run with appropriate privileges.`;
|
|
12
|
-
}
|
|
13
|
-
return err.message;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface InitOptions {
|
|
17
|
-
force?: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Initialize .pi/plugins.json in current project
|
|
22
|
-
*/
|
|
23
|
-
export async function initProject(options: InitOptions = {}): Promise<void> {
|
|
24
|
-
// Check if already exists
|
|
25
|
-
if (existsSync(PROJECT_PLUGINS_JSON) && !options.force) {
|
|
26
|
-
console.log(chalk.yellow(`${PROJECT_PLUGINS_JSON} already exists.`));
|
|
27
|
-
console.log(chalk.dim("Use --force to overwrite"));
|
|
28
|
-
process.exitCode = 1;
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
// Create .pi directory
|
|
34
|
-
await mkdir(PROJECT_PI_DIR, { recursive: true });
|
|
35
|
-
|
|
36
|
-
// Create plugins.json
|
|
37
|
-
const pluginsJson = {
|
|
38
|
-
plugins: {},
|
|
39
|
-
disabled: [],
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
await writeFile(PROJECT_PLUGINS_JSON, JSON.stringify(pluginsJson, null, 2));
|
|
43
|
-
|
|
44
|
-
console.log(chalk.green(`✓ Created ${PROJECT_PLUGINS_JSON}`));
|
|
45
|
-
console.log();
|
|
46
|
-
console.log(chalk.dim("Next steps:"));
|
|
47
|
-
console.log(chalk.dim(" 1. Add plugins: omp install <package> --save"));
|
|
48
|
-
console.log(chalk.dim(" 2. Or edit plugins.json directly"));
|
|
49
|
-
console.log(chalk.dim(" 3. Run: omp install (to install all)"));
|
|
50
|
-
} catch (err) {
|
|
51
|
-
const error = err as NodeJS.ErrnoException;
|
|
52
|
-
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
53
|
-
console.log(chalk.red(formatPermissionError(error, PROJECT_PI_DIR)));
|
|
54
|
-
console.log(chalk.dim(" Check directory permissions or run with appropriate privileges."));
|
|
55
|
-
} else {
|
|
56
|
-
console.log(chalk.red(`Error initializing project: ${error.message}`));
|
|
57
|
-
}
|
|
58
|
-
process.exitCode = 1;
|
|
59
|
-
}
|
|
60
|
-
}
|