@sbugallo/opencode-vpet 0.1.0 → 0.1.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/README.md CHANGED
@@ -67,20 +67,16 @@ Requirements:
67
67
  - Bun `>=1.3.5` only for local development
68
68
 
69
69
 
70
- 1. Register both plugins in your global OpenCode configuration:
70
+ 1. Install both plugins:
71
71
 
72
72
  ```sh
73
73
  npx @sbugallo/opencode-vpet init
74
74
  ```
75
75
 
76
- You can also do it manually by editing `~/.config/opencode/opencode.json` and
77
- `~/.config/opencode/tui.json` to add the following entry:
78
-
79
- ```json
80
- {
81
- "plugin": ["@sbugallo/opencode-vpet"]
82
- }
83
- ```
76
+ The CLI delegates to `opencode plugin @sbugallo/opencode-vpet@<installed-package-version> --global --force`.
77
+ It uses the package's installed exact version so OpenCode uses a version-specific cache key rather
78
+ than reusing a stale bare or `@latest` cache entry. `--force` replaces matching plugin
79
+ configuration registrations.
84
80
 
85
81
  2. Restart OpenCode when the command finishes.
86
82
 
@@ -112,7 +108,8 @@ To update the plugin, run:
112
108
  npx @sbugallo/opencode-vpet update
113
109
  ```
114
110
 
115
- The install CLI updates global OpenCode server and TUI configuration, understands OpenCode JSON and JSONC files, preserves unrelated configuration, and replaces an old unscoped `opencode-vpet` registration with `@sbugallo/opencode-vpet`.
111
+ Like `init`, `update` delegates to OpenCode's native global plugin installer with the installed exact
112
+ package version. If a legacy unscoped `opencode-vpet` registration is present, remove it manually.
116
113
 
117
114
  ## Settings
118
115
 
@@ -0,0 +1,9 @@
1
+ export declare class OpenCodePluginInstallError extends Error {
2
+ readonly exitCode: number | null;
3
+ readonly name = "OpenCodePluginInstallError";
4
+ constructor(exitCode: number | null);
5
+ }
6
+ export type CommandExecutor = (command: string, arguments_: readonly string[]) => Promise<void>;
7
+ export declare const runCommand: CommandExecutor;
8
+ export declare const installGlobalPlugin: (packageSpec: string, execute?: CommandExecutor) => Promise<void>;
9
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"AAEA,qBAAa,0BAA2B,SAAQ,KAAK;IAGvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAF5C,QAAQ,CAAC,IAAI,gCAA+B;gBAEvB,QAAQ,EAAE,MAAM,GAAG,IAAI;CAO7C;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE/F,eAAO,MAAM,UAAU,EAAE,eAQrB,CAAA;AAEJ,eAAO,MAAM,mBAAmB,GAAU,aAAa,MAAM,EAAE,UAAS,eAA4B,KAAG,OAAO,CAAC,IAAI,CAC9C,CAAA"}
package/dist/cli.js CHANGED
@@ -1,103 +1,58 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/cli/config.ts
4
- import { access, mkdir, readFile, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
5
- import { homedir } from "node:os";
6
- import { dirname, join } from "node:path";
7
- import { applyEdits, modify, parse } from "jsonc-parser";
8
- var CANONICAL_PLUGIN = "@sbugallo/opencode-vpet";
9
- var LEGACY_PLUGIN = "opencode-vpet";
10
- var exists = async (path) => {
11
- try {
12
- await access(path);
13
- return true;
14
- } catch (error) {
15
- if (error instanceof Error && "code" in error && error.code === "ENOENT")
16
- return false;
17
- throw error;
18
- }
19
- };
20
- var preferredConfigPath = async (directory, name) => {
21
- const jsonc = join(directory, `${name}.jsonc`);
22
- return await exists(jsonc) ? jsonc : join(directory, `${name}.json`);
23
- };
24
- var nonEmptyPath = (value) => value === undefined || value.trim().length === 0 ? undefined : value;
25
- var resolveConfigDirectory = (env, home) => {
26
- const configDirectory = nonEmptyPath(env.OPENCODE_CONFIG_DIR);
27
- if (configDirectory !== undefined)
28
- return configDirectory;
29
- const xdgConfigHome = nonEmptyPath(env.XDG_CONFIG_HOME);
30
- return xdgConfigHome === undefined ? join(home, ".config", "opencode") : join(xdgConfigHome, "opencode");
31
- };
32
- var resolveConfigPaths = async (env, home) => {
33
- const directory = resolveConfigDirectory(env, home);
34
- return [
35
- nonEmptyPath(env.OPENCODE_CONFIG) ?? await preferredConfigPath(directory, "opencode"),
36
- nonEmptyPath(env.OPENCODE_TUI_CONFIG) ?? await preferredConfigPath(directory, "tui")
37
- ];
38
- };
39
- var parseConfig = (source, path) => {
40
- const errors = [];
41
- const parsed = parse(source, errors, { allowEmptyContent: false, allowTrailingComma: true });
42
- if (errors.length > 0)
43
- throw new Error(`Cannot parse OpenCode configuration: ${path}`);
44
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
45
- throw new Error(`OpenCode configuration must be an object: ${path}`);
46
- }
47
- return parsed;
48
- };
49
- var normalizedPlugins = (value) => {
50
- if (value === undefined)
51
- return [CANONICAL_PLUGIN];
52
- if (!Array.isArray(value))
53
- throw new Error("OpenCode plugin configuration must be an array.");
54
- const retained = value.filter((entry) => typeof entry !== "string" || entry !== LEGACY_PLUGIN && entry !== CANONICAL_PLUGIN);
55
- return [...retained, CANONICAL_PLUGIN];
56
- };
57
- var planConfig = async (path) => {
58
- const source = await exists(path) ? await readFile(path, "utf8") : `{}
59
- `;
60
- const parsed = parseConfig(source, path);
61
- const plugins = normalizedPlugins(parsed.plugin);
62
- const content = applyEdits(source, modify(source, ["plugin"], plugins, { formattingOptions: { insertSpaces: true, tabSize: 2, eol: `
63
- ` } }));
64
- return { path, content, changed: content !== source };
65
- };
66
- var writeAtomically = async (plan) => {
67
- const existing = await exists(plan.path);
68
- const targetPath = existing ? await realpath(plan.path) : plan.path;
69
- const mode = existing ? (await stat(targetPath)).mode & 511 : 384;
70
- await mkdir(dirname(targetPath), { recursive: true });
71
- const temporaryPath = join(dirname(targetPath), `.${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
72
- try {
73
- await writeFile(temporaryPath, plan.content, { encoding: "utf8", flag: "wx", mode });
74
- await rename(temporaryPath, targetPath);
75
- } catch (error) {
76
- await rm(temporaryPath, { force: true });
77
- throw error;
3
+ // src/cli.ts
4
+ import { readFile } from "node:fs/promises";
5
+
6
+ // src/cli/install.ts
7
+ import { spawn } from "node:child_process";
8
+
9
+ class OpenCodePluginInstallError extends Error {
10
+ exitCode;
11
+ name = "OpenCodePluginInstallError";
12
+ constructor(exitCode) {
13
+ super(exitCode === null ? "OpenCode plugin installer exited without a status." : `OpenCode plugin installer exited with status ${exitCode}.`);
14
+ this.exitCode = exitCode;
78
15
  }
79
- };
80
- var normalizeOpenCodeConfigs = async (options = {}) => {
81
- const env = options.env ?? process.env;
82
- const [serverPath, tuiPath] = await resolveConfigPaths(env, options.home ?? homedir());
83
- const plans = await Promise.all([planConfig(serverPath), planConfig(tuiPath)]);
84
- const changedPlans = plans.filter((plan) => plan.changed);
85
- if (!options.dryRun)
86
- await Promise.all(changedPlans.map(writeAtomically));
87
- return { changedPaths: changedPlans.map((plan) => plan.path) };
88
- };
16
+ }
17
+ var runCommand = (command, arguments_) => new Promise((resolve, reject) => {
18
+ const child = spawn(command, arguments_, { shell: false, stdio: "inherit" });
19
+ child.once("error", reject);
20
+ child.once("close", (exitCode) => {
21
+ if (exitCode === 0)
22
+ resolve();
23
+ else
24
+ reject(new OpenCodePluginInstallError(exitCode));
25
+ });
26
+ });
27
+ var installGlobalPlugin = async (packageSpec, execute = runCommand) => execute("opencode", ["plugin", packageSpec, "--global", "--force"]);
89
28
 
90
29
  // src/cli.ts
91
30
  var HELP = `Usage: opencode-vpet <init|update> [--dry-run]
92
31
 
93
32
  Commands:
94
- init Register @sbugallo/opencode-vpet in global OpenCode server and TUI configs.
95
- update Normalize the same registrations after updating the package.
33
+ init Install the current package version through OpenCode's global plugin installer.
34
+ update Reinstall the current package version through the same installer.
96
35
 
97
36
  Options:
98
- --dry-run Show which global config files would change without writing them.
37
+ --dry-run Show the native OpenCode command without running it.
99
38
  --help Show this help text.
100
39
  `;
40
+ var EXACT_SEMVER = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
41
+ var isPackageManifest = (value) => {
42
+ if (typeof value !== "object" || value === null || Array.isArray(value))
43
+ return false;
44
+ if (!("name" in value) || !("version" in value))
45
+ return false;
46
+ const { name, version } = value;
47
+ return name === "@sbugallo/opencode-vpet" && typeof version === "string" && EXACT_SEMVER.test(version);
48
+ };
49
+ var readPackageManifest = async () => {
50
+ const source = await readFile(new URL("../package.json", import.meta.url), "utf8");
51
+ const manifest = JSON.parse(source);
52
+ if (!isPackageManifest(manifest))
53
+ throw new Error("Invalid opencode-vpet package manifest.");
54
+ return manifest;
55
+ };
101
56
  var parseArguments = (arguments_) => {
102
57
  if (arguments_.length === 1 && arguments_[0] === "--help")
103
58
  return { kind: "help" };
@@ -122,13 +77,15 @@ var run = async () => {
122
77
  ${HELP}`);
123
78
  return 2;
124
79
  case "command": {
125
- const result = await normalizeOpenCodeConfigs({ dryRun: parsed.dryRun });
126
- const action = parsed.dryRun ? "Would update" : "Updated";
127
- if (result.changedPaths.length === 0)
128
- process.stdout.write(`OpenCode configuration is already current. Restart OpenCode.
80
+ const manifest = await readPackageManifest();
81
+ const packageSpec = `${manifest.name}@${manifest.version}`;
82
+ if (parsed.dryRun) {
83
+ process.stdout.write(`opencode plugin ${packageSpec} --global --force
129
84
  `);
130
- else
131
- process.stdout.write(`${action} ${result.changedPaths.join(", ")}. Restart OpenCode.
85
+ return 0;
86
+ }
87
+ await installGlobalPlugin(packageSpec);
88
+ process.stdout.write(`OpenCode plugin installation completed. Restart OpenCode.
132
89
  `);
133
90
  return 0;
134
91
  }
@@ -143,5 +100,5 @@ run().then((exitCode) => {
143
100
  process.exitCode = 1;
144
101
  });
145
102
 
146
- //# debugId=EF06F4346B25CF0164756E2164756E21
103
+ //# debugId=7645693B9B10670E64756E2164756E21
147
104
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/cli/config.ts", "../src/cli.ts"],
3
+ "sources": ["../src/cli.ts", "../src/cli/install.ts"],
4
4
  "sourcesContent": [
5
- "import { access, mkdir, readFile, realpath, rename, rm, stat, writeFile } from \"node:fs/promises\"\nimport { homedir } from \"node:os\"\nimport { dirname, join } from \"node:path\"\nimport { applyEdits, modify, parse, type ParseError } from \"jsonc-parser\"\n\nconst CANONICAL_PLUGIN = \"@sbugallo/opencode-vpet\"\nconst LEGACY_PLUGIN = \"opencode-vpet\"\n\ntype Environment = NodeJS.ProcessEnv &\n Readonly<{\n readonly OPENCODE_CONFIG?: string | undefined\n readonly OPENCODE_CONFIG_DIR?: string | undefined\n readonly OPENCODE_TUI_CONFIG?: string | undefined\n readonly XDG_CONFIG_HOME?: string | undefined\n }>\n\nexport type NormalizeOpenCodeConfigsOptions = Readonly<{\n readonly dryRun?: boolean\n readonly env?: Environment\n readonly home?: string\n}>\n\nexport type NormalizeOpenCodeConfigsResult = Readonly<{\n readonly changedPaths: readonly string[]\n}>\n\ntype PlannedConfig = Readonly<{\n readonly path: string\n readonly content: string\n readonly changed: boolean\n}>\n\nconst exists = async (path: string): Promise<boolean> => {\n try {\n await access(path)\n return true\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return false\n throw error\n }\n}\n\nconst preferredConfigPath = async (directory: string, name: \"opencode\" | \"tui\"): Promise<string> => {\n const jsonc = join(directory, `${name}.jsonc`)\n return (await exists(jsonc)) ? jsonc : join(directory, `${name}.json`)\n}\n\nconst nonEmptyPath = (value: string | undefined): string | undefined =>\n value === undefined || value.trim().length === 0 ? undefined : value\n\nconst resolveConfigDirectory = (env: Environment, home: string): string => {\n const configDirectory = nonEmptyPath(env.OPENCODE_CONFIG_DIR)\n if (configDirectory !== undefined) return configDirectory\n const xdgConfigHome = nonEmptyPath(env.XDG_CONFIG_HOME)\n return xdgConfigHome === undefined ? join(home, \".config\", \"opencode\") : join(xdgConfigHome, \"opencode\")\n}\n\nconst resolveConfigPaths = async (env: Environment, home: string): Promise<readonly [string, string]> => {\n const directory = resolveConfigDirectory(env, home)\n return [\n nonEmptyPath(env.OPENCODE_CONFIG) ?? (await preferredConfigPath(directory, \"opencode\")),\n nonEmptyPath(env.OPENCODE_TUI_CONFIG) ?? (await preferredConfigPath(directory, \"tui\")),\n ]\n}\n\nconst parseConfig = (source: string, path: string): Readonly<{ readonly plugin?: unknown }> => {\n const errors: ParseError[] = []\n const parsed: unknown = parse(source, errors, { allowEmptyContent: false, allowTrailingComma: true })\n if (errors.length > 0) throw new Error(`Cannot parse OpenCode configuration: ${path}`)\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`OpenCode configuration must be an object: ${path}`)\n }\n return parsed\n}\n\nconst normalizedPlugins = (value: unknown): readonly unknown[] => {\n if (value === undefined) return [CANONICAL_PLUGIN]\n if (!Array.isArray(value)) throw new Error(\"OpenCode plugin configuration must be an array.\")\n const retained = value.filter(\n (entry) => typeof entry !== \"string\" || (entry !== LEGACY_PLUGIN && entry !== CANONICAL_PLUGIN),\n )\n return [...retained, CANONICAL_PLUGIN]\n}\n\nconst planConfig = async (path: string): Promise<PlannedConfig> => {\n const source = (await exists(path)) ? await readFile(path, \"utf8\") : \"{}\\n\"\n const parsed = parseConfig(source, path)\n const plugins = normalizedPlugins(parsed.plugin)\n const content = applyEdits(\n source,\n modify(source, [\"plugin\"], plugins, { formattingOptions: { insertSpaces: true, tabSize: 2, eol: \"\\n\" } }),\n )\n return { path, content, changed: content !== source }\n}\n\nconst writeAtomically = async (plan: PlannedConfig): Promise<void> => {\n const existing = await exists(plan.path)\n const targetPath = existing ? await realpath(plan.path) : plan.path\n const mode = existing ? (await stat(targetPath)).mode & 0o777 : 0o600\n await mkdir(dirname(targetPath), { recursive: true })\n const temporaryPath = join(\n dirname(targetPath),\n `.${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n )\n try {\n await writeFile(temporaryPath, plan.content, { encoding: \"utf8\", flag: \"wx\", mode })\n await rename(temporaryPath, targetPath)\n } catch (error) {\n await rm(temporaryPath, { force: true })\n throw error\n }\n}\n\nexport const normalizeOpenCodeConfigs = async (\n options: NormalizeOpenCodeConfigsOptions = {},\n): Promise<NormalizeOpenCodeConfigsResult> => {\n const env = options.env ?? process.env\n const [serverPath, tuiPath] = await resolveConfigPaths(env, options.home ?? homedir())\n const plans = await Promise.all([planConfig(serverPath), planConfig(tuiPath)])\n const changedPlans = plans.filter((plan) => plan.changed)\n if (!options.dryRun) await Promise.all(changedPlans.map(writeAtomically))\n return { changedPaths: changedPlans.map((plan) => plan.path) }\n}\n",
6
- "#!/usr/bin/env node\nimport { normalizeOpenCodeConfigs } from \"./cli/config.ts\"\n\nconst HELP = `Usage: opencode-vpet <init|update> [--dry-run]\n\nCommands:\n init Register @sbugallo/opencode-vpet in global OpenCode server and TUI configs.\n update Normalize the same registrations after updating the package.\n\nOptions:\n --dry-run Show which global config files would change without writing them.\n --help Show this help text.\n`\n\ntype Command = \"init\" | \"update\"\n\ntype ParsedArguments =\n | Readonly<{ readonly kind: \"help\" }>\n | Readonly<{ readonly kind: \"command\"; readonly command: Command; readonly dryRun: boolean }>\n | Readonly<{ readonly kind: \"invalid\"; readonly message: string }>\n\nconst parseArguments = (arguments_: readonly string[]): ParsedArguments => {\n if (arguments_.length === 1 && arguments_[0] === \"--help\") return { kind: \"help\" }\n const [command, ...options] = arguments_\n if (command !== \"init\" && command !== \"update\") return { kind: \"invalid\", message: \"Expected init or update.\" }\n if (options.length === 0) return { kind: \"command\", command, dryRun: false }\n if (options.length === 1 && options[0] === \"--dry-run\") return { kind: \"command\", command, dryRun: true }\n return { kind: \"invalid\", message: \"Only --dry-run is supported after a command.\" }\n}\n\nconst run = async (): Promise<number> => {\n const parsed = parseArguments(process.argv.slice(2))\n switch (parsed.kind) {\n case \"help\":\n process.stdout.write(HELP)\n return 0\n case \"invalid\":\n process.stderr.write(`${parsed.message}\\n\\n${HELP}`)\n return 2\n case \"command\": {\n const result = await normalizeOpenCodeConfigs({ dryRun: parsed.dryRun })\n const action = parsed.dryRun ? \"Would update\" : \"Updated\"\n if (result.changedPaths.length === 0)\n process.stdout.write(\"OpenCode configuration is already current. Restart OpenCode.\\n\")\n else process.stdout.write(`${action} ${result.changedPaths.join(\", \")}. Restart OpenCode.\\n`)\n return 0\n }\n }\n}\n\nrun()\n .then((exitCode) => {\n process.exitCode = exitCode\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"Unexpected CLI failure.\"\n process.stderr.write(`${message}\\n`)\n process.exitCode = 1\n })\n"
5
+ "#!/usr/bin/env node\nimport { readFile } from \"node:fs/promises\"\n\nimport { installGlobalPlugin } from \"./cli/install.ts\"\n\nconst HELP = `Usage: opencode-vpet <init|update> [--dry-run]\n\nCommands:\n init Install the current package version through OpenCode's global plugin installer.\n update Reinstall the current package version through the same installer.\n\nOptions:\n --dry-run Show the native OpenCode command without running it.\n --help Show this help text.\n`\n\ntype Command = \"init\" | \"update\"\n\ntype ParsedArguments =\n | Readonly<{ readonly kind: \"help\" }>\n | Readonly<{ readonly kind: \"command\"; readonly command: Command; readonly dryRun: boolean }>\n | Readonly<{ readonly kind: \"invalid\"; readonly message: string }>\n\ntype PackageManifest = Readonly<{ readonly name: \"@sbugallo/opencode-vpet\"; readonly version: string }>\n\nconst EXACT_SEMVER =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/\n\nconst isPackageManifest = (value: unknown): value is PackageManifest => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false\n if (!(\"name\" in value) || !(\"version\" in value)) return false\n const { name, version } = value\n return name === \"@sbugallo/opencode-vpet\" && typeof version === \"string\" && EXACT_SEMVER.test(version)\n}\n\nconst readPackageManifest = async (): Promise<PackageManifest> => {\n const source = await readFile(new URL(\"../package.json\", import.meta.url), \"utf8\")\n const manifest: unknown = JSON.parse(source)\n if (!isPackageManifest(manifest)) throw new Error(\"Invalid opencode-vpet package manifest.\")\n return manifest\n}\n\nconst parseArguments = (arguments_: readonly string[]): ParsedArguments => {\n if (arguments_.length === 1 && arguments_[0] === \"--help\") return { kind: \"help\" }\n const [command, ...options] = arguments_\n if (command !== \"init\" && command !== \"update\") return { kind: \"invalid\", message: \"Expected init or update.\" }\n if (options.length === 0) return { kind: \"command\", command, dryRun: false }\n if (options.length === 1 && options[0] === \"--dry-run\") return { kind: \"command\", command, dryRun: true }\n return { kind: \"invalid\", message: \"Only --dry-run is supported after a command.\" }\n}\n\nconst run = async (): Promise<number> => {\n const parsed = parseArguments(process.argv.slice(2))\n switch (parsed.kind) {\n case \"help\":\n process.stdout.write(HELP)\n return 0\n case \"invalid\":\n process.stderr.write(`${parsed.message}\\n\\n${HELP}`)\n return 2\n case \"command\": {\n const manifest = await readPackageManifest()\n const packageSpec = `${manifest.name}@${manifest.version}`\n if (parsed.dryRun) {\n process.stdout.write(`opencode plugin ${packageSpec} --global --force\\n`)\n return 0\n }\n await installGlobalPlugin(packageSpec)\n process.stdout.write(\"OpenCode plugin installation completed. Restart OpenCode.\\n\")\n return 0\n }\n }\n}\n\nrun()\n .then((exitCode) => {\n process.exitCode = exitCode\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"Unexpected CLI failure.\"\n process.stderr.write(`${message}\\n`)\n process.exitCode = 1\n })\n",
6
+ "import { spawn } from \"node:child_process\"\n\nexport class OpenCodePluginInstallError extends Error {\n readonly name = \"OpenCodePluginInstallError\"\n\n constructor(readonly exitCode: number | null) {\n super(\n exitCode === null\n ? \"OpenCode plugin installer exited without a status.\"\n : `OpenCode plugin installer exited with status ${exitCode}.`,\n )\n }\n}\n\nexport type CommandExecutor = (command: string, arguments_: readonly string[]) => Promise<void>\n\nexport const runCommand: CommandExecutor = (command, arguments_) =>\n new Promise((resolve, reject) => {\n const child = spawn(command, arguments_, { shell: false, stdio: \"inherit\" })\n child.once(\"error\", reject)\n child.once(\"close\", (exitCode) => {\n if (exitCode === 0) resolve()\n else reject(new OpenCodePluginInstallError(exitCode))\n })\n })\n\nexport const installGlobalPlugin = async (packageSpec: string, execute: CommandExecutor = runCommand): Promise<void> =>\n execute(\"opencode\", [\"plugin\", packageSpec, \"--global\", \"--force\"])\n"
7
7
  ],
8
- "mappings": ";;;AAAA;AACA;AACA;AACA;AAEA,IAAM,mBAAmB;AACzB,IAAM,gBAAgB;AA0BtB,IAAM,SAAS,OAAO,SAAmC;AAAA,EACvD,IAAI;AAAA,IACF,MAAM,OAAO,IAAI;AAAA,IACjB,OAAO;AAAA,IACP,OAAO,OAAO;AAAA,IACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS;AAAA,MAAU,OAAO;AAAA,IACjF,MAAM;AAAA;AAAA;AAIV,IAAM,sBAAsB,OAAO,WAAmB,SAA8C;AAAA,EAClG,MAAM,QAAQ,KAAK,WAAW,GAAG,YAAY;AAAA,EAC7C,OAAQ,MAAM,OAAO,KAAK,IAAK,QAAQ,KAAK,WAAW,GAAG,WAAW;AAAA;AAGvE,IAAM,eAAe,CAAC,UACpB,UAAU,aAAa,MAAM,KAAK,EAAE,WAAW,IAAI,YAAY;AAEjE,IAAM,yBAAyB,CAAC,KAAkB,SAAyB;AAAA,EACzE,MAAM,kBAAkB,aAAa,IAAI,mBAAmB;AAAA,EAC5D,IAAI,oBAAoB;AAAA,IAAW,OAAO;AAAA,EAC1C,MAAM,gBAAgB,aAAa,IAAI,eAAe;AAAA,EACtD,OAAO,kBAAkB,YAAY,KAAK,MAAM,WAAW,UAAU,IAAI,KAAK,eAAe,UAAU;AAAA;AAGzG,IAAM,qBAAqB,OAAO,KAAkB,SAAqD;AAAA,EACvG,MAAM,YAAY,uBAAuB,KAAK,IAAI;AAAA,EAClD,OAAO;AAAA,IACL,aAAa,IAAI,eAAe,KAAM,MAAM,oBAAoB,WAAW,UAAU;AAAA,IACrF,aAAa,IAAI,mBAAmB,KAAM,MAAM,oBAAoB,WAAW,KAAK;AAAA,EACtF;AAAA;AAGF,IAAM,cAAc,CAAC,QAAgB,SAA0D;AAAA,EAC7F,MAAM,SAAuB,CAAC;AAAA,EAC9B,MAAM,SAAkB,MAAM,QAAQ,QAAQ,EAAE,mBAAmB,OAAO,oBAAoB,KAAK,CAAC;AAAA,EACpG,IAAI,OAAO,SAAS;AAAA,IAAG,MAAM,IAAI,MAAM,wCAAwC,MAAM;AAAA,EACrF,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAAA,IAC1E,MAAM,IAAI,MAAM,6CAA6C,MAAM;AAAA,EACrE;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,oBAAoB,CAAC,UAAuC;AAAA,EAChE,IAAI,UAAU;AAAA,IAAW,OAAO,CAAC,gBAAgB;AAAA,EACjD,IAAI,CAAC,MAAM,QAAQ,KAAK;AAAA,IAAG,MAAM,IAAI,MAAM,iDAAiD;AAAA,EAC5F,MAAM,WAAW,MAAM,OACrB,CAAC,UAAU,OAAO,UAAU,YAAa,UAAU,iBAAiB,UAAU,gBAChF;AAAA,EACA,OAAO,CAAC,GAAG,UAAU,gBAAgB;AAAA;AAGvC,IAAM,aAAa,OAAO,SAAyC;AAAA,EACjE,MAAM,SAAU,MAAM,OAAO,IAAI,IAAK,MAAM,SAAS,MAAM,MAAM,IAAI;AAAA;AAAA,EACrE,MAAM,SAAS,YAAY,QAAQ,IAAI;AAAA,EACvC,MAAM,UAAU,kBAAkB,OAAO,MAAM;AAAA,EAC/C,MAAM,UAAU,WACd,QACA,OAAO,QAAQ,CAAC,QAAQ,GAAG,SAAS,EAAE,mBAAmB,EAAE,cAAc,MAAM,SAAS,GAAG,KAAK;AAAA,EAAK,EAAE,CAAC,CAC1G;AAAA,EACA,OAAO,EAAE,MAAM,SAAS,SAAS,YAAY,OAAO;AAAA;AAGtD,IAAM,kBAAkB,OAAO,SAAuC;AAAA,EACpE,MAAM,WAAW,MAAM,OAAO,KAAK,IAAI;AAAA,EACvC,MAAM,aAAa,WAAW,MAAM,SAAS,KAAK,IAAI,IAAI,KAAK;AAAA,EAC/D,MAAM,OAAO,YAAY,MAAM,KAAK,UAAU,GAAG,OAAO,MAAQ;AAAA,EAChE,MAAM,MAAM,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACpD,MAAM,gBAAgB,KACpB,QAAQ,UAAU,GAClB,IAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,GACrE;AAAA,EACA,IAAI;AAAA,IACF,MAAM,UAAU,eAAe,KAAK,SAAS,EAAE,UAAU,QAAQ,MAAM,MAAM,KAAK,CAAC;AAAA,IACnF,MAAM,OAAO,eAAe,UAAU;AAAA,IACtC,OAAO,OAAO;AAAA,IACd,MAAM,GAAG,eAAe,EAAE,OAAO,KAAK,CAAC;AAAA,IACvC,MAAM;AAAA;AAAA;AAIH,IAAM,2BAA2B,OACtC,UAA2C,CAAC,MACA;AAAA,EAC5C,MAAM,MAAM,QAAQ,OAAO,QAAQ;AAAA,EACnC,OAAO,YAAY,WAAW,MAAM,mBAAmB,KAAK,QAAQ,QAAQ,QAAQ,CAAC;AAAA,EACrF,MAAM,QAAQ,MAAM,QAAQ,IAAI,CAAC,WAAW,UAAU,GAAG,WAAW,OAAO,CAAC,CAAC;AAAA,EAC7E,MAAM,eAAe,MAAM,OAAO,CAAC,SAAS,KAAK,OAAO;AAAA,EACxD,IAAI,CAAC,QAAQ;AAAA,IAAQ,MAAM,QAAQ,IAAI,aAAa,IAAI,eAAe,CAAC;AAAA,EACxE,OAAO,EAAE,cAAc,aAAa,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE;AAAA;;;ACtH/D,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBb,IAAM,iBAAiB,CAAC,eAAmD;AAAA,EACzE,IAAI,WAAW,WAAW,KAAK,WAAW,OAAO;AAAA,IAAU,OAAO,EAAE,MAAM,OAAO;AAAA,EACjF,OAAO,YAAY,WAAW;AAAA,EAC9B,IAAI,YAAY,UAAU,YAAY;AAAA,IAAU,OAAO,EAAE,MAAM,WAAW,SAAS,2BAA2B;AAAA,EAC9G,IAAI,QAAQ,WAAW;AAAA,IAAG,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,MAAM;AAAA,EAC3E,IAAI,QAAQ,WAAW,KAAK,QAAQ,OAAO;AAAA,IAAa,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,KAAK;AAAA,EACxG,OAAO,EAAE,MAAM,WAAW,SAAS,+CAA+C;AAAA;AAGpF,IAAM,MAAM,YAA6B;AAAA,EACvC,MAAM,SAAS,eAAe,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EACnD,QAAQ,OAAO;AAAA,SACR;AAAA,MACH,QAAQ,OAAO,MAAM,IAAI;AAAA,MACzB,OAAO;AAAA,SACJ;AAAA,MACH,QAAQ,OAAO,MAAM,GAAG,OAAO;AAAA;AAAA,EAAc,MAAM;AAAA,MACnD,OAAO;AAAA,SACJ,WAAW;AAAA,MACd,MAAM,SAAS,MAAM,yBAAyB,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,MACvE,MAAM,SAAS,OAAO,SAAS,iBAAiB;AAAA,MAChD,IAAI,OAAO,aAAa,WAAW;AAAA,QACjC,QAAQ,OAAO,MAAM;AAAA,CAAgE;AAAA,MAClF;AAAA,gBAAQ,OAAO,MAAM,GAAG,UAAU,OAAO,aAAa,KAAK,IAAI;AAAA,CAAwB;AAAA,MAC5F,OAAO;AAAA,IACT;AAAA;AAAA;AAIJ,IAAI,EACD,KAAK,CAAC,aAAa;AAAA,EAClB,QAAQ,WAAW;AAAA,CACpB,EACA,MAAM,CAAC,UAAmB;AAAA,EACzB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AAAA,EACzD,QAAQ,OAAO,MAAM,GAAG;AAAA,CAAW;AAAA,EACnC,QAAQ,WAAW;AAAA,CACpB;",
9
- "debugId": "EF06F4346B25CF0164756E2164756E21",
8
+ "mappings": ";;;AACA;;;ACDA;AAAA;AAEO,MAAM,mCAAmC,MAAM;AAAA,EAG/B;AAAA,EAFZ,OAAO;AAAA,EAEhB,WAAW,CAAU,UAAyB;AAAA,IAC5C,MACE,aAAa,OACT,uDACA,gDAAgD,WACtD;AAAA,IALmB;AAAA;AAOvB;AAIO,IAAM,aAA8B,CAAC,SAAS,eACnD,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,EAC/B,MAAM,QAAQ,MAAM,SAAS,YAAY,EAAE,OAAO,OAAO,OAAO,UAAU,CAAC;AAAA,EAC3E,MAAM,KAAK,SAAS,MAAM;AAAA,EAC1B,MAAM,KAAK,SAAS,CAAC,aAAa;AAAA,IAChC,IAAI,aAAa;AAAA,MAAG,QAAQ;AAAA,IACvB;AAAA,aAAO,IAAI,2BAA2B,QAAQ,CAAC;AAAA,GACrD;AAAA,CACF;AAEI,IAAM,sBAAsB,OAAO,aAAqB,UAA2B,eACxF,QAAQ,YAAY,CAAC,UAAU,aAAa,YAAY,SAAS,CAAC;;;ADtBpE,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBb,IAAM,eACJ;AAEF,IAAM,oBAAoB,CAAC,UAA6C;AAAA,EACtE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EAChF,IAAI,EAAE,UAAU,UAAU,EAAE,aAAa;AAAA,IAAQ,OAAO;AAAA,EACxD,QAAQ,MAAM,YAAY;AAAA,EAC1B,OAAO,SAAS,6BAA6B,OAAO,YAAY,YAAY,aAAa,KAAK,OAAO;AAAA;AAGvG,IAAM,sBAAsB,YAAsC;AAAA,EAChE,MAAM,SAAS,MAAM,SAAS,IAAI,IAAI,mBAAmB,YAAY,GAAG,GAAG,MAAM;AAAA,EACjF,MAAM,WAAoB,KAAK,MAAM,MAAM;AAAA,EAC3C,IAAI,CAAC,kBAAkB,QAAQ;AAAA,IAAG,MAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3F,OAAO;AAAA;AAGT,IAAM,iBAAiB,CAAC,eAAmD;AAAA,EACzE,IAAI,WAAW,WAAW,KAAK,WAAW,OAAO;AAAA,IAAU,OAAO,EAAE,MAAM,OAAO;AAAA,EACjF,OAAO,YAAY,WAAW;AAAA,EAC9B,IAAI,YAAY,UAAU,YAAY;AAAA,IAAU,OAAO,EAAE,MAAM,WAAW,SAAS,2BAA2B;AAAA,EAC9G,IAAI,QAAQ,WAAW;AAAA,IAAG,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,MAAM;AAAA,EAC3E,IAAI,QAAQ,WAAW,KAAK,QAAQ,OAAO;AAAA,IAAa,OAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,KAAK;AAAA,EACxG,OAAO,EAAE,MAAM,WAAW,SAAS,+CAA+C;AAAA;AAGpF,IAAM,MAAM,YAA6B;AAAA,EACvC,MAAM,SAAS,eAAe,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EACnD,QAAQ,OAAO;AAAA,SACR;AAAA,MACH,QAAQ,OAAO,MAAM,IAAI;AAAA,MACzB,OAAO;AAAA,SACJ;AAAA,MACH,QAAQ,OAAO,MAAM,GAAG,OAAO;AAAA;AAAA,EAAc,MAAM;AAAA,MACnD,OAAO;AAAA,SACJ,WAAW;AAAA,MACd,MAAM,WAAW,MAAM,oBAAoB;AAAA,MAC3C,MAAM,cAAc,GAAG,SAAS,QAAQ,SAAS;AAAA,MACjD,IAAI,OAAO,QAAQ;AAAA,QACjB,QAAQ,OAAO,MAAM,mBAAmB;AAAA,CAAgC;AAAA,QACxE,OAAO;AAAA,MACT;AAAA,MACA,MAAM,oBAAoB,WAAW;AAAA,MACrC,QAAQ,OAAO,MAAM;AAAA,CAA6D;AAAA,MAClF,OAAO;AAAA,IACT;AAAA;AAAA;AAIJ,IAAI,EACD,KAAK,CAAC,aAAa;AAAA,EAClB,QAAQ,WAAW;AAAA,CACpB,EACA,MAAM,CAAC,UAAmB;AAAA,EACzB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AAAA,EACzD,QAAQ,OAAO,MAAM,GAAG;AAAA,CAAW;AAAA,EACnC,QAAQ,WAAW;AAAA,CACpB;",
9
+ "debugId": "7645693B9B10670E64756E2164756E21",
10
10
  "names": []
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sbugallo/opencode-vpet",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "An OpenCode virtual-pet plugin with /vpet-spawn, /vpet-freeze, /vpet-unfreeze, /vpet-set, /vpet-dex, and /vpet-history commands.",
5
5
  "author": "Sergio Bugallo",
6
6
  "license": "Apache-2.0",
@@ -37,7 +37,6 @@
37
37
  "opencode-vpet": "./dist/cli.js"
38
38
  },
39
39
  "dependencies": {
40
- "jsonc-parser": "^3.3.1",
41
40
  "solid-js": "^1.9.14"
42
41
  },
43
42
  "devDependencies": {
@@ -64,6 +63,11 @@
64
63
  "import": "./dist/index.js",
65
64
  "default": "./dist/index.js"
66
65
  },
66
+ "./server": {
67
+ "types": "./dist/index.d.ts",
68
+ "import": "./dist/index.js",
69
+ "default": "./dist/index.js"
70
+ },
67
71
  "./tui": {
68
72
  "types": "./dist/tui.d.ts",
69
73
  "import": "./dist/tui.js",
@@ -1,17 +0,0 @@
1
- type Environment = NodeJS.ProcessEnv & Readonly<{
2
- readonly OPENCODE_CONFIG?: string | undefined;
3
- readonly OPENCODE_CONFIG_DIR?: string | undefined;
4
- readonly OPENCODE_TUI_CONFIG?: string | undefined;
5
- readonly XDG_CONFIG_HOME?: string | undefined;
6
- }>;
7
- export type NormalizeOpenCodeConfigsOptions = Readonly<{
8
- readonly dryRun?: boolean;
9
- readonly env?: Environment;
10
- readonly home?: string;
11
- }>;
12
- export type NormalizeOpenCodeConfigsResult = Readonly<{
13
- readonly changedPaths: readonly string[];
14
- }>;
15
- export declare const normalizeOpenCodeConfigs: (options?: NormalizeOpenCodeConfigsOptions) => Promise<NormalizeOpenCodeConfigsResult>;
16
- export {};
17
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAQA,KAAK,WAAW,GAAG,MAAM,CAAC,UAAU,GAClC,QAAQ,CAAC;IACP,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9C,CAAC,CAAA;AAEJ,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAC,CAAA;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACzC,CAAC,CAAA;AAyFF,eAAO,MAAM,wBAAwB,GACnC,UAAS,+BAAoC,KAC5C,OAAO,CAAC,8BAA8B,CAOxC,CAAA"}