Skip to content

Commit a5ac0a2

Browse files
committed
chore(plugin-inspect): remove storybook-static from git and fix lint errors
Removed the auto-generated storybook-static directory from git tracking, added it to .gitignore, and fixed minor ESLint warnings related to Vue props mutation in the Inspector.
1 parent dbeb8f8 commit a5ac0a2

22 files changed

Lines changed: 186 additions & 135 deletions

packages/devframe/src/node/__tests__/rpc-streaming.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { createRpcClient } from 'devframe/rpc/client'
55
import { createRpcServer } from 'devframe/rpc/server'
66
import { createWsRpcChannel } from 'devframe/rpc/transports/ws-client'
77
import { attachWsRpcTransport } from 'devframe/rpc/transports/ws-server'
8+
import { getPort } from 'get-port-please'
89
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
910
import { WebSocket } from 'ws'
11+
1012
import { RpcFunctionsHost } from '../host-functions'
1113

1214
vi.stubGlobal('WebSocket', WebSocket)
1315

14-
import { getPort } from 'get-port-please'
15-
1616
interface Harness {
1717
port: number
1818
rpcHost: RpcFunctionsHost

plugins/inspect/.storybook/main.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { StorybookConfig } from '@storybook/vue3-vite';
2-
import { mergeConfig } from 'vite';
3-
import vue from '@vitejs/plugin-vue';
4-
import UnoCSS from 'unocss/vite';
5-
import { alias } from '../../../alias';
1+
import type { StorybookConfig } from '@storybook/vue3-vite'
2+
import vue from '@vitejs/plugin-vue'
3+
import UnoCSS from 'unocss/vite'
4+
import { mergeConfig } from 'vite'
5+
import { alias } from '../../../alias'
66

77
const config: StorybookConfig = {
88
stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
@@ -16,7 +16,7 @@ const config: StorybookConfig = {
1616
return mergeConfig(config, {
1717
resolve: { alias },
1818
plugins: [vue(), UnoCSS()],
19-
});
19+
})
2020
},
21-
};
22-
export default config;
21+
}
22+
export default config

plugins/inspect/.storybook/preview.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Preview } from '@storybook/vue3';
1+
import type { Preview } from '@storybook/vue3'
22
import 'virtual:uno.css'
33
import '../src/spa/style.css'
44

@@ -24,6 +24,6 @@ const preview: Preview = {
2424
],
2525
},
2626
},
27-
};
27+
}
2828

29-
export default preview;
29+
export default preview

plugins/inspect/src/rpc/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { RpcDefinitionsToFunctions } from 'devframe/rpc'
22
import { describeAgent } from './functions/describe-agent'
33
import { invoke } from './functions/invoke'
4+
import { invokeAgentTool } from './functions/invoke-agent-tool'
45
import { listFunctions } from './functions/list-functions'
56
import { listStateKeys } from './functions/list-state-keys'
6-
import { invokeAgentTool } from './functions/invoke-agent-tool'
77
import { readAgentResource } from './functions/read-agent-resource'
88

99
/**

plugins/inspect/src/spa/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import { onMounted, ref } from 'vue'
33
import AgentSmart from './components/AgentSmart.vue'
44
import FunctionsSmart from './components/FunctionsSmart.vue'
5-
import StateSmart from './components/StateSmart.vue'
65
import HistorySmart from './components/HistorySmart.vue'
7-
import { connect, connection } from './composables/rpc'
6+
import StateSmart from './components/StateSmart.vue'
87
import { useRefresh } from './composables/refresh'
8+
import { connect, connection } from './composables/rpc'
99
1010
type Tab = 'functions' | 'state' | 'agent' | 'history'
1111

plugins/inspect/src/spa/components/AgentSmart.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script setup lang="ts">
22
import type { AgentManifest, InvokeResult } from '@devframes/plugin-inspect/client'
33
import { onMounted, reactive, shallowRef } from 'vue'
4-
import { isStatic, useRpc } from '../composables/rpc'
54
import { useRefreshProvider } from '../composables/refresh'
5+
import { isStatic, useRpc } from '../composables/rpc'
66
import AgentView from './AgentView.vue'
77
88
const rpc = useRpc()
@@ -20,27 +20,33 @@ useRefreshProvider(fetchData)
2020
onMounted(fetchData)
2121
2222
async function onInvoke(id: string, parsedArgs: unknown) {
23-
if (!rpc.value) return
23+
if (!rpc.value)
24+
return
2425
pending[id] = true
2526
try {
2627
results[id] = await rpc.value.call('devframes-plugin-inspect:invoke-agent-tool', id, parsedArgs)
27-
} catch (e) {
28+
}
29+
catch (e) {
2830
const err = e as Error
2931
results[id] = { ok: false, error: { name: err?.name ?? 'Error', message: err?.message ?? String(e) } }
30-
} finally {
32+
}
33+
finally {
3134
pending[id] = false
3235
}
3336
}
3437
3538
async function onRead(id: string) {
36-
if (!rpc.value) return
39+
if (!rpc.value)
40+
return
3741
pending[id] = true
3842
try {
3943
results[id] = await rpc.value.call('devframes-plugin-inspect:read-agent-resource', id)
40-
} catch (e) {
44+
}
45+
catch (e) {
4146
const err = e as Error
4247
results[id] = { ok: false, error: { name: err?.name ?? 'Error', message: err?.message ?? String(e) } }
43-
} finally {
48+
}
49+
finally {
4450
pending[id] = false
4551
}
4652
}

plugins/inspect/src/spa/components/AgentView.stories.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { Meta, StoryObj } from '@storybook/vue3';
2-
import AgentView from './AgentView.vue';
1+
import type { Meta, StoryObj } from '@storybook/vue3'
2+
import AgentView from './AgentView.vue'
33

44
const meta = {
55
title: 'Inspector/AgentView',
@@ -9,10 +9,10 @@ const meta = {
99
onInvoke: { action: 'invoked' },
1010
onRead: { action: 'read' },
1111
},
12-
} satisfies Meta<typeof AgentView>;
12+
} satisfies Meta<typeof AgentView>
1313

14-
export default meta;
15-
type Story = StoryObj<typeof meta>;
14+
export default meta
15+
type Story = StoryObj<typeof meta>
1616

1717
export const Default: Story = {
1818
args: {
@@ -34,7 +34,7 @@ export const Default: Story = {
3434
title: 'Tool 2',
3535
description: 'A destructive tool',
3636
safety: 'destructive',
37-
}
37+
},
3838
],
3939
resources: [
4040
{
@@ -43,7 +43,7 @@ export const Default: Story = {
4343
name: 'Resource 1',
4444
description: 'A sample resource',
4545
mimeType: 'application/json',
46-
}
46+
},
4747
],
4848
},
4949
isStatic: false,
@@ -55,11 +55,11 @@ export const Default: Story = {
5555
tool2: true,
5656
},
5757
},
58-
};
58+
}
5959

6060
export const StaticMode: Story = {
6161
args: {
6262
...Default.args,
6363
isStatic: true,
6464
},
65-
};
65+
}

plugins/inspect/src/spa/components/AgentView.vue

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
22
import type { AgentManifest, InvokeResult } from '@devframes/plugin-inspect/client'
3-
import { ref, reactive } from 'vue'
3+
import { reactive, ref } from 'vue'
44
import JsonView from './JsonView.vue'
55
6-
const props = defineProps<{
6+
defineProps<{
77
manifest: AgentManifest | null
88
isStatic: boolean
99
results: Record<string, InvokeResult | { ok: false, error: { name: string, message: string } }>
@@ -30,7 +30,8 @@ function invokeTool(id: string) {
3030
try {
3131
const raw = JSON.parse(argsInput[id] || '{}')
3232
parsed = raw
33-
} catch (err) {
33+
}
34+
catch (err) {
3435
// Emitting error would be cleaner, for now we will throw to stop execution
3536
throw new Error(`Invalid JSON args: ${(err as Error).message}`)
3637
}
@@ -73,27 +74,35 @@ function readResource(id: string) {
7374
</div>
7475
<template v-if="expanded === tool.id">
7576
<template v-if="tool.inputSchema">
76-
<div class="label">Input schema</div>
77+
<div class="label">
78+
Input schema
79+
</div>
7780
<JsonView :value="tool.inputSchema" :expand-depth="1" />
7881
</template>
7982
<template v-if="tool.outputSchema">
80-
<div class="label">Output schema</div>
83+
<div class="label">
84+
Output schema
85+
</div>
8186
<JsonView :value="tool.outputSchema" :expand-depth="1" />
8287
</template>
8388
<template v-if="tool.examples && tool.examples.length">
84-
<div class="label">Examples</div>
89+
<div class="label">
90+
Examples
91+
</div>
8592
<JsonView :value="tool.examples" :expand-depth="1" />
8693
</template>
8794

88-
<div class="label">Invoke (MCP format)</div>
95+
<div class="label">
96+
Invoke (MCP format)
97+
</div>
8998
<textarea v-model="argsInput[tool.id]" class="args" spellcheck="false" placeholder="{}" />
9099
<div style="margin-top: 8px; display: flex; gap: 8px; align-items: center;">
91100
<button class="btn" :disabled="pending[tool.id] || isStatic" @click="invokeTool(tool.id)">
92101
{{ pending[tool.id] ? 'Invoking…' : 'Invoke' }}
93102
</button>
94103
<span v-if="isStatic" class="note">read-only static backend</span>
95104
</div>
96-
105+
97106
<div v-if="results[tool.id]" class="result">
98107
<div class="result-head">
99108
<span v-if="results[tool.id].ok" class="ok">✓ resolved</span>
@@ -138,7 +147,7 @@ function readResource(id: string) {
138147
</button>
139148
<span v-if="isStatic" class="note">read-only static backend</span>
140149
</div>
141-
150+
142151
<div v-if="results[res.id]" class="result">
143152
<div class="result-head">
144153
<span v-if="results[res.id].ok" class="ok">✓ resolved</span>

plugins/inspect/src/spa/components/FunctionsSmart.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<script setup lang="ts">
22
import type { InvokeResult, RpcFunctionInfo } from '@devframes/plugin-inspect/client'
33
import { onMounted, reactive, shallowRef } from 'vue'
4-
import { isStatic, useRpc } from '../composables/rpc'
54
import { useRefreshProvider } from '../composables/refresh'
5+
import { isStatic, useRpc } from '../composables/rpc'
66
import FunctionsView from './FunctionsView.vue'
77
88
const rpc = useRpc()

plugins/inspect/src/spa/components/FunctionsTreeNode.vue

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script setup lang="ts">
2-
import type { RpcFunctionInfo, InvokeResult } from '@devframes/plugin-inspect/client'
3-
import { getHashColorFromString } from '../utils/color'
2+
import type { RpcFunctionInfo } from '@devframes/plugin-inspect/client'
43
import { ref } from 'vue'
4+
import { getHashColorFromString } from '../utils/color'
55
import JsonView from './JsonView.vue'
66
7-
export type TreeNode = {
7+
export interface TreeNode {
88
name: string
99
fullPath: string
1010
isLeaf: boolean
@@ -23,6 +23,7 @@ const props = defineProps<{
2323
2424
const emit = defineEmits<{
2525
(e: 'invoke', fn: RpcFunctionInfo): void
26+
(e: 'updateArgs', name: string, value: string): void
2627
}>()
2728
2829
const expandedNode = ref(props.depth < 1)
@@ -33,24 +34,30 @@ function toggle() {
3334
expandedFn.value = !expandedFn.value
3435
if (props.node.fn && props.argsInput[props.node.fn.name] === undefined) {
3536
// Initialize if empty
36-
// Emitting an event just to set default isn't necessary because we mutate props.argsInput
37+
// Emitting an event just to set default isn't necessary because it's v-model bound
3738
}
38-
} else {
39+
}
40+
else {
3941
expandedNode.value = !expandedNode.value
4042
}
4143
}
4244
4345
const color = getHashColorFromString(props.node.fullPath)
46+
</script>
4447

48+
<script lang="ts">
49+
export default {
50+
name: 'FunctionsTreeNode',
51+
}
4552
</script>
4653

4754
<template>
4855
<div class="tree-node">
49-
<div v-if="!node.isLeaf" class="group-head" @click="toggle" style="cursor: pointer; user-select: none;">
56+
<div v-if="!node.isLeaf" class="group-head" style="cursor: pointer; user-select: none;" @click="toggle">
5057
<div class="chev i-ph-caret-right" :class="{ open: expandedNode }" />
5158
<span class="ns" :style="{ color }">{{ node.name }}</span>
5259
</div>
53-
60+
5461
<div v-if="node.isLeaf && node.fn" class="fn-row">
5562
<div class="fn-head" :class="{ clickable: node.fn.invokable || !!node.fn.agent || node.fn.hasArgs || node.fn.hasReturns }" @click="toggle">
5663
<div class="chev i-ph-caret-right" :class="{ open: expandedFn }" />
@@ -67,20 +74,28 @@ const color = getHashColorFromString(props.node.fullPath)
6774
</div>
6875

6976
<div v-if="expandedFn" class="fn-detail">
70-
<p v-if="node.fn.agent" class="desc">{{ node.fn.agent.description }}</p>
77+
<p v-if="node.fn.agent" class="desc">
78+
{{ node.fn.agent.description }}
79+
</p>
7180

7281
<template v-if="node.fn.argsSchema">
73-
<div class="label">Args schema</div>
82+
<div class="label">
83+
Args schema
84+
</div>
7485
<JsonView :value="node.fn.argsSchema" :expand-depth="0" />
7586
</template>
7687
<template v-if="node.fn.returnsSchema">
77-
<div class="label">Returns schema</div>
88+
<div class="label">
89+
Returns schema
90+
</div>
7891
<JsonView :value="node.fn.returnsSchema" :expand-depth="0" />
7992
</template>
8093

8194
<template v-if="node.fn.invokable">
82-
<div class="label">Invoke — positional args as a JSON array</div>
83-
<textarea v-model="argsInput[node.fn.name]" class="args" spellcheck="false" placeholder="[]" />
95+
<div class="label">
96+
Invoke — positional args as a JSON array
97+
</div>
98+
<textarea :value="argsInput[node.fn.name]" class="args" spellcheck="false" placeholder="[]" @input="emit('updateArgs', node.fn.name, ($event.target as HTMLTextAreaElement).value)" />
8499
<div style="margin-top: 8px; display: flex; gap: 8px; align-items: center;">
85100
<button class="btn" :disabled="pending[node.fn.name] || isStatic()" @click.stop="emit('invoke', node.fn!)">
86101
{{ pending[node.fn.name] ? 'Invoking…' : 'Invoke' }}
@@ -109,7 +124,7 @@ const color = getHashColorFromString(props.node.fullPath)
109124

110125
<div v-if="!node.isLeaf && expandedNode" class="children" style="padding-left: 14px; border-left: 1px solid var(--df-border-soft); margin-left: 6px;">
111126
<FunctionsTreeNode
112-
v-for="child in Object.values(node.children || {}).sort((a,b) => { if(a.isLeaf !== b.isLeaf) return a.isLeaf ? 1 : -1; return a.name.localeCompare(b.name) })"
127+
v-for="child in Object.values(node.children || {}).sort((a, b) => { if (a.isLeaf !== b.isLeaf) return a.isLeaf ? 1 : -1; return a.name.localeCompare(b.name) })"
113128
:key="child.name"
114129
:node="child"
115130
:depth="depth + 1"
@@ -118,13 +133,8 @@ const color = getHashColorFromString(props.node.fullPath)
118133
:pending="pending"
119134
:is-static="isStatic"
120135
@invoke="emit('invoke', $event)"
136+
@update-args="(n, v) => emit('updateArgs', n, v)"
121137
/>
122138
</div>
123139
</div>
124140
</template>
125-
126-
<script lang="ts">
127-
export default {
128-
name: 'FunctionsTreeNode'
129-
}
130-
</script>

0 commit comments

Comments
 (0)