opencode-rules-md 0.6.6 → 0.8.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 +13 -3
- package/dist/src/active-rules-state.js +1 -1
- package/dist/src/active-rules-state.js.map +1 -1
- package/dist/src/rule-discovery.d.ts +1 -1
- package/dist/src/rule-discovery.d.ts.map +1 -1
- package/dist/src/rule-discovery.js +2 -2
- package/dist/src/rule-discovery.js.map +1 -1
- package/dist/tui/data/rules.d.ts +1 -1
- package/dist/tui/data/rules.d.ts.map +1 -1
- package/dist/tui/data/rules.js +2 -2
- package/dist/tui/data/rules.js.map +1 -1
- package/dist/tui/index.js +1 -1
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/slots/sidebar-content.js +1 -1
- package/dist/tui/slots/sidebar-content.js.map +1 -1
- package/package.json +24 -11
- package/src/active-rules-state.ts +1 -1
- package/src/rule-discovery.ts +2 -2
- package/tui/data/rules.ts +3 -3
- package/tui/index.tsx +1 -1
- package/tui/slots/sidebar-content.tsx +1 -1
- package/dist/cli.mjs +0 -454
- package/dist/src/cli/config.d.ts +0 -74
- package/dist/src/cli/config.d.ts.map +0 -1
- package/dist/src/cli/config.js +0 -292
- package/dist/src/cli/config.js.map +0 -1
- package/dist/src/cli/install.d.ts +0 -33
- package/dist/src/cli/install.d.ts.map +0 -1
- package/dist/src/cli/install.js +0 -99
- package/dist/src/cli/install.js.map +0 -1
- package/dist/src/cli/main.d.ts +0 -19
- package/dist/src/cli/main.d.ts.map +0 -1
- package/dist/src/cli/main.js +0 -149
- package/dist/src/cli/main.js.map +0 -1
- package/dist/src/cli/real-fs.d.ts +0 -26
- package/dist/src/cli/real-fs.d.ts.map +0 -1
- package/dist/src/cli/real-fs.js +0 -42
- package/dist/src/cli/real-fs.js.map +0 -1
- package/dist/src/cli/status.d.ts +0 -34
- package/dist/src/cli/status.d.ts.map +0 -1
- package/dist/src/cli/status.js +0 -67
- package/dist/src/cli/status.js.map +0 -1
- package/src/cli/config.ts +0 -364
- package/src/cli/install.ts +0 -171
- package/src/cli/main.ts +0 -178
- package/src/cli/real-fs.ts +0 -65
- package/src/cli/status.ts +0 -99
package/src/cli/main.ts
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CLI entrypoint for opencode-rules-md installer.
|
|
4
|
-
*
|
|
5
|
-
* Supports:
|
|
6
|
-
* install — add opencode-rules-md to the global opencode + tui configs
|
|
7
|
-
* status — report whether opencode-rules-md is installed
|
|
8
|
-
*
|
|
9
|
-
* Flags:
|
|
10
|
-
* --version <v> — specify a plugin version to install
|
|
11
|
-
* --latest — install the latest version (default)
|
|
12
|
-
* --dry-run — show what would be written, without changing files
|
|
13
|
-
* --yes — skip confirmation prompts (future use)
|
|
14
|
-
* -h, --help — show this help text
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { parseArgs } from 'node:util';
|
|
18
|
-
import { pathToFileURL } from 'node:url';
|
|
19
|
-
import { realpathSync } from 'node:fs';
|
|
20
|
-
import { runInstall } from './install.js';
|
|
21
|
-
import { runStatus } from './status.js';
|
|
22
|
-
import type { CliFs } from './real-fs.js';
|
|
23
|
-
import { realFs } from './real-fs.js';
|
|
24
|
-
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Help text
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
const HELP_TEXT = `opencode-rules-md CLI
|
|
30
|
-
|
|
31
|
-
Usage: opencode-rules-md <command> [options]
|
|
32
|
-
|
|
33
|
-
Commands:
|
|
34
|
-
install Add opencode-rules-md to the global opencode + tui configs
|
|
35
|
-
status Report whether opencode-rules-md is installed
|
|
36
|
-
|
|
37
|
-
Options:
|
|
38
|
-
--version <v> Specify a plugin version to install
|
|
39
|
-
--latest Install the latest version (default)
|
|
40
|
-
--dry-run Show what would be written, without changing files
|
|
41
|
-
--yes Skip confirmation prompts (future use)
|
|
42
|
-
-h, --help Show this help text
|
|
43
|
-
`.trim();
|
|
44
|
-
|
|
45
|
-
const USAGE_ERROR_TEXT = `Error: unknown command. Run 'opencode-rules-md --help' for usage.`.trim();
|
|
46
|
-
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
// Argument parsing
|
|
49
|
-
// ---------------------------------------------------------------------------
|
|
50
|
-
|
|
51
|
-
interface CliOptions {
|
|
52
|
-
version?: string;
|
|
53
|
-
latest?: boolean;
|
|
54
|
-
dryRun?: boolean;
|
|
55
|
-
yes?: boolean;
|
|
56
|
-
help?: boolean;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function parseCliArgs(argv: string[]): { command: string | null; options: CliOptions; unknownFlags: string[] } {
|
|
60
|
-
const { positionals, values } = parseArgs({
|
|
61
|
-
args: argv,
|
|
62
|
-
allowPositionals: true,
|
|
63
|
-
options: {
|
|
64
|
-
version: { type: 'string' },
|
|
65
|
-
latest: { type: 'boolean' },
|
|
66
|
-
'dry-run': { type: 'boolean' },
|
|
67
|
-
yes: { type: 'boolean' },
|
|
68
|
-
h: { type: 'boolean' },
|
|
69
|
-
help: { type: 'boolean' },
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Extract command (first positional)
|
|
74
|
-
const command = positionals[0] ?? null;
|
|
75
|
-
|
|
76
|
-
// Extract options from parsed values
|
|
77
|
-
// Note: -h sets key 'h', --help sets key 'help'
|
|
78
|
-
const options: CliOptions = {
|
|
79
|
-
...(values.version !== undefined && { version: values.version as string }),
|
|
80
|
-
...(values.latest && { latest: true }),
|
|
81
|
-
...(values['dry-run'] && { dryRun: true }),
|
|
82
|
-
...(values.yes && { yes: true }),
|
|
83
|
-
...((values.help || values.h) && { help: true }),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const unknownFlags: string[] = [];
|
|
87
|
-
|
|
88
|
-
return { command, options, unknownFlags };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
// Dispatcher
|
|
93
|
-
// ---------------------------------------------------------------------------
|
|
94
|
-
|
|
95
|
-
export type ExitCode = 0 | 1 | 2;
|
|
96
|
-
|
|
97
|
-
export async function runMain(argv: string[], fs: CliFs = realFs): Promise<ExitCode> {
|
|
98
|
-
try {
|
|
99
|
-
const { command, options, unknownFlags } = parseCliArgs(argv);
|
|
100
|
-
|
|
101
|
-
// Handle help flag at top level (before command dispatch)
|
|
102
|
-
if (options.help) {
|
|
103
|
-
console.log(HELP_TEXT);
|
|
104
|
-
return 0;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Handle unknown flags
|
|
108
|
-
if (unknownFlags.length > 0) {
|
|
109
|
-
console.error(`Error: unknown option(s): ${unknownFlags.join(', ')}`);
|
|
110
|
-
console.error(USAGE_ERROR_TEXT);
|
|
111
|
-
return 2;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// No command given
|
|
115
|
-
if (!command) {
|
|
116
|
-
console.error(USAGE_ERROR_TEXT);
|
|
117
|
-
return 2;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
switch (command) {
|
|
121
|
-
case 'install': {
|
|
122
|
-
const installOpts: { version?: string; dryRun?: boolean } = {};
|
|
123
|
-
if (options.version !== undefined) installOpts.version = options.version;
|
|
124
|
-
if (options.dryRun) installOpts.dryRun = true;
|
|
125
|
-
runInstall(installOpts, fs);
|
|
126
|
-
return 0;
|
|
127
|
-
}
|
|
128
|
-
case 'status': {
|
|
129
|
-
const statusResult = runStatus(fs);
|
|
130
|
-
if (statusResult.installed) {
|
|
131
|
-
const spec = statusResult.serverSpecifier ?? statusResult.tuiSpecifier;
|
|
132
|
-
console.log(`opencode-rules-md is installed (${spec})`);
|
|
133
|
-
} else {
|
|
134
|
-
console.log('opencode-rules-md is not installed');
|
|
135
|
-
}
|
|
136
|
-
return 0;
|
|
137
|
-
}
|
|
138
|
-
default: {
|
|
139
|
-
console.error(`Error: unknown command '${command}'`);
|
|
140
|
-
console.error(USAGE_ERROR_TEXT);
|
|
141
|
-
return 2;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
} catch (err) {
|
|
145
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
146
|
-
console.error(`Error: ${message}`);
|
|
147
|
-
return 1;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
|
-
// Entry point
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Determine whether the current module is being executed as the main entry.
|
|
157
|
-
* Uses realpathSync + pathToFileURL so symlinked invocations (e.g. npx)
|
|
158
|
-
* are matched correctly.
|
|
159
|
-
*/
|
|
160
|
-
function isInvokedAsMain(): boolean {
|
|
161
|
-
if (!process.argv[1]) return false;
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
const realArgv = pathToFileURL(realpathSync(process.argv[1])).href;
|
|
165
|
-
return import.meta.url === realArgv;
|
|
166
|
-
} catch {
|
|
167
|
-
try {
|
|
168
|
-
return import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
169
|
-
} catch {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Only run if executed directly (not imported as a module)
|
|
176
|
-
if (isInvokedAsMain()) {
|
|
177
|
-
void runMain(process.argv.slice(2)).then(code => process.exit(code));
|
|
178
|
-
}
|
package/src/cli/real-fs.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin synchronous adapter over node:fs that implements the CliFs interface.
|
|
3
|
-
* All production CLI disk I/O flows through this module — no direct node:fs
|
|
4
|
-
* calls outside this file.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as fs from 'node:fs';
|
|
8
|
-
import * as nodePath from 'node:path';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Synchronous filesystem interface used by the CLI.
|
|
12
|
-
* Tests supply an in-memory implementation; production uses this adapter.
|
|
13
|
-
*/
|
|
14
|
-
export interface CliFs {
|
|
15
|
-
readFileSync(path: string): string;
|
|
16
|
-
writeFileSync(path: string, content: string, encoding?: string): void;
|
|
17
|
-
renameSync(from: string, to: string): void;
|
|
18
|
-
copyFileSync(from: string, to: string): void;
|
|
19
|
-
unlinkSync(path: string): void;
|
|
20
|
-
mkdirSync(path: string, opts?: { recursive?: boolean }): void;
|
|
21
|
-
readdirSync(path: string): string[];
|
|
22
|
-
existsSync(path: string): boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Production CliFs implementation backed by node:fs (synchronous).
|
|
27
|
-
*/
|
|
28
|
-
export const realFs: CliFs = {
|
|
29
|
-
readFileSync(filePath: string): string {
|
|
30
|
-
return fs.readFileSync(filePath, 'utf-8');
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
writeFileSync(filePath: string, content: string, _encoding?: string): void {
|
|
34
|
-
// Ensure parent directory exists before writing
|
|
35
|
-
const dir = nodePath.dirname(filePath);
|
|
36
|
-
if (!fs.existsSync(dir)) {
|
|
37
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
38
|
-
}
|
|
39
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
renameSync(from: string, to: string): void {
|
|
43
|
-
fs.renameSync(from, to);
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
copyFileSync(from: string, to: string): void {
|
|
47
|
-
fs.copyFileSync(from, to);
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
unlinkSync(filePath: string): void {
|
|
51
|
-
fs.unlinkSync(filePath);
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
mkdirSync(filePath: string, opts?: { recursive?: boolean }): void {
|
|
55
|
-
fs.mkdirSync(filePath, opts);
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
readdirSync(filePath: string): string[] {
|
|
59
|
-
return fs.readdirSync(filePath);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
existsSync(filePath: string): boolean {
|
|
63
|
-
return fs.existsSync(filePath);
|
|
64
|
-
},
|
|
65
|
-
};
|
package/src/cli/status.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* status command: read-only probe that reports install state.
|
|
3
|
-
*
|
|
4
|
-
* Reports install state across BOTH the server and TUI configs:
|
|
5
|
-
* - installed: yes/no (true only when present in both configs)
|
|
6
|
-
* - serverSpecifier: the registered entry in opencode.json (or undefined)
|
|
7
|
-
* - tuiSpecifier: the registered entry in tui.json (or undefined)
|
|
8
|
-
* - serverPath: path to the server config
|
|
9
|
-
* - tuiPath: path to the TUI config
|
|
10
|
-
* - version: bundled CLI version from package.json
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { loadGlobalConfig, TUI_CONFIG_FILENAME } from './config.js';
|
|
14
|
-
import type { CliFs } from './real-fs.js';
|
|
15
|
-
import { realFs } from './real-fs.js';
|
|
16
|
-
import * as fs from 'node:fs';
|
|
17
|
-
import * as path from 'node:path';
|
|
18
|
-
|
|
19
|
-
// ---------------------------------------------------------------------------
|
|
20
|
-
// Result types
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
export interface StatusResult {
|
|
24
|
-
/** True only when the plugin is registered in both server and TUI configs. */
|
|
25
|
-
installed: boolean;
|
|
26
|
-
/** Server config path. */
|
|
27
|
-
serverPath: string;
|
|
28
|
-
/** TUI config path. */
|
|
29
|
-
tuiPath: string;
|
|
30
|
-
/** Registered specifier in the server config, if any. */
|
|
31
|
-
serverSpecifier?: string;
|
|
32
|
-
/** Registered specifier in the TUI config, if any. */
|
|
33
|
-
tuiSpecifier?: string;
|
|
34
|
-
/** Whether the server config existed on disk before the probe. */
|
|
35
|
-
serverExisted: boolean;
|
|
36
|
-
/** Whether the TUI config existed on disk before the probe. */
|
|
37
|
-
tuiExisted: boolean;
|
|
38
|
-
/** Bundled CLI version from package.json. */
|
|
39
|
-
version: string;
|
|
40
|
-
/** First parse error encountered, if any (server takes priority). */
|
|
41
|
-
parseError?: Error;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Run status
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
export function runStatus(cliFs: CliFs = realFs): StatusResult {
|
|
49
|
-
const serverLoad = loadGlobalConfig(cliFs);
|
|
50
|
-
const tuiLoad = loadGlobalConfig(cliFs, { filename: TUI_CONFIG_FILENAME });
|
|
51
|
-
|
|
52
|
-
const serverSpecifier = findSpecifier(serverLoad);
|
|
53
|
-
const tuiSpecifier = findSpecifier(tuiLoad);
|
|
54
|
-
|
|
55
|
-
const installed = serverSpecifier !== undefined && tuiSpecifier !== undefined;
|
|
56
|
-
|
|
57
|
-
const result: StatusResult = {
|
|
58
|
-
installed,
|
|
59
|
-
serverPath: serverLoad.path,
|
|
60
|
-
tuiPath: tuiLoad.path,
|
|
61
|
-
serverExisted: serverLoad.existed,
|
|
62
|
-
tuiExisted: tuiLoad.existed,
|
|
63
|
-
version: getVersion(),
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
if (serverSpecifier) result.serverSpecifier = serverSpecifier;
|
|
67
|
-
if (tuiSpecifier) result.tuiSpecifier = tuiSpecifier;
|
|
68
|
-
|
|
69
|
-
// Surface the first parse error so callers can warn the user
|
|
70
|
-
const parseError = serverLoad.parseError ?? tuiLoad.parseError;
|
|
71
|
-
if (parseError) result.parseError = parseError;
|
|
72
|
-
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// ---------------------------------------------------------------------------
|
|
77
|
-
// Internal helpers
|
|
78
|
-
// ---------------------------------------------------------------------------
|
|
79
|
-
|
|
80
|
-
function findSpecifier(load: ReturnType<typeof loadGlobalConfig>): string | undefined {
|
|
81
|
-
if (load.parseError) return undefined;
|
|
82
|
-
const config = load.config;
|
|
83
|
-
const pluginList: string[] = Array.isArray(config['plugin'])
|
|
84
|
-
? (config['plugin'] as string[])
|
|
85
|
-
: [];
|
|
86
|
-
return pluginList.find(p => p.startsWith('opencode-rules-md'));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function getVersion(): string {
|
|
90
|
-
try {
|
|
91
|
-
// Read package.json relative to the project root
|
|
92
|
-
const pkgPath = path.resolve(process.cwd(), 'package.json');
|
|
93
|
-
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
94
|
-
const pkg = JSON.parse(content) as { version?: string };
|
|
95
|
-
return pkg.version ?? 'unknown';
|
|
96
|
-
} catch {
|
|
97
|
-
return 'unknown';
|
|
98
|
-
}
|
|
99
|
-
}
|