diff --git a/.vitepress/config.mts b/.vitepress/config.mts index fb25d95..a73f422 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -6,7 +6,7 @@ import type { DefaultTheme } from "vitepress"; import { clientSdkNavbar, pluginsNavbar, - quickstartNavbar, + introductionNavbar, } from "./navbars"; import { clientSdkSidebars, pluginsSidebars } from "./sidebars"; @@ -55,9 +55,9 @@ export default defineConfig({ component: "NavItem", props: { text: "Get Started", - link: "/quickstart/", - activeMatch: "^/quickstart(/|$)", - items: quickstartNavbar, + link: "/introduction/", + activeMatch: "^/introduction(/|$)", + items: introductionNavbar, }, }, { @@ -89,6 +89,7 @@ export default defineConfig({ ] satisfies DefaultTheme.NavItem[], sidebar: { + "/plugins/quickstart/": pluginsSidebars.quickstartSidebar, "/plugins/guides/": pluginsSidebars.guidesSidebar, "/plugins/tutorials/": pluginsSidebars.tutorialsSidebar, "/plugins/reference/": pluginsSidebars.referenceSidebar, diff --git a/.vitepress/navbars/index.ts b/.vitepress/navbars/index.ts index 7fc6784..f59f1dc 100644 --- a/.vitepress/navbars/index.ts +++ b/.vitepress/navbars/index.ts @@ -1,3 +1,8 @@ -export * from "./plugins"; -export * from "./client-sdk"; -export * from "./quickstart"; \ No newline at end of file +import type { DefaultTheme } from "vitepress"; + +export { pluginsNavbar } from "./plugins"; +export { clientSdkNavbar } from "./client-sdk"; + +export const introductionNavbar: DefaultTheme.NavItemWithLink[] = [ + { text: "Get Started", link: "/introduction/" }, +]; diff --git a/.vitepress/navbars/plugins.ts b/.vitepress/navbars/plugins.ts index 6b79f57..a87e4e1 100644 --- a/.vitepress/navbars/plugins.ts +++ b/.vitepress/navbars/plugins.ts @@ -1,6 +1,7 @@ import type { DefaultTheme } from "vitepress"; export const pluginsNavbar: DefaultTheme.NavItemWithLink[] = [ + { text: "Creating Your First Plugin", link: "/plugins/quickstart/" }, { text: "Guides", link: "/plugins/guides/" }, { text: "Tutorials", link: "/plugins/tutorials/" }, { text: "Reference", link: "/plugins/reference/" }, diff --git a/.vitepress/navbars/quickstart.ts b/.vitepress/navbars/quickstart.ts deleted file mode 100644 index 2831b2d..0000000 --- a/.vitepress/navbars/quickstart.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { DefaultTheme } from "vitepress"; - -export const quickstartNavbar: DefaultTheme.NavItemWithLink[] = [ - { text: "Get Started", link: "/quickstart/" }, -]; \ No newline at end of file diff --git a/.vitepress/sidebars/plugins/guides.ts b/.vitepress/sidebars/plugins/guides.ts index 3314a42..66be3b7 100644 --- a/.vitepress/sidebars/plugins/guides.ts +++ b/.vitepress/sidebars/plugins/guides.ts @@ -1,35 +1,6 @@ import type { DefaultTheme } from "vitepress"; export const guidesSidebar: DefaultTheme.SidebarItem[] = [ - { - text: "Getting Started", - items: [ - { - text: "Getting Started", - link: "/plugins/guides/", - }, - { - text: "Configure Package", - link: "/plugins/guides/config", - }, - { - text: "AI Assisted Coding", - link: "/plugins/guides/vibe_coding", - }, - { - text: "Set Up Repository", - link: "/plugins/guides/repository", - }, - { - text: "Submit to Store", - link: "/plugins/guides/store", - }, - { - text: "Contributing", - link: "/plugins/guides/documentation", - }, - ], - }, { text: "Frontend Guides", items: [ diff --git a/.vitepress/sidebars/plugins/index.ts b/.vitepress/sidebars/plugins/index.ts index 0fd7bac..b82c5ee 100644 --- a/.vitepress/sidebars/plugins/index.ts +++ b/.vitepress/sidebars/plugins/index.ts @@ -2,3 +2,4 @@ export * from "./guides"; export * from "./tutorials"; export * from "./reference"; export * from "./concepts"; +export * from "./quickstart"; diff --git a/.vitepress/sidebars/plugins/quickstart.ts b/.vitepress/sidebars/plugins/quickstart.ts new file mode 100644 index 0000000..b6db792 --- /dev/null +++ b/.vitepress/sidebars/plugins/quickstart.ts @@ -0,0 +1,49 @@ +import type { DefaultTheme } from "vitepress"; + +export const quickstartSidebar: DefaultTheme.SidebarItem[] = [ + { + text: "Creating Your First Plugin", + items: [ + { + text: "Introduction", + link: "/plugins/quickstart/", + }, + { + text: "Configuring a Plugin", + link: "/plugins/quickstart/config", + }, + { + text: "Building a Plugin", + link: "/plugins/quickstart/build", + }, + { + text: "Frontend Component Basics", + link: "/plugins/quickstart/frontend", + }, + { + text: "Backend Component Basics", + link: "/plugins/quickstart/backend", + }, + { + text: "Hot Reload", + link: "/plugins/quickstart/reload", + }, + { + text: "AI Assisted Coding", + link: "/plugins/quickstart/vibe_coding", + }, + { + text: "Set Up Repository", + link: "/plugins/quickstart/repository", + }, + { + text: "Submit to Store", + link: "/plugins/quickstart/store", + }, + { + text: "Contributing", + link: "/plugins/quickstart/documentation", + }, + ], + }, +]; diff --git a/src/_images/config_file.png b/src/_images/config_file.png new file mode 100644 index 0000000..3b29bff Binary files /dev/null and b/src/_images/config_file.png differ diff --git a/src/_images/config_metadata.png b/src/_images/config_metadata.png new file mode 100644 index 0000000..1f7558a Binary files /dev/null and b/src/_images/config_metadata.png differ diff --git a/src/_images/confirm_uninstall.png b/src/_images/confirm_uninstall.png new file mode 100644 index 0000000..bd5d817 Binary files /dev/null and b/src/_images/confirm_uninstall.png differ diff --git a/src/_images/install_package_button.png b/src/_images/install_package_button.png new file mode 100644 index 0000000..819a475 Binary files /dev/null and b/src/_images/install_package_button.png differ diff --git a/src/_images/installed_plugin.png b/src/_images/installed_plugin.png new file mode 100644 index 0000000..3b0f384 Binary files /dev/null and b/src/_images/installed_plugin.png differ diff --git a/src/_images/installed_plugins.png b/src/_images/installed_plugins.png new file mode 100644 index 0000000..e84c487 Binary files /dev/null and b/src/_images/installed_plugins.png differ diff --git a/src/_images/intercept_page.png b/src/_images/intercept_page.png new file mode 100644 index 0000000..1bda83d Binary files /dev/null and b/src/_images/intercept_page.png differ diff --git a/src/_images/name_prompt.png b/src/_images/name_prompt.png new file mode 100644 index 0000000..33fd56e Binary files /dev/null and b/src/_images/name_prompt.png differ diff --git a/src/_images/plugin_build.png b/src/_images/plugin_build.png new file mode 100644 index 0000000..2975824 Binary files /dev/null and b/src/_images/plugin_build.png differ diff --git a/src/_images/plugin_installed_error.png b/src/_images/plugin_installed_error.png new file mode 100644 index 0000000..f4b61fa Binary files /dev/null and b/src/_images/plugin_installed_error.png differ diff --git a/src/_images/plugin_metadata_components.png b/src/_images/plugin_metadata_components.png new file mode 100644 index 0000000..e6fcb02 Binary files /dev/null and b/src/_images/plugin_metadata_components.png differ diff --git a/src/_images/plugin_metadata_expanded.png b/src/_images/plugin_metadata_expanded.png new file mode 100644 index 0000000..5feb565 Binary files /dev/null and b/src/_images/plugin_metadata_expanded.png differ diff --git a/src/_images/plugin_metadata_row.png b/src/_images/plugin_metadata_row.png new file mode 100644 index 0000000..06f0b86 Binary files /dev/null and b/src/_images/plugin_metadata_row.png differ diff --git a/src/_images/plugin_package_file.png b/src/_images/plugin_package_file.png new file mode 100644 index 0000000..cf032db Binary files /dev/null and b/src/_images/plugin_package_file.png differ diff --git a/src/_images/plugin_package_file_select.png b/src/_images/plugin_package_file_select.png new file mode 100644 index 0000000..2e2c7c9 Binary files /dev/null and b/src/_images/plugin_package_file_select.png differ diff --git a/src/_images/plugin_template_button.png b/src/_images/plugin_template_button.png new file mode 100644 index 0000000..b5eeca7 Binary files /dev/null and b/src/_images/plugin_template_button.png differ diff --git a/src/_images/plugin_uninstall.png b/src/_images/plugin_uninstall.png new file mode 100644 index 0000000..0b57a10 Binary files /dev/null and b/src/_images/plugin_uninstall.png differ diff --git a/src/_images/plugins_interface.png b/src/_images/plugins_interface.png new file mode 100644 index 0000000..9ebae9a Binary files /dev/null and b/src/_images/plugins_interface.png differ diff --git a/src/_images/ui_prompt.png b/src/_images/ui_prompt.png new file mode 100644 index 0000000..c59c9ca Binary files /dev/null and b/src/_images/ui_prompt.png differ diff --git a/src/_images/updated_plugin_page.png b/src/_images/updated_plugin_page.png new file mode 100644 index 0000000..3f03db8 Binary files /dev/null and b/src/_images/updated_plugin_page.png differ diff --git a/src/index.md b/src/index.md index fb48ed7..fb1b92b 100644 --- a/src/index.md +++ b/src/index.md @@ -13,7 +13,7 @@ hero: actions: - theme: brand text: Get Started - link: /quickstart + link: /introduction - theme: alt text: Plugins link: /plugins/guides/ diff --git a/src/introduction.md b/src/introduction.md new file mode 100644 index 0000000..22802a0 --- /dev/null +++ b/src/introduction.md @@ -0,0 +1,23 @@ +# Welcome to the Caido Developer Documentation! + +Here, you will find a wealth of information and resources for the [Software Development Kits (SDKs)](https://en.wikipedia.org/wiki/Software_development_kit) offered by Caido. + +## Plugins + +For users looking to customize/extend Caido's functionality, the [@caido/sdk-frontend](/plugins/reference/sdks/frontend/), [@caido/sdk-backend](/plugins/reference/sdks/backend/) kits provide the components and features for creating your own custom plugins. + +::: tip +View the [Creating Your First Plugin](/plugins/quickstart/) documentation to learn how to create your own Caido plugin. +::: + +The [@caido/sdk-workflow](/plugins/reference/sdks/workflow/) kit provides the interface for working with Caido data [using the JavaScript node](https://docs.caido.io/app/guides/workflows_javascript.html) in workflows. + +For both plugins and workflows, a number of [modules](/plugins/reference/modules/) are supported for Caido’s QuickJS JavaScript engine. + +## Client SDK + +The [@caido/sdk-client](/client-sdk/reference/) kit provides an interface for programmatic access to a running Caido instance from external scripts and tools. + +::: tip +View the [Install the SDK](/client-sdk/guides/install.md) guide to get started. +::: \ No newline at end of file diff --git a/src/plugins/quickstart/backend.md b/src/plugins/quickstart/backend.md new file mode 100644 index 0000000..816bd4e --- /dev/null +++ b/src/plugins/quickstart/backend.md @@ -0,0 +1,25 @@ +# Backend Component Basics + +The backend component of a plugin exposes functions that the frontend can call. + +In the Demo Plugin, when the `Generate random string` button is clicked, `onGenerateClick` calls `sdk.backend.generateRandomString(10)`, assigns the returned string to `myVar`, and the read-only `InputText` updates to show that value. + +```ts +import type { DefineAPI, SDK } from "caido:plugin"; + +const generateRandomString = (sdk: SDK, length: number) => { + const randomString = Math.random() + .toString(36) + .substring(2, length + 2); + sdk.console.log(`Generating random string: ${randomString}`); + return randomString; +}; + +export type API = DefineAPI<{ + generateRandomString: typeof generateRandomString; +}>; + +export function init(sdk: SDK) { + sdk.api.register("generateRandomString", generateRandomString); +} +``` diff --git a/src/plugins/quickstart/build.md b/src/plugins/quickstart/build.md new file mode 100644 index 0000000..171d308 --- /dev/null +++ b/src/plugins/quickstart/build.md @@ -0,0 +1,37 @@ +# Building a Plugin + +To build the plugin files into an installable package, enter the following terminal command: + +```bash +pnpm build +``` + +The output will resemble: + +Build output. + +Once the plugin is built, a `plugin_package.zip` file will be created in the `/dist` directory. + +The plugin_package.zip file. + +In Caido, navigate to the **Plugins** interface and click on the `Install Package` button. + +Plugins interface. + +Select the `/demo/dist/plugin_package.zip` file to install the plugin. + +Selecting the plugin_package.zip file. + +A new row will be added to list of installed plugins in the table of the **Installed** tab. + +Installed plugins list. + +The plugin will also appear in the **Plugins** section of the side navigation menu. + +Installed plugins side navigation menu list. + +## What's next? + +You may have noticed that even though the plugin's display name was set to `Demo Plugin` in the `/demo/caido.config.ts` file, it is displayed as ** My Plugin** in the side navigation menu. + +To learn how to fix this mismatch, continue with [Frontend Component Basics](/plugins/quickstart/frontend.md). diff --git a/src/plugins/quickstart/config.md b/src/plugins/quickstart/config.md new file mode 100644 index 0000000..78a5e96 --- /dev/null +++ b/src/plugins/quickstart/config.md @@ -0,0 +1,218 @@ +# Configuring a Plugin + +In the plugin folder, you will see a `caido.config.ts` file. + +Configuration file. + +--- + +Configuration file metadata. + +## id + +The value of the `id` variable is used by Caido as a plugin specific identifier. This means that each plugin's `id` must be a unique value. + +Let's start with changing the value of the `id` variable from `frontend-vue` to `plugin-demo`: + +```ts +const id = "plugin-demo"; +``` + +## General Information + +The `name`, `description`, `version`, and `author` attributes store information that will be displayed in Caido once the plugin is installed: + +```ts +export default defineConfig({ + id, // References the plugin's unique identifier. + name: "Frontend Vue", // The display name. + description: "Plugin template with frontend using VueJS", // Optional description. + version: "0.0.0", // Semantic versioning label. + author: { + name: "Caido Labs Inc.", // Developer name. + email: "dev@caido.io", // Developer contact email address. + url: "https://caido.io", // Developer website. + }, +``` + +--- + +Displayed metadata. + +For this tutorial, change the attributes to match the following: + +```ts + name: "Plugin Demo", + description: "Plugin demo from tutorial.", + version: "0.0.1", + author: { + name: "Me", + email: "me@example.com", + url: "https://example.com", + }, +``` + +## Component Definitions + +::: info +A Caido plugin can consist of either: + +- A backend component +- Or, a backend component combined with a frontend component + +In this tutorial, the plugin includes a frontend component because we entered `y` for the prompt _"Will your plugin package customize the Caido UI?"_: + +UI prompt. +::: + +In the `plugins` array, the backend and frontend plugin components are defined: + +```ts + plugins: [ + { + kind: "backend", // Component type. + id: "backend", // Unique identifier. + root: "packages/backend", // Path to component source code. + }, + { + kind: 'frontend', + id: "frontend", + root: 'packages/frontend', + // Links the components: + backend: { + id: "backend", + }, +``` + +Each component can also include a `name` attribute that stores the component's display name when the plugin's metadata details are expanded: + +Displayed metadata extended. + +Add the `name` attribute to each component and set the values to `Backend Component` and `Frontend Component` respectively: + +```ts + plugins: [ + { + kind: "backend", + id: "backend", + root: "packages/backend", + name: "Backend Component", + }, + { + kind: 'frontend', + id: "frontend", + root: 'packages/frontend', + name: "Frontend Component", + backend: { + id: "backend", + }, +``` + +## Review + +By now, your `caido.config.ts` file should match the following: + +```ts +import { defineConfig } from '@caido-community/dev'; +import vue from '@vitejs/plugin-vue'; +import tailwindcss from "tailwindcss"; +// @ts-expect-error no declared types at this time +import tailwindPrimeui from "tailwindcss-primeui"; +import tailwindCaido from "@caido/tailwindcss"; +import path from "path"; +import prefixwrap from "postcss-prefixwrap"; + +const id = "plugin-demo"; +export default defineConfig({ + id, + name: "Plugin Demo", + description: "Plugin demo from tutorial.", + version: "0.0.1", + author: { + name: "Me", + email: "me@example.com", + url: "https://example.com", + }, + plugins: [ + { + kind: "backend", + id: "backend", + root: "packages/backend", + name: "Backend Component", + }, + { + kind: 'frontend', + id: "frontend", + root: 'packages/frontend', + name: "Frontend Component", + backend: { + id: "backend", + }, + vite: { + plugins: [vue()], + build: { + rollupOptions: { + external: [ + '@caido/frontend-sdk', + "@codemirror/autocomplete", + "@codemirror/commands", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/search", + "@codemirror/state", + "@codemirror/view", + "@lezer/common", + "@lezer/highlight", + "@lezer/lr", + "vue", + + ] + } + }, + resolve: { + alias: [ + { + find: "@", + replacement: path.resolve(__dirname, "packages/frontend/src"), + }, + ], + }, + css: { + postcss: { + plugins: [ + // This plugin wraps the root element in a unique ID + // This is necessary to prevent styling conflicts between plugins + prefixwrap(`#plugin--${id}`), + + tailwindcss({ + corePlugins: { + preflight: false, + }, + content: [ + './packages/frontend/src/**/*.{vue,ts}', + './node_modules/@caido/primevue/dist/primevue.mjs' + ], + // Check the [data-mode="dark"] attribute on the element to determine the mode + // This attribute is set in the Caido core application + darkMode: ["selector", '[data-mode="dark"]'], + plugins: [ + + // This plugin injects the necessary Tailwind classes for PrimeVue components + tailwindPrimeui, + + // This plugin injects the necessary Tailwind classes for the Caido theme + tailwindCaido, + ], + }) + ] + } + } + } + } + ] +}); +``` + +## What's next? + +Once the attributes have been set, continue with [Building a Plugin](/plugins/quickstart/build.md). diff --git a/src/plugins/guides/documentation.md b/src/plugins/quickstart/documentation.md similarity index 100% rename from src/plugins/guides/documentation.md rename to src/plugins/quickstart/documentation.md diff --git a/src/plugins/quickstart/frontend.md b/src/plugins/quickstart/frontend.md new file mode 100644 index 0000000..eb618b5 --- /dev/null +++ b/src/plugins/quickstart/frontend.md @@ -0,0 +1,138 @@ +# Frontend Component Basics + +As mentioned, in this tutorial, the plugin includes a frontend component because we entered `y` for the prompt _"Will your plugin package customize the Caido UI?"_: + +UI prompt. + +The frontend component gives the plugin a user interface in Caido. + +Plugin user interface. + +## Pages + +Each user interface in Caido is referred to as a "page". + +::: tip +Think of the Caido application as a browser window with multiple open tabs for different web pages. But instead of the tabs being listed across the top of the window, they are listed in the side navigation menu. +::: + +To demonstrate this concept, open Caido in a browser window by navigating to [http://127.0.0.1:8080/](http://127.0.0.1:8080/) (_or the custom listening address you have configured_). + +As you select different interfaces, view the changes to the URL in the browser's address bar. For example, selecting the **Intercept** interface presents the [http://127.0.0.1:8080/#/intercept](http://127.0.0.1:8080/#/intercept) page. + +Intercept interface in the browser. + +## /packages/frontend/src/index.ts + +Plugin pages are created via the `/packages/frontend/src/index.ts` file. + +The `sdk.navigation.addPage()` function takes a page name as a parameter and adds the page to Caido: + +```ts + sdk.navigation.addPage("/my-plugin", { + body: root, + }); +``` + +The `sdk.sidebar.registerItem()` function takes a display name as a parameter and links it to the page name: + +```ts + sdk.sidebar.registerItem("My Plugin", "/my-plugin"); +``` + +Open the `/demo/packages/frontend/src/index.ts` file and change the parameter values to match the following: + +```ts + sdk.navigation.addPage("/plugin-demo", { + body: root, + }); + + // Add a sidebar item + sdk.sidebar.registerItem("Plugin Demo", "/plugin-demo"); +``` + +## /packages/frontend/src/views/App.vue + +While the `/packages/frontend/src/index.ts` file creates the plugin page, the `/packages/frontend/src/views/App.vue` file defines the components of the page using: + +- [Vue.js](https://vuejs.org/): A JavaScript framework for building user interfaces as reusable components. Each `.vue` file typically defines the page structure in a `