@vicinae/api 0.3.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.
Files changed (113) hide show
  1. package/README.md +37 -0
  2. package/bin/run.js +9 -0
  3. package/dist/api/ai.d.ts +110 -0
  4. package/dist/api/ai.js +120 -0
  5. package/dist/api/alert.d.ts +22 -0
  6. package/dist/api/alert.js +61 -0
  7. package/dist/api/bus.d.ts +95 -0
  8. package/dist/api/bus.js +211 -0
  9. package/dist/api/cache.d.ts +117 -0
  10. package/dist/api/cache.js +52 -0
  11. package/dist/api/clipboard.d.ts +34 -0
  12. package/dist/api/clipboard.js +52 -0
  13. package/dist/api/color.d.ts +24 -0
  14. package/dist/api/color.js +24 -0
  15. package/dist/api/components/action-pannel.d.ts +23 -0
  16. package/dist/api/components/action-pannel.js +30 -0
  17. package/dist/api/components/actions.d.ts +52 -0
  18. package/dist/api/components/actions.js +81 -0
  19. package/dist/api/components/detail.d.ts +21 -0
  20. package/dist/api/components/detail.js +12 -0
  21. package/dist/api/components/dropdown.d.ts +36 -0
  22. package/dist/api/components/dropdown.js +21 -0
  23. package/dist/api/components/empty-view.d.ts +9 -0
  24. package/dist/api/components/empty-view.js +12 -0
  25. package/dist/api/components/form.d.ts +81 -0
  26. package/dist/api/components/form.js +53 -0
  27. package/dist/api/components/grid.d.ts +117 -0
  28. package/dist/api/components/grid.js +80 -0
  29. package/dist/api/components/index.d.ts +7 -0
  30. package/dist/api/components/index.js +23 -0
  31. package/dist/api/components/list.d.ts +109 -0
  32. package/dist/api/components/list.js +53 -0
  33. package/dist/api/components/menu-bar.d.ts +26 -0
  34. package/dist/api/components/menu-bar.js +25 -0
  35. package/dist/api/components/metadata.d.ts +23 -0
  36. package/dist/api/components/metadata.js +27 -0
  37. package/dist/api/components/tag.d.ts +16 -0
  38. package/dist/api/components/tag.js +28 -0
  39. package/dist/api/context/index.d.ts +1 -0
  40. package/dist/api/context/index.js +17 -0
  41. package/dist/api/context/navigation-context.d.ts +7 -0
  42. package/dist/api/context/navigation-context.js +8 -0
  43. package/dist/api/context/navigation-provider.d.ts +4 -0
  44. package/dist/api/context/navigation-provider.js +40 -0
  45. package/dist/api/controls.d.ts +3 -0
  46. package/dist/api/controls.js +20 -0
  47. package/dist/api/environment.d.ts +118 -0
  48. package/dist/api/environment.js +17 -0
  49. package/dist/api/hooks/index.d.ts +2 -0
  50. package/dist/api/hooks/index.js +18 -0
  51. package/dist/api/hooks/use-applications.d.ts +2 -0
  52. package/dist/api/hooks/use-applications.js +19 -0
  53. package/dist/api/hooks/use-imperative-form-handle.d.ts +3 -0
  54. package/dist/api/hooks/use-imperative-form-handle.js +25 -0
  55. package/dist/api/hooks/use-navigation.d.ts +4 -0
  56. package/dist/api/hooks/use-navigation.js +13 -0
  57. package/dist/api/hooks.d.ts +1 -0
  58. package/dist/api/hooks.js +24 -0
  59. package/dist/api/icon.d.ts +444 -0
  60. package/dist/api/icon.js +448 -0
  61. package/dist/api/image.d.ts +35 -0
  62. package/dist/api/image.js +84 -0
  63. package/dist/api/index.d.ts +19 -0
  64. package/dist/api/index.js +35 -0
  65. package/dist/api/keyboard.d.ts +16 -0
  66. package/dist/api/keyboard.js +12 -0
  67. package/dist/api/lib/result.d.ts +9 -0
  68. package/dist/api/lib/result.js +11 -0
  69. package/dist/api/local-storage.d.ts +13 -0
  70. package/dist/api/local-storage.js +31 -0
  71. package/dist/api/oauth.d.ts +319 -0
  72. package/dist/api/oauth.js +166 -0
  73. package/dist/api/preference.d.ts +5 -0
  74. package/dist/api/preference.js +18 -0
  75. package/dist/api/proto/application.d.ts +48 -0
  76. package/dist/api/proto/application.js +378 -0
  77. package/dist/api/proto/clipboard.d.ts +65 -0
  78. package/dist/api/proto/clipboard.js +614 -0
  79. package/dist/api/proto/common.d.ts +28 -0
  80. package/dist/api/proto/common.js +102 -0
  81. package/dist/api/proto/extension.d.ts +68 -0
  82. package/dist/api/proto/extension.js +604 -0
  83. package/dist/api/proto/google/protobuf/struct.d.ts +107 -0
  84. package/dist/api/proto/google/protobuf/struct.js +456 -0
  85. package/dist/api/proto/ipc.d.ts +64 -0
  86. package/dist/api/proto/ipc.js +604 -0
  87. package/dist/api/proto/manager.d.ts +82 -0
  88. package/dist/api/proto/manager.js +689 -0
  89. package/dist/api/proto/oauth.d.ts +55 -0
  90. package/dist/api/proto/oauth.js +379 -0
  91. package/dist/api/proto/storage.d.ts +80 -0
  92. package/dist/api/proto/storage.js +804 -0
  93. package/dist/api/proto/ui.d.ts +186 -0
  94. package/dist/api/proto/ui.js +1993 -0
  95. package/dist/api/toast.d.ts +168 -0
  96. package/dist/api/toast.js +152 -0
  97. package/dist/api/utils.d.ts +15 -0
  98. package/dist/api/utils.js +64 -0
  99. package/dist/commands/build/index.d.ts +11 -0
  100. package/dist/commands/build/index.js +123 -0
  101. package/dist/commands/develop/index.d.ts +10 -0
  102. package/dist/commands/develop/index.js +193 -0
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.js +17 -0
  105. package/dist/schemas/manifest.d.ts +75 -0
  106. package/dist/schemas/manifest.js +4 -0
  107. package/dist/utils/logger.d.ts +13 -0
  108. package/dist/utils/logger.js +38 -0
  109. package/dist/utils/utils.d.ts +2 -0
  110. package/dist/utils/utils.js +19 -0
  111. package/dist/utils/vicinae.d.ts +12 -0
  112. package/dist/utils/vicinae.js +33 -0
  113. package/package.json +73 -0
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const core_1 = require("@oclif/core");
40
+ const chokidar = __importStar(require("chokidar"));
41
+ const esbuild = __importStar(require("esbuild"));
42
+ const node_child_process_1 = require("node:child_process");
43
+ const node_fs_1 = require("node:fs");
44
+ const promises_1 = require("node:fs/promises");
45
+ const node_path_1 = require("node:path");
46
+ const logger_js_1 = require("../../utils/logger.js");
47
+ const utils_js_1 = require("../../utils/utils.js");
48
+ const vicinae_js_1 = require("../../utils/vicinae.js");
49
+ const manifest_js_1 = __importDefault(require("../../schemas/manifest.js"));
50
+ class Develop extends core_1.Command {
51
+ static args = {};
52
+ static description = "Start an extension development session";
53
+ static examples = [
54
+ `<%= config.bin %> <%= command.id %> --target /path/to/extension`,
55
+ ];
56
+ static flags = {
57
+ target: core_1.Flags.string({
58
+ aliases: ["input"],
59
+ char: "i",
60
+ default: process.cwd(),
61
+ defaultHelp: "The current working directory",
62
+ description: "Path to the extension directory",
63
+ required: false,
64
+ }),
65
+ };
66
+ async run() {
67
+ const { flags } = await this.parse(Develop);
68
+ const logger = new logger_js_1.Logger();
69
+ const pkgPath = (0, node_path_1.join)(flags.target, "package.json");
70
+ if (!(0, node_fs_1.existsSync)(pkgPath)) {
71
+ logger.logError(`No package.json found at ${pkgPath}. Does this location point to a valid extension repository?`);
72
+ process.exit(1);
73
+ }
74
+ const json = JSON.parse((0, node_fs_1.readFileSync)(pkgPath, 'utf8'));
75
+ const e = manifest_js_1.default.safeParse(json);
76
+ if (e.error) {
77
+ logger.logError(`${pkgPath} is not a valid extension manifest: ${e.error}`);
78
+ process.exit(1);
79
+ }
80
+ const manifest = e.data;
81
+ const vicinae = new vicinae_js_1.VicinaeClient();
82
+ const typeCheck = async () => {
83
+ const spawned = (0, node_child_process_1.spawn)("npx", ["tsc", "--noEmit"]);
84
+ let stderr = Buffer.from("");
85
+ return new Promise((resolve) => {
86
+ spawned.stderr.on("data", (buf) => {
87
+ stderr = Buffer.concat([stderr, buf]);
88
+ });
89
+ spawned.on("exit", (status) => resolve({ error: stderr.toString(), ok: status === 0 }));
90
+ });
91
+ };
92
+ const build = async (outDir) => {
93
+ logger.logInfo("Started type checking in background thread");
94
+ typeCheck().then(({ error, ok }) => {
95
+ if (!ok) {
96
+ logger.logInfo(`Type checking error: ${error}`);
97
+ }
98
+ logger.logInfo("Done type checking");
99
+ });
100
+ const entryPoints = manifest.commands.map((cmd) => (0, node_path_1.join)("src", `${cmd.name}.tsx`));
101
+ logger.logInfo(`entrypoints [${entryPoints.join(", ")}]`);
102
+ const promises = manifest.commands.map((cmd) => {
103
+ const source = (0, node_path_1.join)(process.cwd(), "src", `${cmd.name}.tsx`);
104
+ return esbuild.build({
105
+ bundle: true,
106
+ entryPoints: [source],
107
+ external: ["react", "@vicinae/api"],
108
+ format: "cjs",
109
+ outfile: (0, node_path_1.join)(outDir, `${cmd.name}.js`),
110
+ platform: "node",
111
+ });
112
+ });
113
+ await Promise.all(promises);
114
+ const targetPkg = (0, node_path_1.join)(outDir, "package.json");
115
+ const targetAssets = (0, node_path_1.join)(outDir, "assets");
116
+ (0, node_fs_1.cpSync)("package.json", targetPkg, { force: true });
117
+ if ((0, node_fs_1.existsSync)("assets")) {
118
+ (0, node_fs_1.cpSync)("assets", targetAssets, { force: true, recursive: true });
119
+ }
120
+ else {
121
+ (0, node_fs_1.mkdirSync)(targetAssets, { recursive: true });
122
+ }
123
+ };
124
+ const pingError = vicinae.ping();
125
+ if (pingError) {
126
+ console.error(`Failed to ping vicinae\n`, pingError.message);
127
+ return;
128
+ }
129
+ process.chdir(flags.target);
130
+ const dataDir = (0, utils_js_1.extensionDataDir)();
131
+ const id = `${manifest.name}.dev`;
132
+ const extensionDir = (0, node_path_1.join)(dataDir, id);
133
+ const logFile = (0, node_path_1.join)(extensionDir, "dev.log");
134
+ const pidFile = (0, node_path_1.join)(extensionDir, "cli.pid");
135
+ (0, node_fs_1.mkdirSync)(extensionDir, { recursive: true });
136
+ await build(extensionDir);
137
+ logger.logReady("built extension successfully");
138
+ (0, node_fs_1.writeFileSync)(pidFile, `${process.pid}`);
139
+ (0, node_fs_1.writeFileSync)(logFile, "");
140
+ process.on("SIGINT", () => {
141
+ logger.logInfo("Shutting down...");
142
+ vicinae.stopDevSession(id);
143
+ throw new Error(`Development session interrupted`);
144
+ });
145
+ const error = vicinae.startDevSession(id);
146
+ if (error) {
147
+ console.error(`Failed to invoke vicinae`, error);
148
+ return;
149
+ }
150
+ chokidar
151
+ .watch(["src", "package.json", "assets"], {
152
+ awaitWriteFinish: { pollInterval: 100, stabilityThreshold: 100 },
153
+ ignoreInitial: true,
154
+ })
155
+ .on("all", (_, path) => {
156
+ logger.logEvent(`changed file ${path}:`);
157
+ try {
158
+ build(extensionDir);
159
+ logger.logReady("built extension successfully");
160
+ vicinae.refreshDevSession(id);
161
+ }
162
+ catch (error) {
163
+ logger.logEvent(`Failed to build extension: ${error}`);
164
+ }
165
+ });
166
+ const logFiles = new Map();
167
+ chokidar.watch(logFile).on("all", async (_, path) => {
168
+ const stats = await (0, promises_1.stat)(path);
169
+ if (!stats.isFile())
170
+ return;
171
+ if (!logFiles.has(path)) {
172
+ logger.logInfo(`Monitoring new log file at ${path}`);
173
+ logFiles.set(path, { cursor: 0, path });
174
+ }
175
+ const info = logFiles.get(path);
176
+ if (info.cursor > stats.size) {
177
+ info.cursor = 0;
178
+ }
179
+ if (stats.size === info.cursor)
180
+ return;
181
+ const handle = await (0, promises_1.open)(path, "r");
182
+ const buffer = Buffer.alloc(stats.size - info.cursor);
183
+ (0, node_fs_1.read)(handle.fd, buffer, 0, buffer.length, info.cursor, (error, nRead) => {
184
+ if (error)
185
+ return;
186
+ info.cursor += nRead;
187
+ logger.logTimestamp(buffer.toString());
188
+ handle.close();
189
+ });
190
+ });
191
+ }
192
+ }
193
+ exports.default = Develop;
@@ -0,0 +1 @@
1
+ export * from './api';
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./api"), exports);
@@ -0,0 +1,75 @@
1
+ import { z } from "zod";
2
+ declare const _default: z.ZodObject<{
3
+ icon: z.ZodString;
4
+ name: z.ZodString;
5
+ debug: z.ZodOptional<z.ZodObject<{
6
+ reloadShortcut: z.ZodOptional<z.ZodObject<{
7
+ key: z.ZodString;
8
+ modifiers: z.ZodArray<z.ZodEnum<{
9
+ shift: "shift";
10
+ command: "command";
11
+ option: "option";
12
+ control: "control";
13
+ }>>;
14
+ }, z.core.$strict>>;
15
+ }, z.core.$strip>>;
16
+ owner: z.ZodOptional<z.ZodString>;
17
+ title: z.ZodString;
18
+ access: z.ZodOptional<z.ZodEnum<{
19
+ public: "public";
20
+ private: "private";
21
+ }>>;
22
+ author: z.ZodString;
23
+ license: z.ZodLiteral<"MIT">;
24
+ platforms: z.ZodOptional<z.ZodArray<z.ZodEnum<{
25
+ macOS: "macOS";
26
+ Windows: "Windows";
27
+ }>>>;
28
+ commands: z.ZodArray<z.ZodObject<{
29
+ icon: z.ZodOptional<z.ZodString>;
30
+ mode: z.ZodEnum<{
31
+ "menu-bar": "menu-bar";
32
+ "no-view": "no-view";
33
+ view: "view";
34
+ }>;
35
+ name: z.ZodString;
36
+ title: z.ZodString;
37
+ keywords: z.ZodOptional<z.ZodAny>;
38
+ subtitle: z.ZodOptional<z.ZodString>;
39
+ description: z.ZodString;
40
+ interval: z.ZodOptional<z.ZodString>;
41
+ preferences: z.ZodOptional<z.ZodAny>;
42
+ arguments: z.ZodOptional<z.ZodAny>;
43
+ disabledByDefault: z.ZodOptional<z.ZodBoolean>;
44
+ }, z.core.$catchall<z.ZodAny>>>;
45
+ tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
46
+ icon: z.ZodOptional<z.ZodString>;
47
+ name: z.ZodString;
48
+ title: z.ZodString;
49
+ keywords: z.ZodOptional<z.ZodAny>;
50
+ description: z.ZodString;
51
+ functionalities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
52
+ "AI attachment provider": "AI attachment provider";
53
+ "AI tool": "AI tool";
54
+ }>>>;
55
+ preferences: z.ZodOptional<z.ZodAny>;
56
+ }, z.core.$catchall<z.ZodAny>>>>;
57
+ ai: z.ZodOptional<z.ZodObject<{
58
+ instructions: z.ZodOptional<z.ZodString>;
59
+ evals: z.ZodOptional<z.ZodArray<z.ZodObject<{
60
+ input: z.ZodString;
61
+ usedAsExample: z.ZodOptional<z.ZodBoolean>;
62
+ }, z.core.$strip>>>;
63
+ }, z.core.$strip>>;
64
+ keywords: z.ZodOptional<z.ZodAny>;
65
+ description: z.ZodString;
66
+ preferences: z.ZodOptional<z.ZodAny>;
67
+ categories: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
+ contributors: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ pastContributors: z.ZodOptional<z.ZodArray<z.ZodString>>;
70
+ dependencies: z.ZodObject<{
71
+ "@raycast/api": z.ZodOptional<z.ZodString>;
72
+ }, z.core.$strip>;
73
+ external: z.ZodOptional<z.ZodArray<z.ZodString>>;
74
+ }, z.core.$strip>;
75
+ export default _default;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const zod_1 = require("zod");
4
+ exports.default = zod_1.z.object({ "icon": zod_1.z.string().regex(new RegExp("^[^\\s]+(?:[ ]*[^\\s]+)*$")).describe("A 512x512 icon representing the extension. It will be displayed in the Store and in Preferences. If any of the extension's commands doesn't have an icon, it will 'inherit' the extension's icon. Please note that light and dark themes are supported; just append '@dark' to the filename for the dark theme and the correct icon will be picked at run-time. For example, set for this property 'icon.png' and put in the assets folder the 'icon.png' and 'icon@dark.png' files."), "name": zod_1.z.string().regex(new RegExp("^(@workaround/)?[a-z0-9-~][a-z0-9-_~]*$")).min(3).max(255).describe("The slugged extension's name used internally as identifier and in the store as part of the URL."), "debug": zod_1.z.object({ "reloadShortcut": zod_1.z.object({ "key": zod_1.z.string().min(1).max(2).describe("The keyboard key pressed with the modifier to trigger an action (e.g. ⌘ + B)"), "modifiers": zod_1.z.array(zod_1.z.enum(["command", "option", "control", "shift"])).min(1).max(4).describe("Such as the command modifier (⌘), option modifier (⌥), control modifier (⌃), or shift modifier (⇧).") }).strict().describe("Keyboard shortcut used to refresh/reload a command while the Vicinae window is focused.").optional() }).describe("Compilation and run-time options to improve development experience.").optional(), "owner": zod_1.z.string().regex(new RegExp("^[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*$")).min(2).max(75).describe("User ultimately responsible for the extension. The extension's store URL is composed of the owner username and the extension's name.").optional(), "title": zod_1.z.string().regex(new RegExp("^[^\\s]+(?: [^\\s]+)*$")).min(2).max(255).describe("The extension title will be displayed in the Store and in Preferences."), "access": zod_1.z.enum(["public", "private"]).describe("Public extensions are downloadable by anybody, while private extensions can only be downloaded by a member of a given organization.").optional(), "author": zod_1.z.string().regex(new RegExp("^[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*$")).min(2).max(75).describe("User currently contributing the most to the extension."), "license": zod_1.z.literal("MIT").describe("Currently only MIT is accepted, although more licenses will probably be available in the future."), "platforms": zod_1.z.array(zod_1.z.enum(["macOS", "Windows"])).min(1).describe("Currently only `macOS` and `Windows` are accepted. If not present, the extension is assumed to be available on all platforms.").optional(), "commands": zod_1.z.array(zod_1.z.object({ "icon": zod_1.z.string().regex(new RegExp("^[^\\s]+(?:[ ]*[^\\s]+)*$")).describe("A 512x512 icon representing the command. It will be displayed in Preferences and Vicinae root search. If a command doesn't have an icon, it will 'inherit' the extension's icon. Please note that light and dark themes are supported; just append '@dark' or '@light' to the icons name and the correct icon will be picked at run-time. For example, write for this property 'icon.png' and have in the assets folder the 'icon@light.png' and 'icon@dark.png' assets.").optional(), "mode": zod_1.z.enum(["view", "no-view", "menu-bar"]).describe("A value of 'view' indicates that the command will show a main view when performed. 'no-view' means that the command does not push a view to the main navigation stack in Vicinae. The latter is handy for directly opening URL or other API functionality that doesn't require a user interface. 'menu-bar' renders an extra item in the macOS system menu bar at the top of the screen."), "name": zod_1.z.string().regex(new RegExp("^[a-z0-9-~][a-zA-Z0-9-._~]*$")).min(2).max(255).describe("The name directly maps to the entry point file for the command. So a command named 'index' would map to 'src/index.ts' (or any other supported TypeScript or JavaScript file extension such as .tsx, .js, .jsx)."), "title": zod_1.z.string().regex(new RegExp("^[^\\s]+(?: [^\\s]+)*$")).min(2).max(255).describe("The command title will be displayed in the Store, Preferences, and in Vicinae's root search."), "keywords": zod_1.z.any().optional(), "subtitle": zod_1.z.string().regex(new RegExp("^[^\\s]+(?: [^\\s]+)*$")).min(2).max(255).describe("The subtitle (if any) will be displayed next to the command name in the root search. It helps user differentiate potentially similar commands. For example, a Google Suite extension may define 2 commands titled 'Create Document'. To differentiate them, one of the subtitle can be 'Google Docs' while the other can be 'Google Sheets'.").optional(), "description": zod_1.z.string().regex(new RegExp("^[^\\s]+(\\s+[^\\s]+)*$")).min(0).max(2048).describe("It helps users understand what the command does. It will be displayed in the Store and in Preferences."), "interval": zod_1.z.string().regex(new RegExp("^(\\d+)(s|m|h|d)$")).describe("The value specifies that a no-view or menu-bar command should be launched in the background every X seconds (s), minutes (m), hours (h) or days (d). Examples: 90s, 1m, 12h, 1d. The minimum value is 10 seconds (10s).").optional(), "preferences": zod_1.z.any().describe("Commands can optionally contribute preferences that are shown in Vicinae Preferences > Extensions when selecting the command. You can use preferences for configuration values and passwords or personal access tokens. Commands automatically \"inherit\" extension preferences and can also override entries with the same `name`.").optional(), "arguments": zod_1.z.any().describe("An optional array of arguments that are requested from user when the command is called").optional(), "disabledByDefault": zod_1.z.boolean().describe("Defaults to `false`").optional() }).catchall(zod_1.z.any())).min(1).max(100).describe("List of all commands vended by this extensions. An extension must contain at least one command."), "tools": zod_1.z.array(zod_1.z.object({ "icon": zod_1.z.string().regex(new RegExp("^[^\\s]+(?:[ ]*[^\\s]+)*$")).describe("A 512x512 icon representing the tool. It will be displayed in various places across Vicinae. If a tool doesn't have an icon, it will 'inherit' the extension's icon. Please note that light and dark themes are supported; just append '@dark' or '@light' to the icons name and the correct icon will be picked at run-time. For example, write for this property 'icon.png' and have in the assets folder the 'icon@light.png' and 'icon@dark.png' assets.").optional(), "name": zod_1.z.string().regex(new RegExp("^[a-z0-9-][a-zA-Z0-9-_]*$")).min(2).max(64).describe("The name directly maps to the entry point file for the tool. So a tool named 'index' would map to 'src/tools/index.ts' (or any other supported TypeScript or JavaScript file extension such as .tsx, .js, .jsx)."), "title": zod_1.z.string().regex(new RegExp("^[^\\s]+(?: [^\\s]+)*$")).min(2).max(255).describe("The tool title will be displayed in the Store, Preferences, and any other places the tool might be referenced in the Vicinae UI."), "keywords": zod_1.z.any().optional(), "description": zod_1.z.string().regex(new RegExp("^[^\\s]+(\\s+[^\\s]+)*$")).min(12).max(2048).describe("It helps users (and other actors like AI) understand what the tool does. It will be displayed in the Store and in Preferences."), "functionalities": zod_1.z.array(zod_1.z.enum(["AI attachment provider", "AI tool"])).describe("Limits the tool to the specified functionalities. If not specified, the tool can be used in any context (if it matches the requirements for each of them).").optional(), "preferences": zod_1.z.any().describe("Tools can optionally contribute preferences that are shown in Vicinae Preferences > Extensions when selecting the AI Extension item. You can use preferences for configuration values and passwords or personal access tokens. Tools automatically \"inherit\" extension preferences and can also override entries with the same `name`.").optional() }).catchall(zod_1.z.any())).min(0).max(100).describe("List of all tools that the AI can use to interact with this extension.").optional(), "ai": zod_1.z.object({ "instructions": zod_1.z.string().describe("Additional system instructions added when the tools are used in AI").optional(), "evals": zod_1.z.array(zod_1.z.object({ "input": zod_1.z.string().describe("The prompt to evaluate"), "usedAsExample": zod_1.z.boolean().describe("Whether the eval can be used as an example in Vicinae (default `true`)").optional() })).describe("List of tests to evaluate the reliability of the tools when used in AI").optional() }).describe("Additional information related to the AI capabilities of the extension").optional(), "keywords": zod_1.z.any().optional(), "description": zod_1.z.string().regex(new RegExp("^[^\\s]+(\\s+[^\\s]+)*$")).min(16).max(2048).describe("It helps users understand what the extension does. It will be displayed in the Store and in Preferences."), "preferences": zod_1.z.any().describe("Extensions can contribute preferences that are shown in Vicinae Preferences > Extensions. You can use preferences for configuration values and passwords or personal access tokens.").optional(), "categories": zod_1.z.array(zod_1.z.string()).optional(), "contributors": zod_1.z.array(zod_1.z.string().regex(new RegExp("^[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*$")).min(2).max(75)).min(0).describe("Users who have meaningfully contributed to the extension's commands.").optional(), "pastContributors": zod_1.z.array(zod_1.z.string().regex(new RegExp("^[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*$")).min(2).max(75)).min(0).describe("Users who have meaningfully contributed to the extension's commands but do not maintain it anymore.").optional(), "dependencies": zod_1.z.object({ "@raycast/api": zod_1.z.string().describe("The Vicinae API version used by this extension.").optional() }).describe("Source dependencies following the npm package.json dependency format."), "external": zod_1.z.array(zod_1.z.string()).describe("An Array of package or file names that should be excluded from the build. The package will not be bundled, but the import is preserved and will be evaluated at runtime.").optional() });
@@ -0,0 +1,13 @@
1
+ export declare class Logger {
2
+ prefixes: {
3
+ error: string;
4
+ event: string;
5
+ info: string;
6
+ ready: string;
7
+ };
8
+ logError(message: string): void;
9
+ logEvent(message: string): void;
10
+ logInfo(message: string): void;
11
+ logReady(message: string): void;
12
+ logTimestamp(s: string): void;
13
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Logger = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ class Logger {
9
+ prefixes = {
10
+ error: `${chalk_1.default.red("error")}${chalk_1.default.reset()}`,
11
+ event: `${chalk_1.default.magenta("event")}${chalk_1.default.reset()}`,
12
+ info: `${chalk_1.default.blue("info")}${chalk_1.default.reset()}`,
13
+ ready: `${chalk_1.default.green("ready")}${chalk_1.default.reset()}`,
14
+ };
15
+ logError(message) {
16
+ console.log(`${this.prefixes.error.padEnd(15)} - ${message}`);
17
+ }
18
+ logEvent(message) {
19
+ console.log(`${this.prefixes.event.padEnd(15)} - ${message}`);
20
+ }
21
+ logInfo(message) {
22
+ console.log(`${this.prefixes.info.padEnd(15)} - ${message}`);
23
+ }
24
+ logReady(message) {
25
+ console.log(`${this.prefixes.ready.padEnd(15)} - ${message}`);
26
+ }
27
+ logTimestamp(s) {
28
+ const ts = new Date().toJSON();
29
+ const lines = s.split("\n");
30
+ for (let i = 0; i !== lines.length; ++i) {
31
+ const line = lines[i];
32
+ if (i === lines.length - 1 && line.length === 0)
33
+ continue;
34
+ console.log(`${chalk_1.default.gray(ts.padEnd(20))}${chalk_1.default.reset()} - ${line}`);
35
+ }
36
+ }
37
+ }
38
+ exports.Logger = Logger;
@@ -0,0 +1,2 @@
1
+ export declare const dataDir: () => string;
2
+ export declare const extensionDataDir: () => string;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extensionDataDir = exports.dataDir = void 0;
4
+ const path_1 = require("path");
5
+ const os_1 = require("os");
6
+ const platformDataDir = () => {
7
+ const platform = process.platform;
8
+ if (platform === "linux")
9
+ return process.env.XDG_DATA_HOME || (0, path_1.join)((0, os_1.homedir)(), ".local", "share");
10
+ if (platform === "darwin")
11
+ return (0, path_1.join)((0, os_1.homedir)(), "Library", "Application Support");
12
+ if (platform === "win32")
13
+ return process.env.APPDATA || (0, path_1.join)((0, os_1.homedir)(), "AppData", "Roaming");
14
+ return (0, path_1.join)((0, os_1.homedir)(), ".data");
15
+ };
16
+ const dataDir = () => (0, path_1.join)(platformDataDir(), "vicinae");
17
+ exports.dataDir = dataDir;
18
+ const extensionDataDir = () => (0, path_1.join)((0, exports.dataDir)(), "extensions");
19
+ exports.extensionDataDir = extensionDataDir;
@@ -0,0 +1,12 @@
1
+ export type VicinaeClientOptions = {
2
+ binaryPath: string;
3
+ };
4
+ export declare class VicinaeClient {
5
+ private readonly options;
6
+ constructor(options?: VicinaeClientOptions);
7
+ ping(): Error | null;
8
+ refreshDevSession(extensionId: string): Error | null;
9
+ startDevSession(extensionId: string): Error | null;
10
+ stopDevSession(extensionId: string): Error | null;
11
+ private invoke;
12
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VicinaeClient = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ class VicinaeClient {
6
+ options;
7
+ constructor(options = { binaryPath: "vicinae" }) {
8
+ this.options = options;
9
+ }
10
+ ping() {
11
+ return this.invoke("/ping");
12
+ }
13
+ refreshDevSession(extensionId) {
14
+ return this.invoke(`/api/extensions/develop/refresh?id=${extensionId}`);
15
+ }
16
+ startDevSession(extensionId) {
17
+ return this.invoke(`/api/extensions/develop/start?id=${extensionId}`);
18
+ }
19
+ stopDevSession(extensionId) {
20
+ return this.invoke(`/api/extensions/develop/stop?id=${extensionId}`);
21
+ }
22
+ invoke(endpoint) {
23
+ if (endpoint.startsWith("/")) {
24
+ endpoint = endpoint.slice(1);
25
+ }
26
+ const url = `vicinae://${endpoint}`;
27
+ const result = (0, node_child_process_1.spawnSync)(this.options.binaryPath, [url]);
28
+ if (result.error)
29
+ return result.error;
30
+ return result.status === 0 ? null : new Error(result.stderr.toString());
31
+ }
32
+ }
33
+ exports.VicinaeClient = VicinaeClient;
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@vicinae/api",
3
+ "version": "0.3.0",
4
+ "description": "TypeScript SDK to build Vicinae extensions",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "build": "tsc --outDir dist",
8
+ "pack": "npm run build && npm pack"
9
+ },
10
+ "bin": {
11
+ "vici": "./bin/run.js"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "types"
16
+ ],
17
+ "keywords": [],
18
+ "author": "",
19
+ "license": "ISC",
20
+ "types": [
21
+ "./dist/index.d.ts"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "main": "dist/index.js",
27
+ "dependencies": {
28
+ "@jgoz/esbuild-plugin-typecheck": "^4.0.3",
29
+ "@types/node": "^22.10.1",
30
+ "chokidar": "^4.0.3",
31
+ "esbuild": "^0.25.2",
32
+ "ts-proto": "^2.7.5",
33
+ "@types/react": "^18.1.0",
34
+ "react": "^18.1.0",
35
+ "@oclif/core": "^4",
36
+ "@oclif/plugin-help": "^6",
37
+ "@oclif/plugin-plugins": "^5",
38
+ "chalk": "^5.6.0",
39
+ "zod": "^4.0.17"
40
+ },
41
+ "devDependencies": {
42
+ "@eslint/compat": "^1",
43
+ "@oclif/prettier-config": "^0.2.1",
44
+ "@oclif/test": "^4",
45
+ "@types/chai": "^4",
46
+ "@types/mocha": "^10",
47
+ "@types/node": "^18",
48
+ "chai": "^4",
49
+ "eslint": "^9",
50
+ "eslint-config-oclif": "^6",
51
+ "eslint-config-prettier": "^10",
52
+ "mocha": "^10",
53
+ "oclif": "^4",
54
+ "shx": "^0.3.3",
55
+ "ts-node": "^10",
56
+ "typescript": "^5"
57
+ },
58
+ "oclif": {
59
+ "bin": "vici",
60
+ "dirname": "vici",
61
+ "commands": "./dist/commands",
62
+ "plugins": [
63
+ "@oclif/plugin-help"
64
+ ],
65
+ "topicSeparator": " ",
66
+ "topics": {
67
+ "hello": {
68
+ "description": "Say hello to the world and others"
69
+ }
70
+ }
71
+ },
72
+ "repository": "vicinaehq/vici"
73
+ }