Types
TypeScript type definitions used throughout the SDK. All types are exported from @hotbunny/hackhub-content-sdk.
Quest Types
QuestRewards
interface QuestRewards {
money: number;
xp?: number;
}QuestEmployer
interface QuestEmployer {
firstName: string;
lastName: string;
email: string;
avatar?: string;
}QuestObjectiveDefinition
interface QuestObjectiveDefinition {
name: string;
description: string;
info?: string;
hint?: string;
terminalCommand?: string;
hidden?: boolean;
unlocksAfter?: string[];
trigger?: QuestObjectiveTrigger;
}QuestObjectiveTrigger
interface QuestObjectiveTrigger {
event: string;
condition: (data: any) => boolean;
}QuestMailDefinition
interface QuestMailDefinition {
title: string;
content: string;
replyable?: boolean;
attachment?: {
name: string;
extension?: string;
content?: string;
};
}QuestDialogDefinition
type QuestDialogDefinition = Record<string, QuestDialogSpeech[]>;QuestDialogSpeech
interface QuestDialogSpeech {
speaker: string;
text: string;
audio?: string;
isEnd?: boolean;
timeout?: number;
onEnd?: () => void;
options?: QuestDialogOption[];
}QuestDialogOption
interface QuestDialogOption {
label: string;
text: string;
audio?: string;
switchBranch?: string;
nextIndex?: number;
isEnd?: boolean;
timeout?: number;
onSelect?: () => void;
}Social Integration Types (Quests)
TwotterAccountDefinition
interface TwotterAccountDefinition {
id?: string;
username?: string;
firstName?: string;
lastName?: string;
avatar?: string;
bio?: string;
verified?: boolean;
}TweetDefinition
interface TweetDefinition {
content: string;
userId?: string;
interaction?: { comments: number; share: number; likes: number; views: number };
showInTimeline?: boolean;
}KisscordChatDefinition
interface KisscordChatDefinition {
userId: string;
messages: KisscordMessageDefinition[];
}KisscordMessageDefinition
interface KisscordMessageDefinition {
content: string;
username?: string;
isMine?: boolean;
delayMs?: number;
// Objective name(s) that must ALL be completed before this message (and the
// messages chained after it) appear. Messages before the first gated message
// play at quest start; the chain then pauses until these objectives complete.
// Available since SDK v0.18.0.
unlocksAfter?: string[];
onSent?: () => void | Promise<void>;
}Gated conversations (
unlocksAfter) — By default a chat plays its whole chain back-to-back. AddunlocksAfterto a message to hold it (and everything chained after it) until the listed quest objectives are all complete, so a conversation can reveal later replies as the player progresses:typescriptKisscordChats = [{ contactId: "slate", messages: [ { content: "you awake", delayMs: 500 }, // plays at start { content: "check /arc/ on 4chan", delayMs: 1300 }, // plays at start { content: "found the handle", isMine: true, unlocksAfter: ["run-whois"] }, // waits for run-whois { content: "good enough.", delayMs: 1200, unlocksAfter: ["run-whois", "open-dead-handles-room"] }, ], }];
WeeChatChatDefinition
interface WeeChatChatDefinition {
host: string;
password: string;
messages: WeeChatMessageDefinition[];
}WeeChatMessageDefinition
interface WeeChatMessageDefinition {
content: string;
username?: string;
isMine?: boolean;
delayMs?: number;
onSent?: () => void | Promise<void>;
}Website Types
WebsitePageDefinition
interface WebsitePageDefinition {
path: string;
title: string;
html: string;
seo?: boolean;
}App Types
AppSize
interface AppSize {
width: number;
height: number;
}AppStoreDefinition
interface AppStoreDefinition {
title: string;
ratings: number;
description: string;
price?: number;
}Command Types
CommandAutoComplete
interface CommandAutoComplete {
label: string;
type: AutoCompleteType;
extension?: string;
isFolder?: boolean;
}AutoCompleteType
type AutoCompleteType = "IP" | "PORT" | "STRING" | "DOMAIN" | "MAC" | "FILE";CommandTools
interface CommandTools {
println(content: Printable): void;
printError(text: string): void;
printWarning(text: string): void;
printSuccess(text: string): void;
printInfo(text: string): void;
printColor(text: string, color: PrintColor): void;
printTable(headers: string[], rows: string[][]): void;
newLine(): void;
clear(): void;
prompt(input: string | PromptOptions): Promise<string>;
sleep(ms: number): Promise<void>;
getArgs(): string[];
parseFlags(): ParsedFlags;
exec(command: string): Promise<void>;
isLocked(): boolean;
lock(): void;
unlock(): void;
}PromptOptions
Options for tools.prompt(). Pass instead of a plain label string to mask the input (e.g. for passwords) so typed characters are not echoed in plaintext.
interface PromptOptions {
label: string; // text shown before the input (e.g. "Password >")
password?: boolean; // mask typed characters as "*"
color?: string; // optional label color (named color or hex)
}PrintColor
A named color or a hex string used for colored terminal output.
type PrintColor =
| "red" | "green" | "yellow" | "blue" | "cyan" | "magenta"
| "gray" | "white" | "orange" | "purple" | "pink"
| (string & {}); // any hex value, e.g. "#ff8800"TextSegment
A styled piece of text. Combine several in an array to build one richly formatted line.
interface TextSegment {
text: string;
color?: PrintColor;
bold?: boolean;
italic?: boolean;
underline?: boolean;
dim?: boolean; // rendered faded (lower opacity)
}Printable
Anything println accepts: a plain string, a single styled segment, or an array mixing strings and segments (rendered on one line).
type Printable = string | TextSegment | Array<string | TextSegment>;ParsedFlags
interface ParsedFlags {
flags: Record<string, string | boolean>;
positional: string[];
}Network Types
NetworkPort
interface NetworkPort {
external: number;
internal: number;
active?: boolean;
locked?: boolean;
service?: string;
version?: string;
}NetworkUser
interface NetworkUser {
username: string;
password?: string;
firstName?: string;
lastName?: string;
online?: boolean;
files?: NetworkFileMap[];
acceptReverseTCP?: boolean;
email?: { address: string; password: string };
}FirewallRule
interface FirewallRule {
allowed: boolean;
port: number;
source?: string;
destination?: string;
locked?: boolean;
}NetworkDeviceType
enum NetworkDeviceType {
Router = "ROUTER",
Device = "DEVICE",
Firewall = "FIREWALL",
Splitter = "SPLITTER",
Printer = "PRINTER",
}Mod Types
ModManifest
interface ModManifest {
id: string;
name: string;
version: string;
author: string;
description: string;
apiVersion?: number;
dependencies?: string[];
permissions?: ModPermission[];
icon?: string;
cover?: string;
workshopId?: string;
workshopUploadedVersion?: string;
source?: ModSource;
tags?: string[];
}ModSource
type ModSource = "local" | "workshop";ModPermission
type ModPermission = "filesystem" | "network" | "events" | "mail" | "bank" | "shell" | "ui";ModInfo
interface ModInfo {
id: string;
name: string;
version: string;
author: string;
description: string;
icon?: string;
cover?: string;
enabled: boolean;
status?: ModStatus;
error?: string;
permissions?: ModPermission[];
workshopId?: string;
workshopUploadedVersion?: string;
source?: ModSource;
tags?: string[];
workshopNeedsUpdate?: boolean;
}ModStatus
enum ModStatus {
Pending = "PENDING",
Loading = "LOADING",
Loaded = "LOADED",
Error = "ERROR",
Disabled = "DISABLED",
}ModSettingDefinition
interface ModSettingDefinition {
key: string;
label: string;
type: "toggle" | "select" | "text" | "number" | "slider";
default: any;
options?: { label: string; value: string }[];
min?: number;
max?: number;
step?: number;
}