@gui-chat-plugin/camera 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/dist/core/definition.d.ts +15 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/core.cjs +1 -0
- package/dist/core.js +15 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/style.css +1 -0
- package/dist/vue/CameraCapture.vue.d.ts +9 -0
- package/dist/vue/Preview.vue.d.ts +8 -0
- package/dist/vue/View.vue.d.ts +8 -0
- package/dist/vue/index.d.ts +17 -0
- package/dist/vue.cjs +1 -0
- package/dist/vue.js +224 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @gui-chat-plugin/camera
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@gui-chat-plugin/camera)
|
|
4
|
+
|
|
5
|
+
A camera photo capture plugin for [MulmoChat](https://github.com/receptron/MulmoChat).
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This plugin allows users to take photos using their device's camera. It opens a camera preview modal where users can select their camera (if multiple are available) and capture a photo.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add @gui-chat-plugin/camera
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Vue Implementation (for MulmoChat)
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// In src/tools/index.ts
|
|
23
|
+
import CameraPlugin from "@gui-chat-plugin/camera/vue";
|
|
24
|
+
|
|
25
|
+
const pluginList = [
|
|
26
|
+
// ... other plugins
|
|
27
|
+
CameraPlugin,
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
// In src/main.ts
|
|
31
|
+
import "@gui-chat-plugin/camera/style.css";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Core Only (Framework-agnostic)
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT } from "@gui-chat-plugin/camera";
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Package Exports
|
|
41
|
+
|
|
42
|
+
| Export | Description |
|
|
43
|
+
|--------|-------------|
|
|
44
|
+
| `@gui-chat-plugin/camera` | Core (framework-agnostic) |
|
|
45
|
+
| `@gui-chat-plugin/camera/vue` | Vue implementation |
|
|
46
|
+
| `@gui-chat-plugin/camera/style.css` | Tailwind CSS styles |
|
|
47
|
+
|
|
48
|
+
## Test Prompts
|
|
49
|
+
|
|
50
|
+
1. "Take a photo"
|
|
51
|
+
2. "Open the camera"
|
|
52
|
+
3. "I want to take a selfie"
|
|
53
|
+
4. "Capture an image from my camera"
|
|
54
|
+
|
|
55
|
+
## Development
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
yarn install
|
|
59
|
+
yarn dev # Start dev server
|
|
60
|
+
yarn build # Build
|
|
61
|
+
yarn typecheck # Type check
|
|
62
|
+
yarn lint # Lint
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
MIT
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera Plugin Tool Definition
|
|
3
|
+
*/
|
|
4
|
+
export declare const TOOL_NAME = "takePhoto";
|
|
5
|
+
export declare const TOOL_DEFINITION: {
|
|
6
|
+
type: "function";
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object";
|
|
11
|
+
properties: {};
|
|
12
|
+
required: string[];
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare const SYSTEM_PROMPT = "When the user asks to take a photo, use selfie, or capture an image from the camera, you MUST use the takePhoto API.";
|
package/dist/core.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="takePhoto",t={type:"function",name:e,description:"Take a photo using the device camera.",parameters:{type:"object",properties:{},required:[]}},o=`When the user asks to take a photo, use selfie, or capture an image from the camera, you MUST use the ${e} API.`;exports.SYSTEM_PROMPT=o;exports.TOOL_DEFINITION=t;exports.TOOL_NAME=e;
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const e = "takePhoto", t = {
|
|
2
|
+
type: "function",
|
|
3
|
+
name: e,
|
|
4
|
+
description: "Take a photo using the device camera.",
|
|
5
|
+
parameters: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {},
|
|
8
|
+
required: []
|
|
9
|
+
}
|
|
10
|
+
}, o = `When the user asks to take a photo, use selfie, or capture an image from the camera, you MUST use the ${e} API.`;
|
|
11
|
+
export {
|
|
12
|
+
o as SYSTEM_PROMPT,
|
|
13
|
+
t as TOOL_DEFINITION,
|
|
14
|
+
e as TOOL_NAME
|
|
15
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("./core.cjs");exports.SYSTEM_PROMPT=O.SYSTEM_PROMPT;exports.TOOL_DEFINITION=O.TOOL_DEFINITION;exports.TOOL_NAME=O.TOOL_NAME;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-4{margin-inline:calc(var(--spacing)*4)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.block{display:block}.contents{display:contents}.flex{display:flex}.h-auto{height:auto}.h-full{height:100%}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[100px\]{min-height:100px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.bg-black{background-color:var(--color-black)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-white{background-color:var(--color-white)}.object-contain{object-fit:contain}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-8{padding:calc(var(--spacing)*8)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-2{padding-block:calc(var(--spacing)*2)}.pt-4{padding-top:calc(var(--spacing)*4)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-gray-400{color:var(--color-gray-400)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-white{color:var(--color-white)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-300:hover{background-color:var(--color-gray-300)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-400:disabled{background-color:var(--color-gray-400)}@media(prefers-color-scheme:dark){.dark\:border-gray-600{border-color:var(--color-gray-600)}.dark\:border-gray-700{border-color:var(--color-gray-700)}.dark\:bg-gray-700{background-color:var(--color-gray-700)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:bg-gray-900{background-color:var(--color-gray-900)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-white{color:var(--color-white)}@media(hover:hover){.dark\:hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.dark\:hover\:text-gray-300:hover{color:var(--color-gray-300)}}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
2
|
+
capture: (imageData: string) => any;
|
|
3
|
+
cancel: () => any;
|
|
4
|
+
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
5
|
+
onCapture?: ((imageData: string) => any) | undefined;
|
|
6
|
+
onCancel?: (() => any) | undefined;
|
|
7
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ToolResult } from "gui-chat-protocol/vue";
|
|
2
|
+
import type { ImageToolData } from "../core/types";
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
result: ToolResult<ImageToolData>;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ToolResult } from "gui-chat-protocol/vue";
|
|
2
|
+
import type { ImageToolData } from "../core/types";
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
selectedResult: ToolResult<ImageToolData>;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera Plugin - Vue Implementation
|
|
3
|
+
*/
|
|
4
|
+
import "../style.css";
|
|
5
|
+
import type { ToolPlugin } from "gui-chat-protocol/vue";
|
|
6
|
+
import type { CameraArgs, ImageToolData } from "../core/types";
|
|
7
|
+
import CameraCapture from "./CameraCapture.vue";
|
|
8
|
+
import View from "./View.vue";
|
|
9
|
+
import Preview from "./Preview.vue";
|
|
10
|
+
export declare const plugin: ToolPlugin<ImageToolData, unknown, CameraArgs>;
|
|
11
|
+
export type { CameraArgs, ImageToolData } from "../core/types";
|
|
12
|
+
export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT } from "../core/definition";
|
|
13
|
+
export { CameraCapture, View, Preview };
|
|
14
|
+
declare const _default: {
|
|
15
|
+
plugin: ToolPlugin<ImageToolData, unknown, CameraArgs, import("gui-chat-protocol/vue").InputHandler, Record<string, unknown>>;
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
package/dist/vue.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),m=require("./core.cjs"),w={class:"fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-75"},C={class:"relative bg-white dark:bg-gray-900 rounded-lg shadow-xl max-w-2xl w-full mx-4"},N={key:0,class:"px-4 pt-4 pb-2"},V=["value"],D={class:"p-4"},O={class:"relative bg-black rounded-lg overflow-hidden",style:{"aspect-ratio":"4/3"}},T={key:0,class:"absolute inset-0 flex items-center justify-center text-white text-center p-4"},B={class:"flex items-center justify-center gap-4 p-4 border-t border-gray-200 dark:border-gray-700"},M=["disabled"],h=e.defineComponent({__name:"CameraCapture",emits:["capture","cancel"],setup(c,{emit:g}){const l=g,o=e.ref(null),s=e.ref(null),r=e.ref(""),i=e.ref([]),d=e.ref("");e.onMounted(async()=>{try{await k(),await v()}catch(t){console.error("Camera initialization failed:",t),r.value=t instanceof Error?t.message:"Failed to access camera. Please grant camera permissions."}}),e.onUnmounted(()=>{p()});const k=async()=>{try{(await navigator.mediaDevices.getUserMedia({video:!0,audio:!1})).getTracks().forEach(u=>u.stop());const a=await navigator.mediaDevices.enumerateDevices();i.value=a.filter(u=>u.kind==="videoinput");const n=i.value.find(u=>u.label.toLowerCase().includes("front"));d.value=n?.deviceId||i.value[0]?.deviceId||""}catch(t){console.error("Failed to enumerate cameras:",t),i.value=[]}},v=async t=>{p(),r.value="";try{const a={video:t?{deviceId:{exact:t}}:{facingMode:"user"},audio:!1};s.value=await navigator.mediaDevices.getUserMedia(a),o.value&&(o.value.srcObject=s.value)}catch(a){console.error("Camera access failed:",a),r.value=a instanceof Error?a.message:"Failed to access camera. Please grant camera permissions."}},_=async()=>{d.value&&await v(d.value)},p=()=>{s.value&&(s.value.getTracks().forEach(t=>t.stop()),s.value=null),o.value&&(o.value.srcObject=null)},E=()=>{if(!(!o.value||r.value))try{const t=document.createElement("canvas");t.width=o.value.videoWidth,t.height=o.value.videoHeight;const a=t.getContext("2d");if(!a)throw new Error("Failed to get canvas context");a.drawImage(o.value,0,0,t.width,t.height);const n=t.toDataURL("image/png");p(),l("capture",n)}catch(t){console.error("Capture failed:",t),r.value="Failed to capture photo"}},f=()=>{p(),l("cancel")};return(t,a)=>(e.openBlock(),e.createElementBlock("div",w,[e.createElementVNode("div",C,[e.createElementVNode("div",{class:"flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700"},[a[1]||(a[1]=e.createElementVNode("h3",{class:"text-lg font-semibold text-gray-900 dark:text-white"}," Take Photo ",-1)),e.createElementVNode("button",{onClick:f,class:"text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"}," ✕ ")]),i.value.length>1?(e.openBlock(),e.createElementBlock("div",N,[a[2]||(a[2]=e.createElementVNode("label",{for:"camera-select",class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"}," Select Camera ",-1)),e.withDirectives(e.createElementVNode("select",{id:"camera-select","onUpdate:modelValue":a[0]||(a[0]=n=>d.value=n),onChange:_,class:"w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.value,n=>(e.openBlock(),e.createElementBlock("option",{key:n.deviceId,value:n.deviceId},e.toDisplayString(n.label||`Camera ${i.value.indexOf(n)+1}`),9,V))),128))],544),[[e.vModelSelect,d.value]])])):e.createCommentVNode("",!0),e.createElementVNode("div",D,[e.createElementVNode("div",O,[e.createElementVNode("video",{ref_key:"videoRef",ref:o,autoplay:"",playsinline:"",class:"w-full h-full object-contain"},null,512),r.value?(e.openBlock(),e.createElementBlock("div",T,[e.createElementVNode("div",null,[a[3]||(a[3]=e.createElementVNode("span",{class:"text-5xl mb-2"},"⚠️",-1)),e.createElementVNode("p",null,e.toDisplayString(r.value),1)])])):e.createCommentVNode("",!0)])]),e.createElementVNode("div",B,[e.createElementVNode("button",{onClick:f,class:"px-6 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"}," Cancel "),e.createElementVNode("button",{onClick:E,disabled:!!r.value,class:"px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors flex items-center gap-2"},[...a[4]||(a[4]=[e.createTextVNode(" 📷 ",-1),e.createElementVNode("span",null,"Capture",-1)])],8,M)])])]))}}),P={class:"w-full h-full overflow-y-auto"},S={class:"min-h-full flex flex-col items-center justify-center p-4"},I={class:"flex-1 flex items-center justify-center min-h-0"},$=["src"],j={key:0,class:"mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded-lg max-w-full flex-shrink-0"},F={class:"text-sm text-gray-700 dark:text-gray-300"},y=e.defineComponent({__name:"View",props:{selectedResult:{}},setup(c){return(g,l)=>(e.openBlock(),e.createElementBlock("div",P,[e.createElementVNode("div",S,[e.createElementVNode("div",I,[e.createElementVNode("img",{src:c.selectedResult.data?.imageData,class:"max-w-full max-h-full object-contain rounded",alt:"Captured photo"},null,8,$)]),c.selectedResult.data?.prompt?(e.openBlock(),e.createElementBlock("div",j,[e.createElementVNode("p",F,[l[0]||(l[0]=e.createElementVNode("span",{class:"font-medium"},"Prompt:",-1)),e.createTextVNode(" "+e.toDisplayString(c.selectedResult.data.prompt),1)])])):e.createCommentVNode("",!0)])]))}}),R={class:"min-h-[100px] flex items-center justify-center"},L=["src"],U={key:1,class:"text-gray-400 text-sm"},b=e.defineComponent({__name:"Preview",props:{result:{}},setup(c){return(g,l)=>(e.openBlock(),e.createElementBlock("div",R,[c.result.data?.imageData?(e.openBlock(),e.createElementBlock("img",{key:0,src:c.result.data.imageData,class:"max-w-full h-auto rounded",alt:"Captured photo"},null,8,L)):(e.openBlock(),e.createElementBlock("div",U,"No image yet"))]))}}),A=async(c,g)=>new Promise(l=>{const o=document.createElement("div");document.body.appendChild(o);const s=e.createApp(h,{onCapture:r=>{s.unmount(),document.body.removeChild(o),l({data:{imageData:r,prompt:`Photo taken at ${new Date().toLocaleString()}`},message:"photo captured successfully",instructions:"Acknowledge that the photo was taken and has been already presented to the user. You can describe what you see in the photo if appropriate."})},onCancel:()=>{s.unmount(),document.body.removeChild(o),l({message:"photo capture cancelled by user",cancelled:!0})}});s.mount(o)}),x={toolDefinition:m.TOOL_DEFINITION,execute:A,generatingMessage:"Opening camera...",waitingMessage:"Taking photo...",isEnabled:()=>typeof navigator<"u"&&!!navigator.mediaDevices&&!!navigator.mediaDevices.getUserMedia,viewComponent:y,previewComponent:b,systemPrompt:m.SYSTEM_PROMPT},Y={plugin:x};exports.SYSTEM_PROMPT=m.SYSTEM_PROMPT;exports.TOOL_DEFINITION=m.TOOL_DEFINITION;exports.TOOL_NAME=m.TOOL_NAME;exports.CameraCapture=h;exports.Preview=b;exports.View=y;exports.default=Y;exports.plugin=x;
|
package/dist/vue.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { defineComponent as x, ref as p, onMounted as E, onUnmounted as $, createElementBlock as n, openBlock as l, createElementVNode as a, createCommentVNode as h, withDirectives as P, Fragment as j, renderList as M, toDisplayString as y, vModelSelect as O, createTextVNode as _, createApp as T } from "vue";
|
|
2
|
+
import { SYSTEM_PROMPT as I, TOOL_DEFINITION as F } from "./core.js";
|
|
3
|
+
import { TOOL_NAME as ce } from "./core.js";
|
|
4
|
+
const R = { class: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-75" }, S = { class: "relative bg-white dark:bg-gray-900 rounded-lg shadow-xl max-w-2xl w-full mx-4" }, N = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "px-4 pt-4 pb-2"
|
|
7
|
+
}, L = ["value"], U = { class: "p-4" }, V = {
|
|
8
|
+
class: "relative bg-black rounded-lg overflow-hidden",
|
|
9
|
+
style: { "aspect-ratio": "4/3" }
|
|
10
|
+
}, A = {
|
|
11
|
+
key: 0,
|
|
12
|
+
class: "absolute inset-0 flex items-center justify-center text-white text-center p-4"
|
|
13
|
+
}, z = { class: "flex items-center justify-center gap-4 p-4 border-t border-gray-200 dark:border-gray-700" }, B = ["disabled"], Y = /* @__PURE__ */ x({
|
|
14
|
+
__name: "CameraCapture",
|
|
15
|
+
emits: ["capture", "cancel"],
|
|
16
|
+
setup(d, { emit: v }) {
|
|
17
|
+
const i = v, r = p(null), c = p(null), s = p(""), u = p([]), m = p("");
|
|
18
|
+
E(async () => {
|
|
19
|
+
try {
|
|
20
|
+
await k(), await b();
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error("Camera initialization failed:", e), s.value = e instanceof Error ? e.message : "Failed to access camera. Please grant camera permissions.";
|
|
23
|
+
}
|
|
24
|
+
}), $(() => {
|
|
25
|
+
f();
|
|
26
|
+
});
|
|
27
|
+
const k = async () => {
|
|
28
|
+
try {
|
|
29
|
+
(await navigator.mediaDevices.getUserMedia({
|
|
30
|
+
video: !0,
|
|
31
|
+
audio: !1
|
|
32
|
+
})).getTracks().forEach((g) => g.stop());
|
|
33
|
+
const t = await navigator.mediaDevices.enumerateDevices();
|
|
34
|
+
u.value = t.filter(
|
|
35
|
+
(g) => g.kind === "videoinput"
|
|
36
|
+
);
|
|
37
|
+
const o = u.value.find(
|
|
38
|
+
(g) => g.label.toLowerCase().includes("front")
|
|
39
|
+
);
|
|
40
|
+
m.value = o?.deviceId || u.value[0]?.deviceId || "";
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error("Failed to enumerate cameras:", e), u.value = [];
|
|
43
|
+
}
|
|
44
|
+
}, b = async (e) => {
|
|
45
|
+
f(), s.value = "";
|
|
46
|
+
try {
|
|
47
|
+
const t = {
|
|
48
|
+
video: e ? { deviceId: { exact: e } } : { facingMode: "user" },
|
|
49
|
+
audio: !1
|
|
50
|
+
};
|
|
51
|
+
c.value = await navigator.mediaDevices.getUserMedia(t), r.value && (r.value.srcObject = c.value);
|
|
52
|
+
} catch (t) {
|
|
53
|
+
console.error("Camera access failed:", t), s.value = t instanceof Error ? t.message : "Failed to access camera. Please grant camera permissions.";
|
|
54
|
+
}
|
|
55
|
+
}, C = async () => {
|
|
56
|
+
m.value && await b(m.value);
|
|
57
|
+
}, f = () => {
|
|
58
|
+
c.value && (c.value.getTracks().forEach((e) => e.stop()), c.value = null), r.value && (r.value.srcObject = null);
|
|
59
|
+
}, D = () => {
|
|
60
|
+
if (!(!r.value || s.value))
|
|
61
|
+
try {
|
|
62
|
+
const e = document.createElement("canvas");
|
|
63
|
+
e.width = r.value.videoWidth, e.height = r.value.videoHeight;
|
|
64
|
+
const t = e.getContext("2d");
|
|
65
|
+
if (!t)
|
|
66
|
+
throw new Error("Failed to get canvas context");
|
|
67
|
+
t.drawImage(r.value, 0, 0, e.width, e.height);
|
|
68
|
+
const o = e.toDataURL("image/png");
|
|
69
|
+
f(), i("capture", o);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error("Capture failed:", e), s.value = "Failed to capture photo";
|
|
72
|
+
}
|
|
73
|
+
}, w = () => {
|
|
74
|
+
f(), i("cancel");
|
|
75
|
+
};
|
|
76
|
+
return (e, t) => (l(), n("div", R, [
|
|
77
|
+
a("div", S, [
|
|
78
|
+
a("div", { class: "flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700" }, [
|
|
79
|
+
t[1] || (t[1] = a("h3", { class: "text-lg font-semibold text-gray-900 dark:text-white" }, " Take Photo ", -1)),
|
|
80
|
+
a("button", {
|
|
81
|
+
onClick: w,
|
|
82
|
+
class: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
|
83
|
+
}, " ✕ ")
|
|
84
|
+
]),
|
|
85
|
+
u.value.length > 1 ? (l(), n("div", N, [
|
|
86
|
+
t[2] || (t[2] = a("label", {
|
|
87
|
+
for: "camera-select",
|
|
88
|
+
class: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
|
|
89
|
+
}, " Select Camera ", -1)),
|
|
90
|
+
P(a("select", {
|
|
91
|
+
id: "camera-select",
|
|
92
|
+
"onUpdate:modelValue": t[0] || (t[0] = (o) => m.value = o),
|
|
93
|
+
onChange: C,
|
|
94
|
+
class: "w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
95
|
+
}, [
|
|
96
|
+
(l(!0), n(j, null, M(u.value, (o) => (l(), n("option", {
|
|
97
|
+
key: o.deviceId,
|
|
98
|
+
value: o.deviceId
|
|
99
|
+
}, y(o.label || `Camera ${u.value.indexOf(o) + 1}`), 9, L))), 128))
|
|
100
|
+
], 544), [
|
|
101
|
+
[O, m.value]
|
|
102
|
+
])
|
|
103
|
+
])) : h("", !0),
|
|
104
|
+
a("div", U, [
|
|
105
|
+
a("div", V, [
|
|
106
|
+
a("video", {
|
|
107
|
+
ref_key: "videoRef",
|
|
108
|
+
ref: r,
|
|
109
|
+
autoplay: "",
|
|
110
|
+
playsinline: "",
|
|
111
|
+
class: "w-full h-full object-contain"
|
|
112
|
+
}, null, 512),
|
|
113
|
+
s.value ? (l(), n("div", A, [
|
|
114
|
+
a("div", null, [
|
|
115
|
+
t[3] || (t[3] = a("span", { class: "text-5xl mb-2" }, "⚠️", -1)),
|
|
116
|
+
a("p", null, y(s.value), 1)
|
|
117
|
+
])
|
|
118
|
+
])) : h("", !0)
|
|
119
|
+
])
|
|
120
|
+
]),
|
|
121
|
+
a("div", z, [
|
|
122
|
+
a("button", {
|
|
123
|
+
onClick: w,
|
|
124
|
+
class: "px-6 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
|
|
125
|
+
}, " Cancel "),
|
|
126
|
+
a("button", {
|
|
127
|
+
onClick: D,
|
|
128
|
+
disabled: !!s.value,
|
|
129
|
+
class: "px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors flex items-center gap-2"
|
|
130
|
+
}, [...t[4] || (t[4] = [
|
|
131
|
+
_(" 📷 ", -1),
|
|
132
|
+
a("span", null, "Capture", -1)
|
|
133
|
+
])], 8, B)
|
|
134
|
+
])
|
|
135
|
+
])
|
|
136
|
+
]));
|
|
137
|
+
}
|
|
138
|
+
}), H = { class: "w-full h-full overflow-y-auto" }, W = { class: "min-h-full flex flex-col items-center justify-center p-4" }, q = { class: "flex-1 flex items-center justify-center min-h-0" }, G = ["src"], J = {
|
|
139
|
+
key: 0,
|
|
140
|
+
class: "mt-4 p-3 bg-gray-100 dark:bg-gray-800 rounded-lg max-w-full flex-shrink-0"
|
|
141
|
+
}, K = { class: "text-sm text-gray-700 dark:text-gray-300" }, Q = /* @__PURE__ */ x({
|
|
142
|
+
__name: "View",
|
|
143
|
+
props: {
|
|
144
|
+
selectedResult: {}
|
|
145
|
+
},
|
|
146
|
+
setup(d) {
|
|
147
|
+
return (v, i) => (l(), n("div", H, [
|
|
148
|
+
a("div", W, [
|
|
149
|
+
a("div", q, [
|
|
150
|
+
a("img", {
|
|
151
|
+
src: d.selectedResult.data?.imageData,
|
|
152
|
+
class: "max-w-full max-h-full object-contain rounded",
|
|
153
|
+
alt: "Captured photo"
|
|
154
|
+
}, null, 8, G)
|
|
155
|
+
]),
|
|
156
|
+
d.selectedResult.data?.prompt ? (l(), n("div", J, [
|
|
157
|
+
a("p", K, [
|
|
158
|
+
i[0] || (i[0] = a("span", { class: "font-medium" }, "Prompt:", -1)),
|
|
159
|
+
_(" " + y(d.selectedResult.data.prompt), 1)
|
|
160
|
+
])
|
|
161
|
+
])) : h("", !0)
|
|
162
|
+
])
|
|
163
|
+
]));
|
|
164
|
+
}
|
|
165
|
+
}), X = { class: "min-h-[100px] flex items-center justify-center" }, Z = ["src"], ee = {
|
|
166
|
+
key: 1,
|
|
167
|
+
class: "text-gray-400 text-sm"
|
|
168
|
+
}, te = /* @__PURE__ */ x({
|
|
169
|
+
__name: "Preview",
|
|
170
|
+
props: {
|
|
171
|
+
result: {}
|
|
172
|
+
},
|
|
173
|
+
setup(d) {
|
|
174
|
+
return (v, i) => (l(), n("div", X, [
|
|
175
|
+
d.result.data?.imageData ? (l(), n("img", {
|
|
176
|
+
key: 0,
|
|
177
|
+
src: d.result.data.imageData,
|
|
178
|
+
class: "max-w-full h-auto rounded",
|
|
179
|
+
alt: "Captured photo"
|
|
180
|
+
}, null, 8, Z)) : (l(), n("div", ee, "No image yet"))
|
|
181
|
+
]));
|
|
182
|
+
}
|
|
183
|
+
}), ae = async (d, v) => new Promise((i) => {
|
|
184
|
+
const r = document.createElement("div");
|
|
185
|
+
document.body.appendChild(r);
|
|
186
|
+
const c = T(Y, {
|
|
187
|
+
onCapture: (s) => {
|
|
188
|
+
c.unmount(), document.body.removeChild(r), i({
|
|
189
|
+
data: {
|
|
190
|
+
imageData: s,
|
|
191
|
+
prompt: `Photo taken at ${(/* @__PURE__ */ new Date()).toLocaleString()}`
|
|
192
|
+
},
|
|
193
|
+
message: "photo captured successfully",
|
|
194
|
+
instructions: "Acknowledge that the photo was taken and has been already presented to the user. You can describe what you see in the photo if appropriate."
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
onCancel: () => {
|
|
198
|
+
c.unmount(), document.body.removeChild(r), i({
|
|
199
|
+
message: "photo capture cancelled by user",
|
|
200
|
+
cancelled: !0
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
c.mount(r);
|
|
205
|
+
}), re = {
|
|
206
|
+
toolDefinition: F,
|
|
207
|
+
execute: ae,
|
|
208
|
+
generatingMessage: "Opening camera...",
|
|
209
|
+
waitingMessage: "Taking photo...",
|
|
210
|
+
isEnabled: () => typeof navigator < "u" && !!navigator.mediaDevices && !!navigator.mediaDevices.getUserMedia,
|
|
211
|
+
viewComponent: Q,
|
|
212
|
+
previewComponent: te,
|
|
213
|
+
systemPrompt: I
|
|
214
|
+
}, ne = { plugin: re };
|
|
215
|
+
export {
|
|
216
|
+
Y as CameraCapture,
|
|
217
|
+
te as Preview,
|
|
218
|
+
I as SYSTEM_PROMPT,
|
|
219
|
+
F as TOOL_DEFINITION,
|
|
220
|
+
ce as TOOL_NAME,
|
|
221
|
+
Q as View,
|
|
222
|
+
ne as default,
|
|
223
|
+
re as plugin
|
|
224
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gui-chat-plugin/camera",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Camera photo capture plugin for GUIChat",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./core": {
|
|
16
|
+
"types": "./dist/core/index.d.ts",
|
|
17
|
+
"import": "./dist/core.js",
|
|
18
|
+
"require": "./dist/core.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./vue": {
|
|
21
|
+
"types": "./dist/vue/index.d.ts",
|
|
22
|
+
"import": "./dist/vue.js",
|
|
23
|
+
"require": "./dist/vue.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./style.css": "./dist/style.css"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"dev": "vite",
|
|
32
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
33
|
+
"typecheck": "vue-tsc --noEmit",
|
|
34
|
+
"lint": "eslint src demo"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"gui-chat-protocol": "^0.0.1",
|
|
38
|
+
"vue": "^3.5.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
|
43
|
+
"@typescript-eslint/parser": "^8.53.0",
|
|
44
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
45
|
+
"eslint": "^9.39.2",
|
|
46
|
+
"eslint-plugin-vue": "^10.6.2",
|
|
47
|
+
"globals": "^17.0.0",
|
|
48
|
+
"gui-chat-protocol": "^0.0.1",
|
|
49
|
+
"tailwindcss": "^4.1.18",
|
|
50
|
+
"typescript": "~5.9.3",
|
|
51
|
+
"vite": "^7.3.1",
|
|
52
|
+
"vue": "^3.5.27",
|
|
53
|
+
"vue-eslint-parser": "^10.2.0",
|
|
54
|
+
"vue-tsc": "^3.2.2"
|
|
55
|
+
},
|
|
56
|
+
"keywords": [
|
|
57
|
+
"guichat",
|
|
58
|
+
"plugin",
|
|
59
|
+
"camera",
|
|
60
|
+
"photo"
|
|
61
|
+
],
|
|
62
|
+
"license": "MIT"
|
|
63
|
+
}
|