@ericsanchezok/synergy-plugin-kit 2.2.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.
Files changed (53) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.js +25 -0
  3. package/dist/cmd.d.ts +6 -0
  4. package/dist/cmd.js +3 -0
  5. package/dist/commands/build.d.ts +6 -0
  6. package/dist/commands/build.js +194 -0
  7. package/dist/commands/create.d.ts +9 -0
  8. package/dist/commands/create.js +416 -0
  9. package/dist/commands/dev.d.ts +9 -0
  10. package/dist/commands/dev.js +192 -0
  11. package/dist/commands/entry.d.ts +19 -0
  12. package/dist/commands/entry.js +71 -0
  13. package/dist/commands/index.d.ts +9 -0
  14. package/dist/commands/index.js +9 -0
  15. package/dist/commands/pack.d.ts +8 -0
  16. package/dist/commands/pack.js +64 -0
  17. package/dist/commands/publish-market.d.ts +23 -0
  18. package/dist/commands/publish-market.js +224 -0
  19. package/dist/commands/sign.d.ts +10 -0
  20. package/dist/commands/sign.js +120 -0
  21. package/dist/commands/test.d.ts +5 -0
  22. package/dist/commands/test.js +40 -0
  23. package/dist/commands/validate.d.ts +10 -0
  24. package/dist/commands/validate.js +348 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.js +3 -0
  27. package/dist/lib/capability.d.ts +2 -0
  28. package/dist/lib/capability.js +42 -0
  29. package/dist/lib/crypto.d.ts +5 -0
  30. package/dist/lib/crypto.js +27 -0
  31. package/dist/lib/hash.d.ts +3 -0
  32. package/dist/lib/hash.js +14 -0
  33. package/dist/lib/ids.d.ts +3 -0
  34. package/dist/lib/ids.js +7 -0
  35. package/dist/lib/market-entry.d.ts +57 -0
  36. package/dist/lib/market-entry.js +181 -0
  37. package/dist/lib/paths.d.ts +3 -0
  38. package/dist/lib/paths.js +5 -0
  39. package/dist/lib/risk.d.ts +2 -0
  40. package/dist/lib/risk.js +28 -0
  41. package/dist/lib/runtime-discovery.d.ts +12 -0
  42. package/dist/lib/runtime-discovery.js +13 -0
  43. package/dist/lib/runtime-mode.d.ts +9 -0
  44. package/dist/lib/runtime-mode.js +15 -0
  45. package/dist/lib/runtime-policy.d.ts +12 -0
  46. package/dist/lib/runtime-policy.js +62 -0
  47. package/dist/lib/signature.d.ts +15 -0
  48. package/dist/lib/signature.js +15 -0
  49. package/dist/lib/spec.d.ts +7 -0
  50. package/dist/lib/spec.js +21 -0
  51. package/dist/ui.d.ts +15 -0
  52. package/dist/ui.js +26 -0
  53. package/package.json +43 -0
@@ -0,0 +1,57 @@
1
+ import { type PluginManifest as PluginManifestType } from "@ericsanchezok/synergy-plugin";
2
+ export interface GithubRegistryEntry {
3
+ schemaVersion: 1;
4
+ id: string;
5
+ name: string;
6
+ description: string;
7
+ repo: string;
8
+ homepage?: string;
9
+ author: {
10
+ name: string;
11
+ email?: string;
12
+ url?: string;
13
+ };
14
+ verified: boolean;
15
+ official: boolean;
16
+ keywords: string[];
17
+ compatibility: {
18
+ synergy: string;
19
+ };
20
+ versions: Array<{
21
+ version: string;
22
+ downloadUrl: string;
23
+ signatureUrl: string;
24
+ integrity: string;
25
+ manifestHash: string;
26
+ permissionsHash: string;
27
+ risk: "low" | "medium" | "high";
28
+ runtimeMode: "in-process" | "worker" | "process";
29
+ permissionsSummary: Array<{
30
+ key: string;
31
+ description: string;
32
+ risk: string;
33
+ }>;
34
+ tools: string[];
35
+ uiSurfaces: string[];
36
+ publishedAt: string;
37
+ changelog?: string;
38
+ }>;
39
+ yankedVersions: string[];
40
+ }
41
+ export declare function parseAuthor(input?: string): GithubRegistryEntry["author"];
42
+ export declare function normalizeRepoUrl(input?: string): string | undefined;
43
+ export declare function githubRepoSlug(input?: string): string | undefined;
44
+ export declare function releaseAssetUrl(repo: string | undefined, version: string, filename: string): string | undefined;
45
+ export declare function readTarballManifest(tarballPath: string): PluginManifestType;
46
+ export declare function uiSurfaces(manifest: PluginManifestType): string[];
47
+ export declare function githubEntry(input: {
48
+ tarballPath: string;
49
+ repo?: string;
50
+ downloadUrl?: string;
51
+ signatureUrl?: string;
52
+ verified?: boolean;
53
+ official?: boolean;
54
+ changelog?: string;
55
+ publishedAt?: string;
56
+ }): GithubRegistryEntry;
57
+ export declare function writeGithubEntry(filepath: string, next: GithubRegistryEntry): GithubRegistryEntry;
@@ -0,0 +1,181 @@
1
+ import fs from "fs";
2
+ import os from "os";
3
+ import path from "path";
4
+ import { PluginManifest } from "@ericsanchezok/synergy-plugin";
5
+ import { baseCapabilities } from "./capability";
6
+ import { computeManifestHash, computePermissionsHash } from "./hash";
7
+ import { computeRisk } from "./risk";
8
+ import { resolveRuntimeMode } from "./runtime-mode";
9
+ import { readSignatureFile } from "./signature";
10
+ import { sha256File } from "./crypto";
11
+ export function parseAuthor(input) {
12
+ if (!input)
13
+ return { name: "unknown" };
14
+ const email = input.match(/<([^>]+)>/)?.[1];
15
+ const url = input.match(/\(([^)]+)\)/)?.[1];
16
+ const name = input
17
+ .replace(/<[^>]+>/g, "")
18
+ .replace(/\([^)]+\)/g, "")
19
+ .trim() || input;
20
+ return { name, ...(email ? { email } : {}), ...(url ? { url } : {}) };
21
+ }
22
+ export function normalizeRepoUrl(input) {
23
+ if (!input)
24
+ return undefined;
25
+ const trimmed = input.trim();
26
+ const gitSsh = trimmed.match(/^git@github\.com:([^/]+\/[^/]+?)(?:\.git)?$/);
27
+ if (gitSsh)
28
+ return `https://github.com/${gitSsh[1]}`;
29
+ if (/^https:\/\/github\.com\/[^/]+\/[^/]+/.test(trimmed))
30
+ return trimmed.replace(/\.git$/, "");
31
+ return trimmed;
32
+ }
33
+ export function githubRepoSlug(input) {
34
+ const normalized = normalizeRepoUrl(input);
35
+ if (!normalized)
36
+ return undefined;
37
+ const match = normalized.match(/^https:\/\/github\.com\/([^/]+\/[^/]+?)(?:\/.*)?$/);
38
+ if (!match)
39
+ return undefined;
40
+ return match[1].replace(/\.git$/, "");
41
+ }
42
+ export function releaseAssetUrl(repo, version, filename) {
43
+ const normalized = normalizeRepoUrl(repo);
44
+ if (!normalized || !normalized.startsWith("https://github.com/"))
45
+ return undefined;
46
+ return `${normalized}/releases/download/v${version}/${encodeURIComponent(filename)}`;
47
+ }
48
+ function extractArchive(tarballPath) {
49
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "synergy-plugin-entry-"));
50
+ const result = Bun.spawnSync(["tar", "-xzf", tarballPath, "-C", tmp], { stdout: "pipe", stderr: "pipe" });
51
+ if (result.exitCode !== 0) {
52
+ const stderr = new TextDecoder().decode(result.stderr);
53
+ throw new Error(`Failed to inspect tarball${stderr ? `: ${stderr}` : ""}`);
54
+ }
55
+ return tmp;
56
+ }
57
+ export function readTarballManifest(tarballPath) {
58
+ const extractedDir = extractArchive(tarballPath);
59
+ const manifestPath = path.join(extractedDir, "plugin.json");
60
+ if (!fs.existsSync(manifestPath)) {
61
+ throw new Error("Tarball does not contain plugin.json. Run `synergy-plugin build` and `synergy-plugin pack` first.");
62
+ }
63
+ return PluginManifest.parse(JSON.parse(fs.readFileSync(manifestPath, "utf-8")));
64
+ }
65
+ export function uiSurfaces(manifest) {
66
+ const ui = manifest.contributes?.ui;
67
+ if (!ui)
68
+ return [];
69
+ const surfaces = [];
70
+ if (ui.toolRenderers?.length)
71
+ surfaces.push("toolRenderers");
72
+ if (ui.partRenderers?.length)
73
+ surfaces.push("partRenderers");
74
+ if (ui.workspacePanels?.length)
75
+ surfaces.push("workspacePanels");
76
+ if (ui.globalPanels?.length)
77
+ surfaces.push("globalPanels");
78
+ if (ui.settings?.length)
79
+ surfaces.push("settings");
80
+ if (ui.chatComponents?.length)
81
+ surfaces.push("chatComponents");
82
+ if (ui.themes?.length)
83
+ surfaces.push("themes");
84
+ if (ui.icons?.length)
85
+ surfaces.push("icons");
86
+ if (ui.routes?.length)
87
+ surfaces.push("routes");
88
+ if (ui.commands?.length)
89
+ surfaces.push("commands");
90
+ return surfaces;
91
+ }
92
+ function registryPermissions(capabilities) {
93
+ return capabilities.map((cap) => ({
94
+ key: cap,
95
+ description: `Requires ${cap}`,
96
+ risk: cap.includes("write") || cap === "shell" || cap === "secrets" ? "high" : "medium",
97
+ }));
98
+ }
99
+ export function githubEntry(input) {
100
+ const manifest = readTarballManifest(input.tarballPath);
101
+ const repo = normalizeRepoUrl(input.repo ?? manifest.repository ?? manifest.homepage);
102
+ if (!repo)
103
+ throw new Error("GitHub registry entry requires --repo or manifest.repository");
104
+ const filename = path.basename(input.tarballPath);
105
+ const downloadUrl = input.downloadUrl ?? releaseAssetUrl(repo, manifest.version, filename);
106
+ const signatureUrl = input.signatureUrl ?? (downloadUrl ? `${downloadUrl}.sig` : undefined);
107
+ if (!downloadUrl || !signatureUrl) {
108
+ throw new Error("GitHub registry entry requires --download-url and --signature-url");
109
+ }
110
+ const capabilities = baseCapabilities(manifest);
111
+ const risk = computeRisk(capabilities, manifest);
112
+ const runtimeMode = resolveRuntimeMode({
113
+ source: "local",
114
+ manifestMode: manifest.runtime?.mode,
115
+ userTrusted: true,
116
+ risk,
117
+ });
118
+ const integrity = `sha256-${sha256File(input.tarballPath)}`;
119
+ const manifestHash = computeManifestHash(manifest);
120
+ const permissionsHash = computePermissionsHash(manifest, capabilities);
121
+ const signature = readSignatureFile(input.tarballPath);
122
+ if (!signature)
123
+ throw new Error(`Signature file not found or invalid: ${input.tarballPath}.sig`);
124
+ if (signature.pluginId !== manifest.name)
125
+ throw new Error("Signature pluginId does not match manifest name");
126
+ if (signature.version !== manifest.version)
127
+ throw new Error("Signature version does not match manifest version");
128
+ if (signature.payload.tarballHash !== integrity.slice("sha256-".length)) {
129
+ throw new Error("Signature tarball hash does not match artifact integrity");
130
+ }
131
+ if (signature.payload.manifestHash !== manifestHash)
132
+ throw new Error("Signature manifest hash does not match manifest");
133
+ if (signature.payload.permissionsHash !== permissionsHash) {
134
+ throw new Error("Signature permissions hash does not match manifest capabilities");
135
+ }
136
+ return {
137
+ schemaVersion: 1,
138
+ id: manifest.name,
139
+ name: manifest.name,
140
+ description: manifest.description,
141
+ repo,
142
+ ...(manifest.homepage ? { homepage: manifest.homepage } : {}),
143
+ author: parseAuthor(manifest.author),
144
+ verified: Boolean(input.verified),
145
+ official: Boolean(input.official),
146
+ keywords: [...new Set([...(manifest.keywords ?? []), "synergy-plugin"])].sort(),
147
+ compatibility: { synergy: manifest.engines?.synergy ?? manifest.minSynergyVersion ?? ">=1.0.0" },
148
+ versions: [
149
+ {
150
+ version: manifest.version,
151
+ downloadUrl,
152
+ signatureUrl,
153
+ integrity,
154
+ manifestHash,
155
+ permissionsHash,
156
+ risk,
157
+ runtimeMode,
158
+ permissionsSummary: registryPermissions(capabilities),
159
+ tools: (manifest.contributes?.tools ?? []).map((tool) => tool.name),
160
+ uiSurfaces: uiSurfaces(manifest),
161
+ publishedAt: input.publishedAt ?? new Date().toISOString(),
162
+ ...(input.changelog ? { changelog: input.changelog } : {}),
163
+ },
164
+ ],
165
+ yankedVersions: [],
166
+ };
167
+ }
168
+ export function writeGithubEntry(filepath, next) {
169
+ let merged = next;
170
+ if (fs.existsSync(filepath)) {
171
+ const existing = JSON.parse(fs.readFileSync(filepath, "utf-8"));
172
+ const versions = [
173
+ ...existing.versions.filter((version) => version.version !== next.versions[0]?.version),
174
+ ...next.versions,
175
+ ].sort((a, b) => Date.parse(a.publishedAt) - Date.parse(b.publishedAt));
176
+ merged = { ...existing, ...next, versions, yankedVersions: existing.yankedVersions ?? [] };
177
+ }
178
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
179
+ fs.writeFileSync(filepath, JSON.stringify(merged, null, 2) + "\n");
180
+ return merged;
181
+ }
@@ -0,0 +1,3 @@
1
+ export declare const SYNERGY_ROOT: string;
2
+ export declare const SIGNING_KEYS_DIR: string;
3
+ export declare const SIGNING_KEY_FILE: string;
@@ -0,0 +1,5 @@
1
+ import os from "os";
2
+ import path from "path";
3
+ export const SYNERGY_ROOT = process.env.SYNERGY_HOME || path.join(os.homedir(), ".synergy");
4
+ export const SIGNING_KEYS_DIR = path.join(SYNERGY_ROOT, "keys");
5
+ export const SIGNING_KEY_FILE = path.join(SIGNING_KEYS_DIR, "signing-key.json");
@@ -0,0 +1,2 @@
1
+ import type { PluginManifest } from "@ericsanchezok/synergy-plugin";
2
+ export declare function computeRisk(capabilities: string[], manifest?: PluginManifest): "low" | "medium" | "high";
@@ -0,0 +1,28 @@
1
+ export function computeRisk(capabilities, manifest) {
2
+ if (capabilities.length === 0)
3
+ return "low";
4
+ let risk = "low";
5
+ for (const cap of capabilities) {
6
+ switch (cap) {
7
+ case "shell":
8
+ case "filesystem:write":
9
+ case "secrets":
10
+ case "hooks.promptTransform":
11
+ risk = "high";
12
+ break;
13
+ case "filesystem:read":
14
+ case "session_data":
15
+ case "config:write":
16
+ if (risk !== "high")
17
+ risk = "medium";
18
+ break;
19
+ case "network":
20
+ if (risk !== "high") {
21
+ const domains = manifest?.permissions?.network?.connectDomains ?? [];
22
+ risk = domains.length > 0 ? "medium" : "high";
23
+ }
24
+ break;
25
+ }
26
+ }
27
+ return risk;
28
+ }
@@ -0,0 +1,12 @@
1
+ export interface RuntimeDiscoveryInput {
2
+ manifestToolNames: string[];
3
+ runtimeToolNames: string[] | null;
4
+ pluginId: string;
5
+ }
6
+ export interface RuntimeDiscoveryResult {
7
+ matched: string[];
8
+ undeclared: string[];
9
+ declaredButMissing: string[];
10
+ loadFailed: boolean;
11
+ }
12
+ export declare function validateRuntimeDiscovery(input: RuntimeDiscoveryInput): RuntimeDiscoveryResult;
@@ -0,0 +1,13 @@
1
+ export function validateRuntimeDiscovery(input) {
2
+ if (input.runtimeToolNames === null) {
3
+ return { matched: [], undeclared: [], declaredButMissing: input.manifestToolNames, loadFailed: true };
4
+ }
5
+ const manifestTools = new Set(input.manifestToolNames);
6
+ const runtimeTools = new Set(input.runtimeToolNames);
7
+ return {
8
+ matched: input.runtimeToolNames.filter((tool) => manifestTools.has(tool)),
9
+ undeclared: input.runtimeToolNames.filter((tool) => !manifestTools.has(tool)),
10
+ declaredButMissing: input.manifestToolNames.filter((tool) => !runtimeTools.has(tool)),
11
+ loadFailed: false,
12
+ };
13
+ }
@@ -0,0 +1,9 @@
1
+ export type PluginSource = "local" | "official" | "npm" | "git" | "url" | "builtin";
2
+ export type RuntimeMode = "in-process" | "worker" | "process";
3
+ export declare function resolveRuntimeMode(input: {
4
+ source: PluginSource;
5
+ manifestMode?: RuntimeMode;
6
+ userTrusted?: boolean;
7
+ risk?: "low" | "medium" | "high";
8
+ forceProcess?: boolean;
9
+ }): RuntimeMode;
@@ -0,0 +1,15 @@
1
+ const TRUSTED_SOURCES = new Set(["builtin", "official", "local"]);
2
+ export function resolveRuntimeMode(input) {
3
+ const { source, manifestMode, userTrusted = false, risk = "low", forceProcess = false } = input;
4
+ if (forceProcess)
5
+ return "process";
6
+ if (risk === "high")
7
+ return "process";
8
+ if (manifestMode === "process")
9
+ return "process";
10
+ if (manifestMode === "worker" && userTrusted)
11
+ return "worker";
12
+ if (manifestMode === "in-process")
13
+ return TRUSTED_SOURCES.has(source) ? "in-process" : "process";
14
+ return TRUSTED_SOURCES.has(source) ? "in-process" : "process";
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { PluginManifest } from "@ericsanchezok/synergy-plugin";
2
+ import type { PluginSource } from "./runtime-mode";
3
+ export interface CheckResult {
4
+ type: "pass" | "warn" | "error";
5
+ message: string;
6
+ }
7
+ export declare function validateRuntimePolicy(input: {
8
+ manifest: PluginManifest;
9
+ source: PluginSource;
10
+ trustTier: "declarative" | "trusted-import" | "sandbox";
11
+ risk: "low" | "medium" | "high";
12
+ }): CheckResult[];
@@ -0,0 +1,62 @@
1
+ export function validateRuntimePolicy(input) {
2
+ const results = [];
3
+ const { manifest, source, trustTier, risk } = input;
4
+ const effectiveMode = manifest.runtime?.mode ?? "in-process";
5
+ const isThirdParty = source !== "local" && source !== "builtin";
6
+ if (isThirdParty && effectiveMode === "in-process") {
7
+ results.push({
8
+ type: "error",
9
+ message: `Third-party plugin (source=${source}) cannot run in-process. Use worker or process isolation.`,
10
+ });
11
+ }
12
+ if (risk === "high" && effectiveMode === "in-process") {
13
+ results.push({
14
+ type: "error",
15
+ message: "High-risk plugin cannot run in-process. Use worker or process isolation.",
16
+ });
17
+ }
18
+ const requestedTier = manifest.trust?.requestedTier;
19
+ if (trustTier === "sandbox" && requestedTier !== "sandbox") {
20
+ results.push({
21
+ type: "warn",
22
+ message: `Plugin has sandbox trust tier but effective runtime mode "${effectiveMode}" may not provide full sandbox isolation. ` +
23
+ "Consider using process mode with explicit resource limits.",
24
+ });
25
+ }
26
+ if (requestedTier !== undefined && requestedTier !== trustTier) {
27
+ results.push({
28
+ type: "warn",
29
+ message: `Plugin requested trust tier "${requestedTier}" but was assigned "${trustTier}" ` +
30
+ `(source=${source}). Runtime mode is "${effectiveMode}".`,
31
+ });
32
+ }
33
+ if (effectiveMode === "worker") {
34
+ const tools = manifest.permissions?.tools;
35
+ const hasShell = tools?.shell ?? false;
36
+ const hasFileWrite = tools?.filesystem === "write";
37
+ const hasMcpSpawn = tools?.mcp === "spawn";
38
+ const contributedTools = manifest.contributes?.tools ?? [];
39
+ const toolShell = contributedTools.some((tool) => tool.capabilities?.shell);
40
+ const toolFileWrite = contributedTools.some((tool) => tool.capabilities?.filesystem === "write");
41
+ if (hasShell || toolShell || hasFileWrite || toolFileWrite || hasMcpSpawn) {
42
+ const unsupported = [];
43
+ if (hasShell || toolShell)
44
+ unsupported.push("shell");
45
+ if (hasFileWrite || toolFileWrite)
46
+ unsupported.push("filesystem:write");
47
+ if (hasMcpSpawn)
48
+ unsupported.push("mcp:spawn");
49
+ results.push({
50
+ type: "warn",
51
+ message: `Worker mode does not fully support: ${unsupported.join(", ")}. Consider process mode for these capabilities.`,
52
+ });
53
+ }
54
+ }
55
+ if (effectiveMode === "process" && !manifest.runtime?.resources) {
56
+ results.push({
57
+ type: "warn",
58
+ message: "Process mode used without resource limits. Specify runtime.resources to prevent resource exhaustion.",
59
+ });
60
+ }
61
+ return results;
62
+ }
@@ -0,0 +1,15 @@
1
+ export interface SignatureMetadata {
2
+ signatureVersion: 1;
3
+ pluginId: string;
4
+ version: string;
5
+ algorithm: "ed25519";
6
+ signer: string;
7
+ signature: string;
8
+ signedAt: number;
9
+ payload: {
10
+ tarballHash: string;
11
+ manifestHash: string;
12
+ permissionsHash: string;
13
+ };
14
+ }
15
+ export declare function readSignatureFile(tarballPath: string): SignatureMetadata | null;
@@ -0,0 +1,15 @@
1
+ import fs from "fs";
2
+ export function readSignatureFile(tarballPath) {
3
+ const sigPath = `${tarballPath}.sig`;
4
+ if (!fs.existsSync(sigPath))
5
+ return null;
6
+ try {
7
+ const parsed = JSON.parse(fs.readFileSync(sigPath, "utf-8"));
8
+ if (parsed.signatureVersion !== 1 || parsed.algorithm !== "ed25519")
9
+ return null;
10
+ return parsed;
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
@@ -0,0 +1,7 @@
1
+ import type { PluginDescriptor, PluginManifest as PluginManifestType } from "@ericsanchezok/synergy-plugin";
2
+ export declare function resolveEntryFromPluginDir(pluginDir: string, manifest: PluginManifestType | null): string;
3
+ export declare function importUrlForEntry(entryPath: string, nonce?: number): string;
4
+ export declare function assertCanonicalPluginIdentity(input: {
5
+ manifest: PluginManifestType | null;
6
+ descriptor: PluginDescriptor;
7
+ }): void;
@@ -0,0 +1,21 @@
1
+ import path from "path";
2
+ import { pathToFileURL } from "url";
3
+ export function resolveEntryFromPluginDir(pluginDir, manifest) {
4
+ const main = manifest?.main ?? "./src/index.ts";
5
+ return path.resolve(pluginDir, main);
6
+ }
7
+ export function importUrlForEntry(entryPath, nonce) {
8
+ const url = pathToFileURL(entryPath);
9
+ if (nonce !== undefined)
10
+ url.searchParams.set("t", String(nonce));
11
+ return url.toString();
12
+ }
13
+ export function assertCanonicalPluginIdentity(input) {
14
+ const manifestId = input.manifest?.name;
15
+ const descriptorId = input.descriptor.id;
16
+ if (!descriptorId)
17
+ throw new Error("PluginDescriptor.id is required");
18
+ if (manifestId && manifestId !== descriptorId) {
19
+ throw new Error(`Plugin identity mismatch: plugin.json.name "${manifestId}" does not match descriptor id "${descriptorId}"`);
20
+ }
21
+ }
package/dist/ui.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export declare namespace UI {
2
+ const Style: {
3
+ readonly TEXT_NORMAL: "\u001B[0m";
4
+ readonly TEXT_NORMAL_BOLD: "\u001B[1m";
5
+ readonly TEXT_DIM: "\u001B[2m";
6
+ readonly TEXT_SUCCESS: "\u001B[32m";
7
+ readonly TEXT_WARNING: "\u001B[33m";
8
+ readonly TEXT_DANGER: "\u001B[31m";
9
+ readonly TEXT_HIGHLIGHT: "\u001B[36m";
10
+ readonly TEXT_HIGHLIGHT_BOLD: "\u001B[1;36m";
11
+ };
12
+ function println(message?: string): void;
13
+ function print(message: string): void;
14
+ function error(message: string): void;
15
+ }
package/dist/ui.js ADDED
@@ -0,0 +1,26 @@
1
+ import { EOL } from "os";
2
+ export var UI;
3
+ (function (UI) {
4
+ UI.Style = {
5
+ TEXT_NORMAL: "\x1b[0m",
6
+ TEXT_NORMAL_BOLD: "\x1b[1m",
7
+ TEXT_DIM: "\x1b[2m",
8
+ TEXT_SUCCESS: "\x1b[32m",
9
+ TEXT_WARNING: "\x1b[33m",
10
+ TEXT_DANGER: "\x1b[31m",
11
+ TEXT_HIGHLIGHT: "\x1b[36m",
12
+ TEXT_HIGHLIGHT_BOLD: "\x1b[1;36m",
13
+ };
14
+ function println(message = "") {
15
+ process.stdout.write(message + EOL);
16
+ }
17
+ UI.println = println;
18
+ function print(message) {
19
+ process.stdout.write(message);
20
+ }
21
+ UI.print = print;
22
+ function error(message) {
23
+ process.stderr.write(`${UI.Style.TEXT_DANGER}${message}${UI.Style.TEXT_NORMAL}${EOL}`);
24
+ }
25
+ UI.error = error;
26
+ })(UI || (UI = {}));
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/package.json",
3
+ "name": "@ericsanchezok/synergy-plugin-kit",
4
+ "version": "2.2.1",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/SII-Holos/synergy.git"
10
+ },
11
+ "publishConfig": {
12
+ "registry": "https://registry.npmjs.org",
13
+ "access": "public"
14
+ },
15
+ "bin": {
16
+ "synergy-plugin": "./dist/cli.js",
17
+ "synergy-plugin-kit": "./dist/cli.js"
18
+ },
19
+ "scripts": {
20
+ "typecheck": "tsgo --noEmit",
21
+ "build": "tsc"
22
+ },
23
+ "exports": {
24
+ ".": {
25
+ "import": "./dist/index.js",
26
+ "types": "./dist/index.d.ts"
27
+ },
28
+ "./commands": {
29
+ "import": "./dist/commands/index.js",
30
+ "types": "./dist/commands/index.d.ts"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "dependencies": {
37
+ "@ericsanchezok/synergy-plugin": "2.2.0",
38
+ "yargs": "18.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "zod": ">=4.0.0"
42
+ }
43
+ }