Skip to content

090#33

Open
alvagante wants to merge 9 commits intomainfrom
090
Open

090#33
alvagante wants to merge 9 commits intomainfrom
090

Conversation

@alvagante
Copy link
Member

No description provided.

- Delete orphaned database schema files (audit-schema.sql, migrations.sql, rbac-schema.sql)
- Rename initial migration to 000_initial_schema.sql for clarity
- Update DatabaseService to load only numbered migrations instead of base schema files
- Move all schema definitions to the migrations directory as single source of truth
- Add documentation in copilot-instructions.md explaining migration-first approach
- Create internal task documentation for database schema cleanup process
- Eliminate duplicate table definitions that existed across base schemas and migrations
…a file

- Update COPY instruction to include all database files and migrations
- Change from copying only schema.sql to copying entire src/database/ directory
- Ensures future database-related files are automatically included in builds
- Improves maintainability by avoiding need to update Dockerfile when new database files are added
…tern

- Add new Proxmox integration with ProxmoxClient, ProxmoxService, and ProxmoxIntegration classes
- Implement Proxmox API client with authentication and resource management capabilities
- Add comprehensive test coverage for Proxmox integration and service layer
- Update IntegrationManager to register and manage Proxmox integration
- Add dedicated Proxmox routes handler for API endpoints
- Update integration types to include Proxmox configuration schema
- Refactor ConfigService and schema to support Proxmox settings
- Update server configuration to include Proxmox routes
- Add Kiro specification files for puppet-pabawi refactoring workflow
- Update vitest configuration for improved test execution
- Improves infrastructure flexibility by adding virtualization platform support alongside existing integrations
…ycle management

- Add ProvisionPage with dynamic form generation for VM and LXC creation
- Add ManageTab component for node lifecycle actions (start, stop, reboot, destroy)
- Add ProxmoxProvisionForm and ProxmoxSetupGuide components for integration setup
- Add formGenerator utility for dynamic form rendering based on capability metadata
- Add permissions system for RBAC-aware UI element visibility
- Add comprehensive validation and error handling for provisioning operations
- Add test utilities and generators for provisioning-related tests
- Add documentation for Proxmox setup, provisioning, permissions, and management workflows
- Add Kiro specification files for Proxmox frontend UI and integration features
- Update Navigation component to include new Provision page route
- Update IntegrationSetupPage to support Proxmox configuration
- Update API client with provisioning endpoints and type definitions
- Update package.json with required dependencies
Copilot AI review requested due to automatic review settings March 11, 2026 20:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Proxmox provisioning and lifecycle management support across backend + frontend, including a new Provision page, Manage tab actions, and migration-first DB packaging updates.

Changes:

  • Frontend: adds /provision route + navigation gating, new ManageTab, and several accessibility-oriented UI tweaks.
  • Backend: registers Proxmox plugin, adds provisioning discovery endpoint, adds node lifecycle/destroy endpoints, and extends node linking to retain per-source identifiers.
  • Ops/Docs/Tests: migration-first DB packaging updates, new Proxmox tests + generators, and updated documentation/version bumps to 0.9.0.

Reviewed changes

Copilot reviewed 74 out of 103 changed files in this pull request and generated 21 comments.

Show a summary per file
File Description
frontend/src/components/PackageInstallInterface.svelte Adds header icon and adjusts execution-tool selector markup.
frontend/src/components/Navigation.svelte Adds Provision nav item gated by provisioning permission; bumps displayed version.
frontend/src/components/ManageTab.svelte New node lifecycle management UI + confirmation dialog.
frontend/src/components/IntegrationBadge.svelte Adds “Proxmox” label.
frontend/src/components/InstallSoftwareForm.svelte Adjusts execution-tool selector markup.
frontend/src/components/GroupActionModal.svelte Removes tabindex from scrollable target list region.
frontend/src/components/FactsViewer.svelte Adjusts source/category selector markup; adds ARIA grouping.
frontend/src/components/ExecuteTaskForm.svelte Adjusts “Select Task” label markup.
frontend/src/components/ExecuteCommandForm.svelte Adjusts execution-tool selector markup; adds ARIA grouping.
frontend/src/components/AnsiblePlaybookInterface.svelte Adds header icon.
frontend/src/tests/generators.ts New fast-check generators for provisioning UI tests.
frontend/src/tests/generators.test.ts Tests validating the new fast-check generators.
frontend/src/tests/README.md Documentation for property-based generators and usage.
frontend/src/App.svelte Registers new /provision route.
frontend/package.json Bumps version to 0.9.0; adds fast-check + jest-dom dev deps.
docs/provisioning-guide.md New user documentation for provisioning workflows.
docs/development/BACKEND_CODE_ANALYSIS.md Updates DB schema info to migration-first.
backend/vitest.config.ts Includes Proxmox integration tests in Vitest config.
backend/test/integrations/NodeLinkingService.test.ts Adds coverage for per-source node identifier preservation.
backend/test/integrations/IntegrationManager.test.ts Expands node dedupe assertions and adds provisioning-capabilities tests.
backend/src/server.ts Registers Proxmox integration when configured; logs setup info.
backend/src/routes/streaming.ts Adds “token in query param” fallback for EventSource auth.
backend/src/routes/inventory.ts Adds node lifecycle action + destroy endpoints for Proxmox nodes.
backend/src/routes/integrations/status.ts Adds “proxmox not configured” status entry.
backend/src/routes/integrations/provisioning.ts New provisioning integration discovery endpoint.
backend/src/routes/integrations.ts Mounts Proxmox + provisioning routers with auth/RBAC when available.
backend/src/integrations/types.ts Adds ProvisioningCapability interface.
backend/src/integrations/proxmox/types.ts New Proxmox integration type definitions + error types.
backend/src/integrations/proxmox/tests/ProxmoxIntegration.test.ts New unit tests for ProxmoxIntegration.
backend/src/integrations/proxmox/ProxmoxIntegration.ts New Proxmox plugin implementing info + execution tool interfaces.
backend/src/integrations/proxmox/ProxmoxClient.ts New Proxmox API client with retries + task polling.
backend/src/integrations/NodeLinkingService.ts Adds sourceData to linked nodes; adjusts identifier extraction.
backend/src/integrations/IntegrationManager.ts Changes aggregated nodes to LinkedNode[]; adds provisioning capability aggregation.
backend/src/database/rbac-schema.sql Removes legacy RBAC schema file (migration-first).
backend/src/database/migrations/000_initial_schema.sql Adds header comments to initial migration.
backend/src/database/migrations.sql Removes legacy monolithic migrations file.
backend/src/database/audit-schema.sql Removes legacy audit schema file (migration-first).
backend/src/database/DatabaseService.ts Removes schema-file loading; runs migrations only.
backend/src/config/schema.ts Adds Zod schema for Proxmox integration config.
backend/src/config/ConfigService.ts Parses Proxmox env vars into integration config.
backend/package.json Bumps version to 0.9.0; copies migrations directory in build.
Dockerfile Copies full src/database/ into image dist/database/.
CLAUDE.md Updates DB schema notes to migration-first approach.
.kiro/todo/proxmox-ssl-fix.md Notes about Proxmox SSL workaround.
.kiro/todo/proxmox-restart-required.md Notes about stale compiled code requiring restart.
.kiro/todo/provisioning-endpoint-fix.md Notes about provisioning endpoint being added.
.kiro/todo/node-linking-redesign.md Notes about node linking redesign using sourceData.
.kiro/todo/expert-mode-prototype-pollution.md Adds todo note about prototype pollution hardening.
.kiro/todo/docker-missing-schema-files.md Notes about Docker schema packaging fix.
.kiro/todo/database-schema-cleanup-task.md Notes about schema cleanup and migration-first completion.
.kiro/steering/security-best-practices.md Adds note about secret allowlist pragma; contains a typo.
.kiro/specs/puppet-pabawi-refactoring/tasks.md Adds spec tasks doc for puppet refactor.
.kiro/specs/puppet-pabawi-refactoring/requirements.md Adds spec requirements doc for puppet refactor.
.kiro/specs/puppet-pabawi-refactoring/.config.kiro Adds Kiro spec configuration.
.kiro/specs/proxmox-integration/requirements.md Adds Proxmox integration requirements doc.
.kiro/specs/proxmox-integration/.config.kiro Adds Kiro spec configuration.
.kiro/specs/proxmox-frontend-ui/tasks.md Adds Proxmox frontend UI implementation plan.
.kiro/specs/proxmox-frontend-ui/requirements.md Adds Proxmox frontend UI requirements doc.
.kiro/specs/proxmox-frontend-ui/.config.kiro Adds Kiro spec configuration.
.kiro/database-cleanup-prompt.md Adds prompt doc for DB schema cleanup.
.github/copilot-instructions.md Updates DB schema notes to migration-first approach.

return;
}

const proxmoxSource = integrationManager.getInformationSource("proxmox");
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The route calls executeAction with a non-Action payload ({ action, target }), but the plugin API elsewhere uses an Action type (e.g., including type: "task"). This will very likely break at runtime if the underlying Proxmox execution path expects action.type or other required fields. Prefer retrieving the execution tool (integrationManager.getExecutionTool("proxmox")) and calling executeAction with the correct Action shape (including type) instead of casting an information source to an execution tool.

Copilot uses AI. Check for mistakes.
Comment on lines +1193 to +1201
// Execute the action
const proxmoxService = proxmoxSource as unknown as {
executeAction: (action: { action: string; target: string }) => Promise<unknown>;
};

const result = await proxmoxService.executeAction({
action: body.action,
target: nodeId,
});
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The route calls executeAction with a non-Action payload ({ action, target }), but the plugin API elsewhere uses an Action type (e.g., including type: "task"). This will very likely break at runtime if the underlying Proxmox execution path expects action.type or other required fields. Prefer retrieving the execution tool (integrationManager.getExecutionTool("proxmox")) and calling executeAction with the correct Action shape (including type) instead of casting an information source to an execution tool.

Copilot uses AI. Check for mistakes.
return;
}

const proxmoxSource = integrationManager.getInformationSource("proxmox");
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getInformationSource("proxmox") returns an information-source plugin, but destroyGuest is not part of that interface (and ProxmoxIntegration in this PR doesn’t expose a destroyGuest method). This cast is likely to fail at runtime. A safer design is to perform destroy via the execution tool interface (e.g., executeAction with a destroy action), or to expose a typed destroy method on the Proxmox execution plugin and retrieve it via getExecutionTool("proxmox").

Copilot uses AI. Check for mistakes.
Comment on lines +1343 to +1347
const proxmoxService = proxmoxSource as unknown as {
destroyGuest: (node: string, vmid: number) => Promise<unknown>;
};

const result = await proxmoxService.destroyGuest(node, vmid);
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getInformationSource("proxmox") returns an information-source plugin, but destroyGuest is not part of that interface (and ProxmoxIntegration in this PR doesn’t expose a destroyGuest method). This cast is likely to fail at runtime. A safer design is to perform destroy via the execution tool interface (e.g., executeAction with a destroy action), or to expose a typed destroy method on the Proxmox execution plugin and retrieve it via getExecutionTool("proxmox").

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +55
// If token is in query param, move it to Authorization header for middleware
if (req.query.token && typeof req.query.token === 'string') {
req.headers.authorization = `Bearer ${req.query.token}`;
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepting bearer tokens via query string is high risk (URLs end up in logs, browser history, proxies, and referrers). If this fallback is required for EventSource, consider tightening it: only set the header when no Authorization header exists, ensure access logs (and any expert/debug logs) never record req.originalUrl unredacted, and set SSE responses to Cache-Control: no-store to reduce accidental persistence. Also consider a short-lived one-time stream token flow instead of reusing the main JWT in the URL.

Suggested change
// If token is in query param, move it to Authorization header for middleware
if (req.query.token && typeof req.query.token === 'string') {
req.headers.authorization = `Bearer ${req.query.token}`;
// If token is in query param, move it to Authorization header for middleware,
// but only when no Authorization header is already present. Also remove the
// token from the query to reduce the chance of it being logged downstream.
if (
typeof req.query.token === "string" &&
!req.headers.authorization
) {
req.headers.authorization = `Bearer ${req.query.token}`;
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete (req.query as any).token;

Copilot uses AI. Check for mistakes.
Comment on lines +323 to +330
<div
class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-900 dark:bg-opacity-75"
onclick={cancelConfirmation}
onkeydown={(e) => e.key === 'Escape' && cancelConfirmation()}
role="button"
tabindex="-1"
aria-label="Close dialog"
></div>
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With tabindex="-1", this overlay won’t receive keyboard focus via Tab, so the onkeydown handler is unlikely to fire for typical users. If Escape-to-close is required, attach the Escape key handler to the dialog container (or window) rather than relying on an unfocusable overlay, and ensure focus management for the modal (initial focus + trapping) so keyboard users can interact reliably.

Copilot uses AI. Check for mistakes.
- Validate all user inputs
- Use parameterized queries to prevent SQL injection
- Implement proper authentication and authorization
- Use pragma: allowlist secret comment to lint secrets catched by precommit
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: change 'catched' to 'caught' (and consider rephrasing to 'to allowlist secrets caught by pre-commit').

Suggested change
- Use pragma: allowlist secret comment to lint secrets catched by precommit
- Use pragma: allowlist secret comment to allowlist secrets caught by pre-commit

Copilot uses AI. Check for mistakes.
name: "proxmox",
type: "both",
config: proxmoxConfig as unknown as Record<string, unknown>,
priority: proxmoxConfig.priority ?? 7, // Between Puppetserver (8) and Hiera (6)
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline priority comment looks inconsistent with the repository’s stated priority scheme (e.g., Puppetserver typically has a much higher priority than single digits). If the numeric scale has changed, update the comment to match the actual priority conventions; otherwise, correct the referenced values to avoid misleading future changes.

Suggested change
priority: proxmoxConfig.priority ?? 7, // Between Puppetserver (8) and Hiera (6)
priority: proxmoxConfig.priority ?? 7, // Default 7: between Bolt/PuppetDB (10) and Hiera (6)

Copilot uses AI. Check for mistakes.
* Note: RBAC middleware should be applied at the route mounting level in server.ts
* Required permission: lifecycle:* or lifecycle:{action}
*/
router.post(
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New API surface (POST /api/nodes/:id/action and DELETE /api/nodes/:id) introduces important lifecycle/destructive behavior, but there are no accompanying route-level tests here. Add backend tests validating: (1) only supported Proxmox node ids are accepted, (2) correct integration method is invoked with the correct action payload, and (3) error/status codes (400/503/500) match the intended contract.

Copilot uses AI. Check for mistakes.
* Note: RBAC middleware should be applied at the route mounting level in server.ts
* Required permission: lifecycle:destroy
*/
router.delete(
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New API surface (POST /api/nodes/:id/action and DELETE /api/nodes/:id) introduces important lifecycle/destructive behavior, but there are no accompanying route-level tests here. Add backend tests validating: (1) only supported Proxmox node ids are accepted, (2) correct integration method is invoked with the correct action payload, and (3) error/status codes (400/503/500) match the intended contract.

Copilot uses AI. Check for mistakes.
- Move 7 completed task documents from .kiro/todo to .kiro/done directory
- Add comprehensive REMAINING_TODOS_REPORT.md with prioritized task breakdown
- Include test failure analysis, RBAC issues, and environment configuration items
- Add SQLite test database temporary files (test-migration.db-shm, test-migration.db-wal)
- Update frontend logger with minor improvements
- Consolidate task tracking and provide clear roadmap for remaining work
- Add getNodes() method to retrieve PVE cluster nodes with status and resource info
- Add getNextVMID() method to fetch next available VM ID from cluster
- Add getISOImages() method to list ISO images available on node storage
- Add getTemplates() method to list OS templates available on node storage
- Implement caching for node and resource queries (60-120 second TTL)
- Add corresponding integration layer methods to expose Proxmox service capabilities
- Update frontend navigation and routing to support new provisioning workflows
- Enhance ProxmoxProvisionForm with node selection and resource discovery UI
- Update API client and type definitions for provisioning operations
- Improve error handling and logging across Proxmox integration layer
- Update foundFilter initial state from 'all' to 'found' for better UX
- Aligns with filterMode default behavior to show relevant data by default
- Reduces noise by filtering out not-found entries on initial load
Copilot AI review requested due to automatic review settings March 14, 2026 14:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 72 out of 118 changed files in this pull request and generated 11 comments.

{#each displayableActions as action}
<button
type="button"
onclick={() => executeAction(action.name)}
Comment on lines +325 to +326
onclick={cancelConfirmation}
onkeydown={(e) => e.key === 'Escape' && cancelConfirmation()}
Comment on lines +1195 to +1198
executeAction: (action: { action: string; target: string }) => Promise<unknown>;
};

const result = await proxmoxService.executeAction({

const node = parts[1];
const vmid = parseInt(parts[2], 10);

Comment on lines +171 to +172
// Combine all URIs
linkedNode.uri = Array.from(new Set(allUris)).join(", ");
Comment on lines +52 to +55
// Handle token from query parameter (EventSource doesn't support headers)
// If token is in query param, move it to Authorization header for middleware
if (req.query.token && typeof req.query.token === 'string') {
req.headers.authorization = `Bearer ${req.query.token}`;
Comment on lines +68 to +84
// Check Proxmox integration
const proxmox = integrationManager.getExecutionTool("proxmox") as ProxmoxIntegration | null;

if (proxmox) {
// Determine integration status based on health check
let status: 'connected' | 'degraded' | 'not_configured' = 'not_configured';
const healthCheck = proxmox.getLastHealthCheck();

if (healthCheck) {
if (healthCheck.healthy) {
status = 'connected';
} else if (healthCheck.message?.includes('not initialized') || healthCheck.message?.includes('disabled')) {
status = 'not_configured';
} else {
status = 'degraded';
}
}
<div
class="max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-900/50"
role="region"
aria-labelledby="target-nodes-label"
Comment on lines +188 to +190
<svg class="h-6 w-6 text-gray-700 dark:text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
- Validate all user inputs
- Use parameterized queries to prevent SQL injection
- Implement proper authentication and authorization
- Use pragma: allowlist secret comment to lint secrets catched by precommit
…ved API handling

- Fix ProxmoxClient to use form-urlencoded encoding for POST/PUT/DELETE requests instead of JSON, matching Proxmox API requirements
- Add detailed error messages in API responses by including response body text for better diagnostics
- Add getStorages() method to ProxmoxService and ProxmoxIntegration to query available storage devices on nodes with optional content type filtering
- Add getNetworkBridges() method to ProxmoxService and ProxmoxIntegration to query network interfaces on nodes with bridge type filtering
- Implement caching for both storage and network queries with 120-second TTL to reduce API calls
- Update ProxmoxProvisionForm frontend component to use new storage and network discovery endpoints
- Extend provisioning types to support storage and network configuration options
- Update API client to expose new storage and network discovery endpoints
@alvagante
Copy link
Member Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Contributor

Copilot AI commented Mar 14, 2026

@alvagante I've opened a new pull request, #35, to work on those changes. Once the pull request is ready, I'll request review from you.

… and code quality improvements

Co-authored-by: alvagante <283804+alvagante@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 14, 2026 18:51
asyncHandler(async (req: Request, res: Response): Promise<void> => {
const startTime = Date.now();
const expertModeService = new ExpertModeService();
const requestId = req.id ?? expertModeService.generateRequestId();
asyncHandler(async (req: Request, res: Response): Promise<void> => {
const startTime = Date.now();
const expertModeService = new ExpertModeService();
const requestId = req.id ?? expertModeService.generateRequestId();
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 71 out of 117 changed files in this pull request and generated 10 comments.

Comment on lines +276 to +279
<div class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Execution Tool
</label>
<div class="flex gap-2">
</div>
<div class="flex gap-2" role="group" aria-label="Execution Tool">
Comment on lines +209 to +212
<div class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Facts Source
</label>
<div class="flex flex-wrap gap-2">
</div>
<div class="flex flex-wrap gap-2" role="group" aria-label="Facts Source">
Comment on lines +237 to +240
<div class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Facts Category
</label>
<div class="flex flex-wrap gap-2">
</div>
<div class="flex flex-wrap gap-2" role="group" aria-label="Facts Category">
Comment on lines +264 to +266
<div class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Select Task <span class="text-red-500">*</span>
</label>
</div>
Comment on lines +333 to +339
<div
class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-900 dark:bg-opacity-75"
onclick={cancelConfirmation}
role="button"
tabindex="0"
aria-label="Close dialog"
></div>
Comment on lines +1352 to +1357
const result = await proxmoxTool.executeAction({
type: "task",
target: nodeId,
action: "destroy_vm",
parameters: { node, vmid },
});
Comment on lines +46 to +51
const proxmox = integrationManager.getExecutionTool("proxmox") as ProxmoxIntegration | null;

if (proxmox) {
// Determine integration status based on health check
let status: 'connected' | 'degraded' | 'not_configured' = 'not_configured';
const healthCheck = proxmox.getLastHealthCheck();
Comment on lines +52 to +62
if (config.ssl && config.ssl.rejectUnauthorized === false) {
this.logger.warn(
"Proxmox ssl.rejectUnauthorized=false is set, but per-client TLS bypass is not yet implemented. " +
"Proxmox connections will use the default TLS verification. " +
"Configure a trusted CA certificate (ssl.ca) to connect to Proxmox with self-signed certs.",
{
component: "ProxmoxClient",
operation: "constructor",
}
);
}
Comment on lines +1130 to +1131
const expertModeService = new ExpertModeService();
const requestId = req.id ?? expertModeService.generateRequestId();
Comment on lines +247 to +260
getAllProvisioningCapabilities(): Array<{
source: string;
capabilities: Array<{
name: string;
description: string;
operation: "create" | "destroy";
parameters: Array<{
name: string;
type: string;
required: boolean;
default?: unknown;
}>;
}>;
}> {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants