@bohuyeshan/openagent-labforge-core 3.11.1 → 3.11.3
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.ja.md +34 -27
- package/README.ko.md +34 -27
- package/README.md +245 -188
- package/README.ru.md +28 -21
- package/README.zh-cn.md +245 -188
- package/bin/platform.test.ts +21 -20
- package/dist/agents/atlas/default.d.ts +1 -1
- package/dist/agents/atlas/gemini.d.ts +1 -1
- package/dist/agents/atlas/gpt.d.ts +1 -1
- package/dist/agents/bio-methodologist.d.ts +1 -1
- package/dist/agents/bio-pipeline-operator.d.ts +1 -1
- package/dist/agents/builtin-agents/general-agents.d.ts +1 -0
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +2 -0
- package/dist/agents/env-context.d.ts +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/metis.d.ts +1 -1
- package/dist/agents/prometheus/gemini.d.ts +1 -1
- package/dist/agents/prometheus/gpt.d.ts +1 -1
- package/dist/agents/prometheus/interview-mode.d.ts +1 -1
- package/dist/agents/prometheus/plan-generation.d.ts +1 -1
- package/dist/agents/prometheus/plan-template.d.ts +1 -1
- package/dist/agents/prometheus/system-prompt.d.ts +1 -1
- package/dist/agents/types.d.ts +1 -1
- package/dist/cli/config-manager/bun-install.d.ts +6 -1
- package/dist/cli/config-manager/plugin-name-with-version.d.ts +1 -1
- package/dist/cli/doctor/constants.d.ts +1 -1
- package/dist/cli/index.js +763 -467
- package/dist/cli/install-validators.d.ts +1 -0
- package/dist/cli/model-fallback-types.d.ts +1 -0
- package/dist/cli/openai-only-model-catalog.d.ts +3 -0
- package/dist/cli/run/index.d.ts +1 -0
- package/dist/cli/run/model-resolver.d.ts +4 -0
- package/dist/cli/run/types.d.ts +1 -0
- package/dist/cli/types.d.ts +3 -0
- package/dist/config/schema/agent-names.d.ts +3 -1
- package/dist/config/schema/background-task.d.ts +2 -0
- package/dist/config/schema/git-env-prefix.d.ts +5 -0
- package/dist/config/schema/git-master.d.ts +1 -0
- package/dist/config/schema/hooks.d.ts +2 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +54 -1
- package/dist/config/schema.d.ts +1 -0
- package/dist/create-hooks.d.ts +13 -0
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +16 -1
- package/dist/features/background-agent/constants.d.ts +1 -1
- package/dist/features/background-agent/manager.d.ts +20 -4
- package/dist/features/background-agent/process-cleanup.d.ts +1 -1
- package/dist/features/background-agent/remove-task-toast-tracking.d.ts +1 -0
- package/dist/features/background-agent/subagent-spawn-limits.d.ts +23 -0
- package/dist/features/background-agent/task-history.d.ts +1 -0
- package/dist/features/background-agent/task-poller.d.ts +1 -0
- package/dist/features/background-agent/types.d.ts +4 -0
- package/dist/features/claude-code-agent-loader/claude-model-mapper.d.ts +4 -0
- package/dist/features/claude-code-agent-loader/loader.d.ts +3 -3
- package/dist/features/claude-code-agent-loader/types.d.ts +8 -1
- package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +2 -2
- package/dist/features/claude-code-plugin-loader/loader.d.ts +2 -2
- package/dist/features/claude-code-plugin-loader/types.d.ts +1 -1
- package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +1 -1
- package/dist/features/skill-mcp-manager/types.d.ts +4 -0
- package/dist/features/tmux-subagent/index.d.ts +1 -0
- package/dist/features/tmux-subagent/manager.d.ts +5 -0
- package/dist/features/tmux-subagent/pane-state-parser.d.ts +8 -0
- package/dist/features/tmux-subagent/tracked-session-state.d.ts +8 -0
- package/dist/features/tmux-subagent/types.d.ts +2 -0
- package/dist/hooks/atlas/boulder-session-lineage.d.ts +6 -0
- package/dist/hooks/atlas/final-wave-approval-gate.d.ts +4 -0
- package/dist/hooks/atlas/idle-event.d.ts +8 -0
- package/dist/hooks/atlas/resolve-active-boulder-session.d.ts +11 -0
- package/dist/hooks/atlas/tool-execute-after.d.ts +2 -0
- package/dist/hooks/atlas/types.d.ts +2 -0
- package/dist/hooks/atlas/verification-reminders.d.ts +4 -0
- package/dist/hooks/auto-slash-command/hook.d.ts +7 -0
- package/dist/hooks/auto-slash-command/processed-command-store.d.ts +7 -0
- package/dist/hooks/auto-update-checker/checker/sync-package-json.d.ts +7 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +3 -1
- package/dist/hooks/auto-update-checker/constants.d.ts +2 -2
- package/dist/hooks/comment-checker/downloader.d.ts +1 -1
- package/dist/hooks/compaction-context-injector/compaction-context-prompt.d.ts +1 -0
- package/dist/hooks/compaction-context-injector/constants.d.ts +5 -0
- package/dist/hooks/compaction-context-injector/hook.d.ts +5 -1
- package/dist/hooks/compaction-context-injector/recovery-prompt-config.d.ts +6 -0
- package/dist/hooks/compaction-context-injector/recovery.d.ts +6 -0
- package/dist/hooks/compaction-context-injector/session-id.d.ts +2 -0
- package/dist/hooks/compaction-context-injector/session-prompt-config-resolver.d.ts +16 -0
- package/dist/hooks/compaction-context-injector/tail-monitor.d.ts +13 -0
- package/dist/hooks/compaction-context-injector/types.d.ts +43 -0
- package/dist/hooks/compaction-context-injector/validated-model.d.ts +13 -0
- package/dist/hooks/context-window-monitor.d.ts +2 -5
- package/dist/hooks/delegate-task-english-directive/hook.d.ts +14 -0
- package/dist/hooks/delegate-task-english-directive/index.d.ts +1 -0
- package/dist/hooks/gpt-permission-continuation/assistant-message.d.ts +23 -0
- package/dist/hooks/gpt-permission-continuation/constants.d.ts +4 -0
- package/dist/hooks/gpt-permission-continuation/detector.d.ts +1 -0
- package/dist/hooks/gpt-permission-continuation/handler.d.ts +12 -0
- package/dist/hooks/gpt-permission-continuation/index.d.ts +13 -0
- package/dist/hooks/gpt-permission-continuation/session-state.d.ts +15 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/keyword-detector/hook.d.ts +1 -0
- package/dist/hooks/preemptive-compaction.d.ts +2 -5
- package/dist/hooks/ralph-loop/pending-verification-handler.d.ts +16 -0
- package/dist/hooks/runtime-fallback/fallback-bootstrap-model.d.ts +10 -0
- package/dist/hooks/runtime-fallback/fallback-retry-dispatcher.d.ts +11 -0
- package/dist/hooks/runtime-fallback/hook.d.ts +2 -3
- package/dist/hooks/runtime-fallback/last-user-retry-parts.d.ts +4 -0
- package/dist/hooks/runtime-fallback/message-update-handler.d.ts +1 -2
- package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +7 -0
- package/dist/hooks/runtime-fallback/session-messages.d.ts +9 -0
- package/dist/hooks/runtime-fallback/session-status-handler.d.ts +3 -0
- package/dist/hooks/runtime-fallback/types.d.ts +57 -3
- package/dist/hooks/runtime-fallback/visible-assistant-response.d.ts +3 -0
- package/dist/hooks/session-notification-content.d.ts +30 -0
- package/dist/hooks/session-notification-scheduler.d.ts +5 -3
- package/dist/hooks/session-notification.d.ts +2 -0
- package/dist/hooks/start-work/index.d.ts +1 -1
- package/dist/hooks/start-work/worktree-detector.d.ts +7 -0
- package/dist/hooks/todo-continuation-enforcer/constants.d.ts +6 -2
- package/dist/hooks/todo-continuation-enforcer/handler.d.ts +1 -0
- package/dist/hooks/todo-continuation-enforcer/idle-event.d.ts +1 -0
- package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +10 -1
- package/dist/hooks/todo-continuation-enforcer/stagnation-detection.d.ts +6 -0
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +5 -0
- package/dist/hooks/tool-output-truncator.d.ts +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10581 -7245
- package/dist/openagent-labforge.schema.json +70 -4
- package/dist/plugin/hooks/create-continuation-hooks.d.ts +2 -1
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
- package/dist/plugin/normalize-tool-arg-schemas.d.ts +2 -0
- package/dist/plugin/ultrawork-model-override.d.ts +1 -15
- package/dist/plugin/ultrawork-variant-availability.d.ts +6 -0
- package/dist/plugin-dispose.d.ts +10 -0
- package/dist/plugin-handlers/agent-override-protection.d.ts +3 -0
- package/dist/plugin-state.d.ts +5 -0
- package/dist/shared/compaction-agent-config-checkpoint.d.ts +11 -0
- package/dist/shared/context-limit-resolver.d.ts +5 -0
- package/dist/shared/data-path.d.ts +2 -2
- package/dist/shared/dynamic-truncator.d.ts +4 -7
- package/dist/shared/external-plugin-detector.d.ts +1 -1
- package/dist/shared/fallback-chain-from-models.d.ts +3 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/model-error-classifier.d.ts +2 -1
- package/dist/shared/opencode-command-dirs.d.ts +3 -0
- package/dist/shared/plugin-identity.d.ts +7 -0
- package/dist/shared/question-denied-session-permission.d.ts +6 -0
- package/dist/shared/retry-status-utils.d.ts +2 -0
- package/dist/shared/system-directive.d.ts +6 -5
- package/dist/shared/vision-capable-models-cache.d.ts +4 -0
- package/dist/tools/call-omo-agent/background-executor.d.ts +2 -1
- package/dist/tools/call-omo-agent/constants.d.ts +1 -1
- package/dist/tools/call-omo-agent/sync-executor.d.ts +11 -3
- package/dist/tools/call-omo-agent/tools.d.ts +2 -1
- package/dist/tools/delegate-task/cancel-unstable-agent-task.d.ts +2 -0
- package/dist/tools/delegate-task/model-selection.d.ts +1 -0
- package/dist/tools/delegate-task/model-string-parser.d.ts +1 -3
- package/dist/tools/look-at/multimodal-fallback-chain.d.ts +4 -0
- package/dist/tools/lsp/constants.d.ts +1 -0
- package/dist/tools/lsp/directory-diagnostics.d.ts +1 -0
- package/dist/tools/lsp/lsp-client-transport.d.ts +4 -2
- package/dist/tools/lsp/lsp-client-wrapper.d.ts +2 -1
- package/dist/tools/lsp/server-path-bases.d.ts +1 -0
- package/generated/skills-bundles/catalog.json +282 -39
- package/generated/skills-bundles/full/INDEX.md +38 -10
- package/generated/skills-bundles/full/skills/data-analysis/experiment-monitoring/auto-claude__monitor-experiment/SKILL.md +63 -0
- package/generated/skills-bundles/full/skills/data-analysis/experiment-ops/auto-claude__run-experiment/SKILL.md +112 -0
- package/generated/skills-bundles/full/skills/data-analysis/optimization/auto-claude__dse-loop/SKILL.md +279 -0
- package/generated/skills-bundles/full/skills/data-analysis/statistics/auto-claude__analyze-results/SKILL.md +47 -0
- package/generated/skills-bundles/full/skills/data-analysis/visualization/auto-claude__paper-figure/SKILL.md +281 -0
- package/generated/skills-bundles/full/skills/productivity/communication/auto-claude__feishu-notify/SKILL.md +154 -0
- package/generated/skills-bundles/full/skills/productivity/visual-design/auto-claude__pixel-art/SKILL.md +138 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-compile/SKILL.md +252 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-plan/SKILL.md +254 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-write/SKILL.md +310 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-write/templates/iclr2026.tex +84 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-write/templates/icml2025.tex +87 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-write/templates/math_commands.tex +48 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-write/templates/neurips2025.tex +80 -0
- package/generated/skills-bundles/full/skills/research/document-authoring/auto-claude__paper-writing/SKILL.md +255 -0
- package/generated/skills-bundles/full/skills/research/literature-and-web-search/auto-claude__arxiv/SKILL.md +133 -0
- package/generated/skills-bundles/full/skills/research/literature-and-web-search/auto-claude__novelty-check/SKILL.md +87 -0
- package/generated/skills-bundles/full/skills/research/literature-and-web-search/auto-claude__research-lit/SKILL.md +194 -0
- package/generated/skills-bundles/full/skills/research/research-ideation/auto-claude__idea-creator/SKILL.md +228 -0
- package/generated/skills-bundles/full/skills/research/research-ideation/auto-claude__idea-discovery/SKILL.md +186 -0
- package/generated/skills-bundles/full/skills/research/research-ideation/auto-claude__idea-discovery-robot/SKILL.md +351 -0
- package/generated/skills-bundles/full/skills/research/research-ideation/auto-claude__research-pipeline/SKILL.md +174 -0
- package/generated/skills-bundles/full/skills/research/theory-writing/auto-claude__proof-writer/SKILL.md +224 -0
- package/generated/skills-bundles/paper/INDEX.md +40 -0
- package/generated/skills-bundles/paper/skills/data-analysis/experiment-monitoring/auto-claude__monitor-experiment/SKILL.md +63 -0
- package/generated/skills-bundles/paper/skills/data-analysis/experiment-ops/auto-claude__run-experiment/SKILL.md +112 -0
- package/generated/skills-bundles/paper/skills/data-analysis/optimization/auto-claude__dse-loop/SKILL.md +279 -0
- package/generated/skills-bundles/paper/skills/data-analysis/statistics/auto-claude__analyze-results/SKILL.md +47 -0
- package/generated/skills-bundles/paper/skills/data-analysis/visualization/auto-claude__paper-figure/SKILL.md +281 -0
- package/generated/skills-bundles/paper/skills/productivity/communication/auto-claude__feishu-notify/SKILL.md +154 -0
- package/generated/skills-bundles/paper/skills/productivity/visual-design/auto-claude__pixel-art/SKILL.md +138 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-compile/SKILL.md +252 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-plan/SKILL.md +254 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-write/SKILL.md +310 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-write/templates/iclr2026.tex +84 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-write/templates/icml2025.tex +87 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-write/templates/math_commands.tex +48 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-write/templates/neurips2025.tex +80 -0
- package/generated/skills-bundles/paper/skills/research/document-authoring/auto-claude__paper-writing/SKILL.md +255 -0
- package/generated/skills-bundles/paper/skills/research/literature-and-web-search/auto-claude__arxiv/SKILL.md +133 -0
- package/generated/skills-bundles/paper/skills/research/literature-and-web-search/auto-claude__novelty-check/SKILL.md +87 -0
- package/generated/skills-bundles/paper/skills/research/literature-and-web-search/auto-claude__research-lit/SKILL.md +194 -0
- package/generated/skills-bundles/paper/skills/research/research-ideation/auto-claude__idea-creator/SKILL.md +228 -0
- package/generated/skills-bundles/paper/skills/research/research-ideation/auto-claude__idea-discovery/SKILL.md +186 -0
- package/generated/skills-bundles/paper/skills/research/research-ideation/auto-claude__idea-discovery-robot/SKILL.md +351 -0
- package/generated/skills-bundles/paper/skills/research/research-ideation/auto-claude__research-pipeline/SKILL.md +174 -0
- package/generated/skills-bundles/paper/skills/research/theory-writing/auto-claude__proof-writer/SKILL.md +224 -0
- package/package.json +21 -21
- package/generated/skills-bundles/full/skills/engineering/virtualization/skills-main__virtualbox/LICENSE.txt +0 -21
- package/generated/skills-bundles/full/skills/engineering/virtualization/skills-main__virtualbox/SKILL.md +0 -615
- package/generated/skills-bundles/full/skills/engineering/virtualization/skills-main__virtualbox/_meta.json +0 -11
- package/generated/skills-bundles/full/skills/engineering/virtualization/skills-main__virtualbox/scripts/virtualbox-utils.ts +0 -586
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/.clawhubsafe +0 -0
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/LICENSE +0 -21
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/README.md +0 -127
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/SECURITY.md +0 -68
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/SKILL.md +0 -141
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/_meta.json +0 -11
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/scripts/speak.sh +0 -52
- package/generated/skills-bundles/full/skills/productivity/voice-and-accessibility/skills-main__voiceclaw/scripts/transcribe.sh +0 -50
- package/generated/skills-bundles/full/skills/research/media-search/skills-main__youtube-search/LICENSE.txt +0 -21
- package/generated/skills-bundles/full/skills/research/media-search/skills-main__youtube-search/SKILL.md +0 -416
- package/generated/skills-bundles/full/skills/research/media-search/skills-main__youtube-search/_meta.json +0 -11
|
@@ -1,586 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VirtualBox Utility Functions
|
|
3
|
-
*
|
|
4
|
-
* Helper functions for managing VirtualBox VMs programmatically.
|
|
5
|
-
* Requires VBoxManage CLI to be installed and accessible.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { exec } from 'child_process';
|
|
9
|
-
import { promisify } from 'util';
|
|
10
|
-
|
|
11
|
-
const execAsync = promisify(exec);
|
|
12
|
-
|
|
13
|
-
// Default VBoxManage command (can be overridden for different platforms)
|
|
14
|
-
const VBOXMANAGE = process.env.VBOXMANAGE_PATH || 'VBoxManage';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Execute a VBoxManage command
|
|
18
|
-
*/
|
|
19
|
-
async function vboxCommand(args: string): Promise<{ stdout: string; stderr: string }> {
|
|
20
|
-
try {
|
|
21
|
-
const { stdout, stderr } = await execAsync(`${VBOXMANAGE} ${args}`);
|
|
22
|
-
return { stdout, stderr };
|
|
23
|
-
} catch (error: any) {
|
|
24
|
-
throw new Error(`VBoxManage command failed: ${error.message}`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// ============================================
|
|
29
|
-
// VM Listing and Information
|
|
30
|
-
// ============================================
|
|
31
|
-
|
|
32
|
-
interface VMInfo {
|
|
33
|
-
name: string;
|
|
34
|
-
uuid: string;
|
|
35
|
-
state: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* List all registered VMs
|
|
40
|
-
*/
|
|
41
|
-
export async function listVMs(): Promise<VMInfo[]> {
|
|
42
|
-
const { stdout } = await vboxCommand('list vms');
|
|
43
|
-
const vms: VMInfo[] = [];
|
|
44
|
-
|
|
45
|
-
const lines = stdout.trim().split('\n');
|
|
46
|
-
for (const line of lines) {
|
|
47
|
-
if (!line) continue;
|
|
48
|
-
const match = line.match(/^"(.+)"\s+\{(.+)\}$/);
|
|
49
|
-
if (match) {
|
|
50
|
-
vms.push({
|
|
51
|
-
name: match[1],
|
|
52
|
-
uuid: match[2],
|
|
53
|
-
state: 'unknown'
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return vms;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* List all running VMs
|
|
63
|
-
*/
|
|
64
|
-
export async function listRunningVMs(): Promise<VMInfo[]> {
|
|
65
|
-
const { stdout } = await vboxCommand('list runningvms');
|
|
66
|
-
const vms: VMInfo[] = [];
|
|
67
|
-
|
|
68
|
-
const lines = stdout.trim().split('\n');
|
|
69
|
-
for (const line of lines) {
|
|
70
|
-
if (!line) continue;
|
|
71
|
-
const match = line.match(/^"(.+)"\s+\{(.+)\}$/);
|
|
72
|
-
if (match) {
|
|
73
|
-
vms.push({
|
|
74
|
-
name: match[1],
|
|
75
|
-
uuid: match[2],
|
|
76
|
-
state: 'running'
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return vms;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Get detailed information about a VM
|
|
86
|
-
*/
|
|
87
|
-
export async function getVMInfo(vmName: string): Promise<Record<string, string>> {
|
|
88
|
-
const { stdout } = await vboxCommand(`showvminfo "${vmName}" --machinereadable`);
|
|
89
|
-
const info: Record<string, string> = {};
|
|
90
|
-
|
|
91
|
-
const lines = stdout.trim().split('\n');
|
|
92
|
-
for (const line of lines) {
|
|
93
|
-
const match = line.match(/^(.+)="(.*)"$/);
|
|
94
|
-
if (match) {
|
|
95
|
-
info[match[1]] = match[2];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return info;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Check if a VM exists
|
|
104
|
-
*/
|
|
105
|
-
export async function vmExists(vmName: string): Promise<boolean> {
|
|
106
|
-
try {
|
|
107
|
-
const vms = await listVMs();
|
|
108
|
-
return vms.some(vm => vm.name === vmName || vm.uuid === vmName);
|
|
109
|
-
} catch {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Check if a VM is running
|
|
116
|
-
*/
|
|
117
|
-
export async function isVMRunning(vmName: string): Promise<boolean> {
|
|
118
|
-
const running = await listRunningVMs();
|
|
119
|
-
return running.some(vm => vm.name === vmName || vm.uuid === vmName);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// ============================================
|
|
123
|
-
// VM Lifecycle Management
|
|
124
|
-
// ============================================
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Start a VM
|
|
128
|
-
*/
|
|
129
|
-
export async function startVM(vmName: string, headless: boolean = true): Promise<void> {
|
|
130
|
-
const type = headless ? '--type headless' : '';
|
|
131
|
-
await vboxCommand(`startvm "${vmName}" ${type}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Stop a VM gracefully (ACPI shutdown)
|
|
136
|
-
*/
|
|
137
|
-
export async function stopVM(vmName: string): Promise<void> {
|
|
138
|
-
await vboxCommand(`controlvm "${vmName}" acpipowerbutton`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Force stop a VM (power off)
|
|
143
|
-
*/
|
|
144
|
-
export async function forceStopVM(vmName: string): Promise<void> {
|
|
145
|
-
await vboxCommand(`controlvm "${vmName}" poweroff`);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Pause a running VM
|
|
150
|
-
*/
|
|
151
|
-
export async function pauseVM(vmName: string): Promise<void> {
|
|
152
|
-
await vboxCommand(`controlvm "${vmName}" pause`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Resume a paused VM
|
|
157
|
-
*/
|
|
158
|
-
export async function resumeVM(vmName: string): Promise<void> {
|
|
159
|
-
await vboxCommand(`controlvm "${vmName}" resume`);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Reset a VM (hard reboot)
|
|
164
|
-
*/
|
|
165
|
-
export async function resetVM(vmName: string): Promise<void> {
|
|
166
|
-
await vboxCommand(`controlvm "${vmName}" reset`);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Save VM state (hibernate)
|
|
171
|
-
*/
|
|
172
|
-
export async function saveVMState(vmName: string): Promise<void> {
|
|
173
|
-
await vboxCommand(`controlvm "${vmName}" savestate`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ============================================
|
|
177
|
-
// VM Creation and Deletion
|
|
178
|
-
// ============================================
|
|
179
|
-
|
|
180
|
-
interface VMCreateOptions {
|
|
181
|
-
name: string;
|
|
182
|
-
osType?: string;
|
|
183
|
-
memory?: number;
|
|
184
|
-
cpus?: number;
|
|
185
|
-
diskSize?: number;
|
|
186
|
-
diskPath?: string;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Create a new VM
|
|
191
|
-
*/
|
|
192
|
-
export async function createVM(options: VMCreateOptions): Promise<string> {
|
|
193
|
-
const { name, osType = 'Other_64', memory = 2048, cpus = 1, diskSize, diskPath } = options;
|
|
194
|
-
|
|
195
|
-
// Create and register VM
|
|
196
|
-
await vboxCommand(`createvm --name "${name}" --ostype "${osType}" --register`);
|
|
197
|
-
|
|
198
|
-
// Set memory and CPU
|
|
199
|
-
await vboxCommand(`modifyvm "${name}" --memory ${memory} --cpus ${cpus}`);
|
|
200
|
-
|
|
201
|
-
// Create disk if size specified
|
|
202
|
-
if (diskSize && diskPath) {
|
|
203
|
-
await vboxCommand(`createhd --filename "${diskPath}" --size ${diskSize}`);
|
|
204
|
-
await vboxCommand(`storagectl "${name}" --name "SATA Controller" --add sata`);
|
|
205
|
-
await vboxCommand(`storageattach "${name}" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium "${diskPath}"`);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return name;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Delete a VM
|
|
213
|
-
*/
|
|
214
|
-
export async function deleteVM(vmName: string, deleteFiles: boolean = false): Promise<void> {
|
|
215
|
-
const flag = deleteFiles ? '--delete' : '';
|
|
216
|
-
await vboxCommand(`unregistervm "${vmName}" ${flag}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Clone a VM
|
|
221
|
-
*/
|
|
222
|
-
export async function cloneVM(sourceName: string, targetName: string, linked: boolean = false): Promise<void> {
|
|
223
|
-
const options = linked ? '--options link' : '';
|
|
224
|
-
await vboxCommand(`clonevm "${sourceName}" --name "${targetName}" ${options} --register`);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ============================================
|
|
228
|
-
// Snapshot Management
|
|
229
|
-
// ============================================
|
|
230
|
-
|
|
231
|
-
interface SnapshotInfo {
|
|
232
|
-
name: string;
|
|
233
|
-
uuid: string;
|
|
234
|
-
description?: string;
|
|
235
|
-
timestamp?: string;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* List snapshots for a VM
|
|
240
|
-
*/
|
|
241
|
-
export async function listSnapshots(vmName: string): Promise<SnapshotInfo[]> {
|
|
242
|
-
try {
|
|
243
|
-
const { stdout } = await vboxCommand(`snapshot "${vmName}" list --machinereadable`);
|
|
244
|
-
const snapshots: SnapshotInfo[] = [];
|
|
245
|
-
|
|
246
|
-
// Parse machine-readable snapshot output
|
|
247
|
-
const lines = stdout.trim().split('\n');
|
|
248
|
-
const currentSnapshot: Partial<SnapshotInfo> = {};
|
|
249
|
-
|
|
250
|
-
for (const line of lines) {
|
|
251
|
-
// Parse SnapshotName="..."
|
|
252
|
-
// Parse SnapshotUUID="..."
|
|
253
|
-
const nameMatch = line.match(/SnapshotName="(.+)"/);
|
|
254
|
-
const uuidMatch = line.match(/SnapshotUUID="(.+)"/);
|
|
255
|
-
|
|
256
|
-
if (nameMatch) {
|
|
257
|
-
currentSnapshot.name = nameMatch[1];
|
|
258
|
-
}
|
|
259
|
-
if (uuidMatch) {
|
|
260
|
-
currentSnapshot.uuid = uuidMatch[1];
|
|
261
|
-
if (currentSnapshot.name) {
|
|
262
|
-
snapshots.push(currentSnapshot as SnapshotInfo);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return snapshots;
|
|
268
|
-
} catch {
|
|
269
|
-
return [];
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Take a snapshot
|
|
275
|
-
*/
|
|
276
|
-
export async function takeSnapshot(vmName: string, snapshotName: string, description?: string): Promise<void> {
|
|
277
|
-
const desc = description ? `--description "${description}"` : '';
|
|
278
|
-
await vboxCommand(`snapshot "${vmName}" take "${snapshotName}" ${desc}`);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Restore a snapshot
|
|
283
|
-
*/
|
|
284
|
-
export async function restoreSnapshot(vmName: string, snapshotName: string): Promise<void> {
|
|
285
|
-
await vboxCommand(`snapshot "${vmName}" restore "${snapshotName}"`);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Delete a snapshot
|
|
290
|
-
*/
|
|
291
|
-
export async function deleteSnapshot(vmName: string, snapshotName: string): Promise<void> {
|
|
292
|
-
await vboxCommand(`snapshot "${vmName}" delete "${snapshotName}"`);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// ============================================
|
|
296
|
-
// Network Configuration
|
|
297
|
-
// ============================================
|
|
298
|
-
|
|
299
|
-
type NetworkMode = 'none' | 'nat' | 'bridged' | 'hostonly' | 'internal';
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Configure network adapter
|
|
303
|
-
*/
|
|
304
|
-
export async function configureNetwork(
|
|
305
|
-
vmName: string,
|
|
306
|
-
adapter: number,
|
|
307
|
-
mode: NetworkMode,
|
|
308
|
-
options?: { bridgeAdapter?: string; hostOnlyAdapter?: string }
|
|
309
|
-
): Promise<void> {
|
|
310
|
-
let cmd = `modifyvm "${vmName}" --nic${adapter} ${mode}`;
|
|
311
|
-
|
|
312
|
-
if (mode === 'bridged' && options?.bridgeAdapter) {
|
|
313
|
-
cmd += ` --bridgeadapter${adapter} "${options.bridgeAdapter}"`;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (mode === 'hostonly' && options?.hostOnlyAdapter) {
|
|
317
|
-
cmd += ` --hostonlyadapter${adapter} "${options.hostOnlyAdapter}"`;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
await vboxCommand(cmd);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Add NAT port forwarding rule
|
|
325
|
-
*/
|
|
326
|
-
export async function addPortForward(
|
|
327
|
-
vmName: string,
|
|
328
|
-
ruleName: string,
|
|
329
|
-
hostPort: number,
|
|
330
|
-
guestPort: number,
|
|
331
|
-
protocol: 'tcp' | 'udp' = 'tcp',
|
|
332
|
-
adapter: number = 1
|
|
333
|
-
): Promise<void> {
|
|
334
|
-
await vboxCommand(
|
|
335
|
-
`modifyvm "${vmName}" --natpf${adapter} "${ruleName},${protocol},,${hostPort},,${guestPort}"`
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Remove NAT port forwarding rule
|
|
341
|
-
*/
|
|
342
|
-
export async function removePortForward(vmName: string, ruleName: string, adapter: number = 1): Promise<void> {
|
|
343
|
-
await vboxCommand(`modifyvm "${vmName}" --natpf${adapter} delete "${ruleName}"`);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* List host-only interfaces
|
|
348
|
-
*/
|
|
349
|
-
export async function listHostOnlyInterfaces(): Promise<string[]> {
|
|
350
|
-
const { stdout } = await vboxCommand('list hostonlyifs');
|
|
351
|
-
const interfaces: string[] = [];
|
|
352
|
-
|
|
353
|
-
const lines = stdout.split('\n');
|
|
354
|
-
for (const line of lines) {
|
|
355
|
-
const match = line.match(/^Name:\s+(.+)$/);
|
|
356
|
-
if (match) {
|
|
357
|
-
interfaces.push(match[1]);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return interfaces;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// ============================================
|
|
365
|
-
// Resource Configuration
|
|
366
|
-
// ============================================
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Set VM memory
|
|
370
|
-
*/
|
|
371
|
-
export async function setMemory(vmName: string, memoryMB: number): Promise<void> {
|
|
372
|
-
await vboxCommand(`modifyvm "${vmName}" --memory ${memoryMB}`);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Set VM CPU count
|
|
377
|
-
*/
|
|
378
|
-
export async function setCPUs(vmName: string, cpus: number): Promise<void> {
|
|
379
|
-
await vboxCommand(`modifyvm "${vmName}" --cpus ${cpus}`);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Configure VM for performance
|
|
384
|
-
*/
|
|
385
|
-
export async function configurePerformance(
|
|
386
|
-
vmName: string,
|
|
387
|
-
options: {
|
|
388
|
-
nestedVirtualization?: boolean;
|
|
389
|
-
hardwareVirtualization?: boolean;
|
|
390
|
-
largePages?: boolean;
|
|
391
|
-
}
|
|
392
|
-
): Promise<void> {
|
|
393
|
-
const { nestedVirtualization = false, hardwareVirtualization = true, largePages = true } = options;
|
|
394
|
-
|
|
395
|
-
const commands = [
|
|
396
|
-
`--hwvirtex ${hardwareVirtualization ? 'on' : 'off'}`,
|
|
397
|
-
`--nested-hw-virt ${nestedVirtualization ? 'on' : 'off'}`,
|
|
398
|
-
`--largepages ${largePages ? 'on' : 'off'}`
|
|
399
|
-
];
|
|
400
|
-
|
|
401
|
-
await vboxCommand(`modifyvm "${vmName}" ${commands.join(' ')}`);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// ============================================
|
|
405
|
-
// Metrics and Monitoring
|
|
406
|
-
// ============================================
|
|
407
|
-
|
|
408
|
-
interface VMMetrics {
|
|
409
|
-
cpuLoad?: string;
|
|
410
|
-
ramUsage?: string;
|
|
411
|
-
netRate?: string;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Setup metrics collection
|
|
416
|
-
*/
|
|
417
|
-
export async function setupMetrics(vmName: string, period: number = 10, samples: number = 5): Promise<void> {
|
|
418
|
-
await vboxCommand(`metrics setup --period ${period} --samples ${samples} "${vmName}"`);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* Query VM metrics
|
|
423
|
-
*/
|
|
424
|
-
export async function queryMetrics(vmName: string): Promise<VMMetrics> {
|
|
425
|
-
const { stdout } = await vboxCommand(`metrics query "${vmName}" "CPU/Load:RAM/Usage:Net/Rate"`);
|
|
426
|
-
const metrics: VMMetrics = {};
|
|
427
|
-
|
|
428
|
-
const lines = stdout.split('\n');
|
|
429
|
-
for (const line of lines) {
|
|
430
|
-
if (line.includes('CPU/Load')) {
|
|
431
|
-
const match = line.match(/CPU\/Load.*?(\d+\.?\d*%)/);
|
|
432
|
-
if (match) metrics.cpuLoad = match[1];
|
|
433
|
-
}
|
|
434
|
-
if (line.includes('RAM/Usage')) {
|
|
435
|
-
const match = line.match(/RAM\/Usage.*?(\d+\.?\d*\s*[KMG]?B)/);
|
|
436
|
-
if (match) metrics.ramUsage = match[1];
|
|
437
|
-
}
|
|
438
|
-
if (line.includes('Net/Rate')) {
|
|
439
|
-
const match = line.match(/Net\/Rate.*?(\d+\.?\d*\s*[KMG]?B\/s)/);
|
|
440
|
-
if (match) metrics.netRate = match[1];
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
return metrics;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// ============================================
|
|
448
|
-
// Export/Import
|
|
449
|
-
// ============================================
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Export VM to OVA
|
|
453
|
-
*/
|
|
454
|
-
export async function exportVM(vmName: string, outputPath: string): Promise<void> {
|
|
455
|
-
await vboxCommand(`export "${vmName}" --output "${outputPath}"`);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Import VM from OVA
|
|
460
|
-
*/
|
|
461
|
-
export async function importVM(ovaPath: string, vmName?: string): Promise<void> {
|
|
462
|
-
const nameOption = vmName ? `--vsys 0 --vmname "${vmName}"` : '';
|
|
463
|
-
await vboxCommand(`import "${ovaPath}" ${nameOption}`);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// ============================================
|
|
467
|
-
// Utility Functions
|
|
468
|
-
// ============================================
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Wait for VM to reach a specific state
|
|
472
|
-
*/
|
|
473
|
-
export async function waitForState(
|
|
474
|
-
vmName: string,
|
|
475
|
-
targetState: 'running' | 'powered off' | 'saved' | 'paused',
|
|
476
|
-
timeout: number = 60000
|
|
477
|
-
): Promise<boolean> {
|
|
478
|
-
const startTime = Date.now();
|
|
479
|
-
|
|
480
|
-
while (Date.now() - startTime < timeout) {
|
|
481
|
-
const info = await getVMInfo(vmName);
|
|
482
|
-
const state = info.VMState || '';
|
|
483
|
-
|
|
484
|
-
if (targetState === 'running' && state === 'running') return true;
|
|
485
|
-
if (targetState === 'powered off' && state === 'poweroff') return true;
|
|
486
|
-
if (targetState === 'saved' && state === 'saved') return true;
|
|
487
|
-
if (targetState === 'paused' && state === 'paused') return true;
|
|
488
|
-
|
|
489
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
return false;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* Safe shutdown with timeout
|
|
497
|
-
*/
|
|
498
|
-
export async function safeShutdown(vmName: string, timeout: number = 30000): Promise<boolean> {
|
|
499
|
-
await stopVM(vmName);
|
|
500
|
-
const success = await waitForState(vmName, 'powered off', timeout);
|
|
501
|
-
|
|
502
|
-
if (!success) {
|
|
503
|
-
console.log('Graceful shutdown timed out, forcing power off...');
|
|
504
|
-
await forceStopVM(vmName);
|
|
505
|
-
return await waitForState(vmName, 'powered off', 10000);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
return true;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Get VBoxManage version
|
|
513
|
-
*/
|
|
514
|
-
export async function getVersion(): Promise<string> {
|
|
515
|
-
const { stdout } = await vboxCommand('--version');
|
|
516
|
-
return stdout.trim();
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* List available OS types
|
|
521
|
-
*/
|
|
522
|
-
export async function listOSTypes(): Promise<{ id: string; description: string }[]> {
|
|
523
|
-
const { stdout } = await vboxCommand('list ostypes');
|
|
524
|
-
const types: { id: string; description: string }[] = [];
|
|
525
|
-
|
|
526
|
-
const lines = stdout.split('\n');
|
|
527
|
-
let currentId = '';
|
|
528
|
-
let currentDesc = '';
|
|
529
|
-
|
|
530
|
-
for (const line of lines) {
|
|
531
|
-
const idMatch = line.match(/^ID:\s+(.+)$/);
|
|
532
|
-
const descMatch = line.match(/^Description:\s+(.+)$/);
|
|
533
|
-
|
|
534
|
-
if (idMatch) {
|
|
535
|
-
currentId = idMatch[1];
|
|
536
|
-
}
|
|
537
|
-
if (descMatch) {
|
|
538
|
-
currentDesc = descMatch[1];
|
|
539
|
-
if (currentId) {
|
|
540
|
-
types.push({ id: currentId, description: currentDesc });
|
|
541
|
-
currentId = '';
|
|
542
|
-
currentDesc = '';
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
return types;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// Export all functions
|
|
551
|
-
export default {
|
|
552
|
-
listVMs,
|
|
553
|
-
listRunningVMs,
|
|
554
|
-
getVMInfo,
|
|
555
|
-
vmExists,
|
|
556
|
-
isVMRunning,
|
|
557
|
-
startVM,
|
|
558
|
-
stopVM,
|
|
559
|
-
forceStopVM,
|
|
560
|
-
pauseVM,
|
|
561
|
-
resumeVM,
|
|
562
|
-
resetVM,
|
|
563
|
-
saveVMState,
|
|
564
|
-
createVM,
|
|
565
|
-
deleteVM,
|
|
566
|
-
cloneVM,
|
|
567
|
-
listSnapshots,
|
|
568
|
-
takeSnapshot,
|
|
569
|
-
restoreSnapshot,
|
|
570
|
-
deleteSnapshot,
|
|
571
|
-
configureNetwork,
|
|
572
|
-
addPortForward,
|
|
573
|
-
removePortForward,
|
|
574
|
-
listHostOnlyInterfaces,
|
|
575
|
-
setMemory,
|
|
576
|
-
setCPUs,
|
|
577
|
-
configurePerformance,
|
|
578
|
-
setupMetrics,
|
|
579
|
-
queryMetrics,
|
|
580
|
-
exportVM,
|
|
581
|
-
importVM,
|
|
582
|
-
waitForState,
|
|
583
|
-
safeShutdown,
|
|
584
|
-
getVersion,
|
|
585
|
-
listOSTypes
|
|
586
|
-
};
|
|
File without changes
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 M Asif Rahman (https://github.com/Asif2BD)
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|