[{"data":1,"prerenderedAt":741},["ShallowReactive",2],{"docs-doc-en-contributing":3,"docs-list-en":650},{"doc":4,"locale":331,"available":648},{"id":5,"title":6,"body":7,"description":637,"extension":638,"group":439,"meta":639,"navigation":640,"order":641,"path":642,"section":643,"seo":644,"stem":645,"updated":646,"__hash__":647},"docs_en\u002Fdocs\u002Fcontributing.md","Contributing",{"type":8,"value":9,"toc":625},"minimark",[10,22,27,111,115,135,142,146,149,182,197,208,212,215,248,271,278,282,289,342,346,363,367,370,378,381,463,477,481,488,499,505,509,516,542,545,548,600,603,606,610,621],[11,12,13,14,21],"p",{},"The code, documentation and translations of SCNexus all come from the community. This page covers where to start and which checks a contribution has to pass. Before you begin, please read the ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus\u002Fblob\u002Fmain\u002FCODE_OF_CONDUCT.english.md",[19],"nofollow","Code of Conduct","; it applies to every space where this project is discussed.",[23,24,26],"h2",{"id":25},"what-you-can-contribute","What you can contribute",[28,29,30,44,54,65,80,100],"ul",{},[31,32,33,37,38,43],"li",{},[34,35,36],"strong",{},"Report a bug",": file it in ",[15,39,42],{"href":40,"rel":41},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus\u002Fissues",[19],"Issues"," with the app version, your OS version and reproduction steps; add a screenshot for UI problems.",[31,45,46,49,50,53],{},[34,47,48],{},"Feature requests",": also in ",[15,51,42],{"href":40,"rel":52},[19],"; describing the situation you are in and what you do today is more useful than a list of features.",[31,55,56,59,60,64],{},[34,57,58],{},"Code",": send a Pull Request against ",[61,62,63],"code",{},"main","; the environment and the checks are described under \"Development environment\" and \"Before you submit\" below.",[31,66,67,70,71,74,75,79],{},[34,68,69],{},"UI translations",": the text lives in ",[61,72,73],{},"packages\u002Fapp-renderer-v2\u002Fsrc\u002Flocales"," and all three languages are kept in sync; see ",[15,76,78],{"href":77},"\u002Fdocs\u002Flocalization","Translating the interface"," for the details.",[31,81,82,85,86,91,92,95,96,99],{},[34,83,84],{},"Documentation",": submit it to ",[15,87,90],{"href":88,"rel":89},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus-docs",[19],"scnexus-docs","; Chinese and English live in the ",[61,93,94],{},"content\u002Fzh-CN"," and ",[61,97,98],{},"content\u002Fen"," directories.",[31,101,102,105,106,110],{},[34,103,104],{},"Answering questions",": QQ group and Discord — links are at the end of ",[15,107,109],{"href":108},"\u002Fdocs\u002Foverview","Getting started",".",[23,112,114],{"id":113},"repositories","Repositories",[28,116,117,127],{},[31,118,119,126],{},[34,120,121],{},[15,122,125],{"href":123,"rel":124},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus",[19],"scnexus",": the desktop app — Electron main process, preload, interface and the package standard.",[31,128,129,134],{},[34,130,131],{},[15,132,90],{"href":88,"rel":133},[19],": this site, its documentation and pages.",[11,136,137,138,110],{},"The server and the website are not open source. Issues with those parts can still be filed in the issue tracker, or sent to ",[15,139,141],{"href":140},"mailto:support@scnexus.net","support@scnexus.net",[23,143,145],{"id":144},"development-environment","Development environment",[11,147,148],{},"The desktop app is a pnpm monorepo and requires Node.js 26 and pnpm 11 or later:",[150,151,156],"pre",{"className":152,"code":153,"language":154,"meta":155,"style":155},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","pnpm install\npnpm run dev\n","bash","",[61,157,158,171],{"__ignoreMap":155},[159,160,163,167],"span",{"class":161,"line":162},"line",1,[159,164,166],{"class":165},"sbgvK","pnpm",[159,168,170],{"class":169},"s_sjI"," install\n",[159,172,174,176,179],{"class":161,"line":173},2,[159,175,166],{"class":165},[159,177,178],{"class":169}," run",[159,180,181],{"class":169}," dev\n",[11,183,184,185,190,191,196],{},"Package responsibilities and coding conventions are described in ",[15,186,189],{"href":187,"rel":188},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus\u002Fblob\u002Fmain\u002FAGENTS.md",[19],"AGENTS.md"," (in Chinese); build, Electron smoke test and packaging commands are documented in ",[15,192,195],{"href":193,"rel":194},"https:\u002F\u002Fgithub.com\u002FMengLuoRJ\u002Fscnexus\u002Fblob\u002Fmain\u002Fdocs\u002Fbuilding.md",[19],"docs\u002Fbuilding.md",". The stack is Electron 45 + Vite 8 + Vue 3 (Composition API) + Nuxt UI 4 + Tailwind CSS 4, with Vitest for tests.",[11,198,199,200,203,204,207],{},"The documentation site is a separate Nuxt project: run ",[61,201,202],{},"pnpm install"," and then ",[61,205,206],{},"pnpm dev"," to preview it locally.",[23,209,211],{"id":210},"before-you-submit","Before you submit",[11,213,214],{},"Run the following from the repository root before submitting a code change:",[150,216,218],{"className":152,"code":217,"language":154,"meta":155,"style":155},"pnpm run typecheck\npnpm run lint\npnpm run test\n",[61,219,220,229,238],{"__ignoreMap":155},[159,221,222,224,226],{"class":161,"line":162},[159,223,166],{"class":165},[159,225,178],{"class":169},[159,227,228],{"class":169}," typecheck\n",[159,230,231,233,235],{"class":161,"line":173},[159,232,166],{"class":165},[159,234,178],{"class":169},[159,236,237],{"class":169}," lint\n",[159,239,241,243,245],{"class":161,"line":240},3,[159,242,166],{"class":165},[159,244,178],{"class":169},[159,246,247],{"class":169}," test\n",[28,249,250,257,264],{},[31,251,252,253,256],{},"Tests may be limited to the affected part (for example ",[61,254,255],{},"pnpm run test:main","), but type checking and static analysis must pass in full.",[31,258,259,260,263],{},"If you only changed documentation or configuration, run ",[61,261,262],{},"pnpm run format:check"," at minimum.",[31,265,266,267,270],{},"Verify interface changes at the ",[34,268,269],{},"1000×700"," main window size, which is the design baseline.",[11,272,273,274,277],{},"For documentation changes, run ",[61,275,276],{},"pnpm typecheck"," and check the rendered page and its links locally.",[23,279,281],{"id":280},"code-conventions","Code conventions",[11,283,284,285,288],{},"The full specification is in ",[15,286,189],{"href":187,"rel":287},[19],"; these are the points most easily missed:",[28,290,291,297,303,313,319,336],{},[31,292,293,296],{},[34,294,295],{},"Keep the boundaries."," The main process owns windows, files, the game process and persistence; the renderer only draws the interface. Cross-process work goes through IPC, and packages never import each other's sources.",[31,298,299,302],{},[34,300,301],{},"Types are not a security boundary."," The main process validates arguments and callers at runtime; shared TypeScript types are a development aid only.",[31,304,305,308,309,312],{},[34,306,307],{},"One way to write components."," Single-file components use ",[61,310,311],{},"\u003Cscript lang=\"ts\" setup>"," with the Composition API, and state lives in Composition API Pinia stores.",[31,314,315,318],{},[34,316,317],{},"Layer the feedback."," Operation results use a toast, decisions use a dialog, and persistent context uses an inline notice.",[31,320,321,324,325,328,329,95,332,335],{},[34,322,323],{},"Three languages stay in sync."," When adding or changing text, the ",[61,326,327],{},"zh",", ",[61,330,331],{},"en",[61,333,334],{},"zh-Hant"," keys must match.",[31,337,338,341],{},[34,339,340],{},"No unnecessary abstraction."," Follow the style of the surrounding code, do not design structures for one-off logic, and do not refactor code that already works.",[23,343,345],{"id":344},"pull-requests","Pull requests",[28,347,348,354,357,360],{},[31,349,350,351,353],{},"All pull requests target the ",[61,352,63],{}," branch.",[31,355,356],{},"One pull request does one thing: keep feature work separate from translation and formatting changes so each can be reviewed on its own.",[31,358,359],{},"Describe what changed, why, and how you verified it. Paste the commands you ran.",[31,361,362],{},"For interface changes, attach a screenshot or recording and mention how it looks at 1000×700.",[23,364,366],{"id":365},"contributing-documentation","Contributing documentation",[11,368,369],{},"Content is organised per language, and two files at the same path are the Chinese and English versions of one page:",[150,371,376],{"className":372,"code":374,"language":375},[373],"language-text","content\u002F\n├── zh-CN\u002F\n│   ├── guide\u002F       # SCNexus documentation\n│   ├── editor\u002F      # Editor documentation\n│   └── reference\u002F   # Reference\n└── en\u002F              # same structure as zh-CN\n","text",[61,377,374],{"__ignoreMap":155},[11,379,380],{},"Frontmatter decides where a page appears in the sidebar:",[382,383,384,397],"table",{},[385,386,387],"thead",{},[388,389,390,394],"tr",{},[391,392,393],"th",{},"Field",[391,395,396],{},"Purpose",[398,399,400,411,421,443,453],"tbody",{},[388,401,402,408],{},[403,404,405],"td",{},[61,406,407],{},"title",[403,409,410],{},"Page title and sidebar entry",[388,412,413,418],{},[403,414,415],{},[61,416,417],{},"description",[403,419,420],{},"Page description used for search results and SEO",[388,422,423,428],{},[403,424,425],{},[61,426,427],{},"group",[403,429,430,431,328,434,328,437,328,440],{},"Sidebar group: ",[61,432,433],{},"start",[61,435,436],{},"usage",[61,438,439],{},"contribute",[61,441,442],{},"reference",[388,444,445,450],{},[403,446,447],{},[61,448,449],{},"order",[403,451,452],{},"Sort order within the group; lower numbers come first",[388,454,455,460],{},[403,456,457],{},[61,458,459],{},"updated",[403,461,462],{},"Last updated date, shown under the title",[11,464,465,466,469,470,473,474,476],{},"Link to other pages with a site-absolute path such as ",[61,467,468],{},"\u002Fguide\u002Fcampaign"," — no language prefix and no ",[61,471,472],{},".md"," suffix. Remember to set ",[61,475,449],{}," on new pages, otherwise they land at the end of their group.",[23,478,480],{"id":479},"code-of-conduct","Code of conduct",[11,482,483,484,487],{},"By taking part you agree to follow the ",[15,485,20],{"href":17,"rel":486},[19],", adapted from Contributor Covenant 2.1:",[28,489,490,493,496],{},[31,491,492],{},"Respect different positions, viewpoints and experiences, and criticise ideas rather than people; offer and accept constructive feedback.",[31,494,495],{},"Unacceptable behaviour includes sexualised language or imagery, insults and personal attacks, public or private harassment, and publishing someone's private information without permission.",[31,497,498],{},"Content that violates these rules may be removed, edited or rejected. Responses escalate through correction, warning, temporary ban and permanent ban, depending on severity.",[11,500,501,502,504],{},"Report abuse, harassment or other unacceptable behaviour to ",[15,503,141],{"href":140},". Every complaint is reviewed promptly and fairly, and the privacy and safety of the reporter is respected.",[23,506,508],{"id":507},"reporting-security-issues","Reporting security issues",[11,510,511,512,515],{},"Please do ",[34,513,514],{},"not"," report security vulnerabilities through public issues, discussions or chat groups.",[28,517,518,533],{},[31,519,520,521,524,525,528,529,532],{},"Prefer ",[34,522,523],{},"GitHub Private Vulnerability Reporting"," on the repository (",[61,526,527],{},"Security"," → ",[61,530,531],{},"Report a vulnerability",").",[31,534,535,536,538,539,110],{},"If that channel is unavailable, email ",[15,537,141],{"href":140}," with the subject prefix ",[61,540,541],{},"[SCNexus Security]",[11,543,544],{},"A useful report includes the affected version or commit, your operating system and build type, the impact and the conditions required to trigger it, and reproduction steps or a proof of concept. Do not include real credentials, personal data or third-party content.",[11,546,547],{},"These classes of issue are in scope:",[28,549,550,564,570,576,582,588,594],{},[31,551,552,555,556,559,560,563],{},[34,553,554],{},"IPC and process isolation",": bypassing the preload bridge, escaping ",[61,557,558],{},"contextIsolation"," or ",[61,561,562],{},"sandbox",", reaching Node.js APIs from the renderer.",[31,565,566,569],{},[34,567,568],{},"Local service exposure",": unauthenticated or cross-origin access to the loopback service, token leakage, listening on non-loopback interfaces.",[31,571,572,575],{},[34,573,574],{},"Archive and file handling",": path traversal, symlink abuse during extraction, archive bombs, writes outside managed directories.",[31,577,578,581],{},[34,579,580],{},"Credentials and sessions",": weak credential storage, reading another account's data on the same machine, session confusion between accounts, tokens in logs.",[31,583,584,587],{},[34,585,586],{},"Renderer content security",": CSP bypasses, unsafe handling of remote content, navigation to untrusted origins.",[31,589,590,593],{},[34,591,592],{},"Update integrity",": tampering with update metadata or packages.",[31,595,596,599],{},[34,597,598],{},"Dependencies and supply chain",": a vulnerable dependency reachable from application code.",[11,601,602],{},"Issues that require physical access to an unlocked device, that depend on a modified bundle or a disabled signature check, or that come from automated scanners without a demonstrated impact are out of scope. Problems inside third-party components should go upstream.",[11,604,605],{},"We normally acknowledge a report within five business days, then work with the reporter to confirm affected versions, assess severity, prepare a fix and agree on a disclosure date. Reporters are credited in the advisory unless they ask to remain anonymous. The project does not run a paid bug bounty.",[23,607,609],{"id":608},"licence","Licence",[11,611,612,613,616,617,620],{},"The desktop app is released under the ",[34,614,615],{},"BSD 3-Clause"," licence; the full text is in the repository's ",[61,618,619],{},"LICENSE",". You may use, modify and redistribute the code, including commercially, provided the copyright notice, licence terms and disclaimer are retained. Code you contribute is released under the same licence.",[622,623,624],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":155,"searchDepth":240,"depth":240,"links":626},[627,628,629,630,631,632,633,634,635,636],{"id":25,"depth":173,"text":26},{"id":113,"depth":173,"text":114},{"id":144,"depth":173,"text":145},{"id":210,"depth":173,"text":211},{"id":280,"depth":173,"text":281},{"id":344,"depth":173,"text":345},{"id":365,"depth":173,"text":366},{"id":479,"depth":173,"text":480},{"id":507,"depth":173,"text":508},{"id":608,"depth":173,"text":609},"How to contribute to SCNexus: where the repositories live, how to set up a development environment, what to run before submitting, the code and documentation conventions, the code of conduct, and how to report security issues.","md",{},true,200,"\u002Fdocs\u002Fcontributing","app",{"title":6,"description":637},"docs\u002Fcontributing","2026-11-01","KSh32SCfD3voO5oXXD5viIUHaDKMLnd0j8E9dkcyf_c",[331,649],"zh-CN",[651,656,658,662,667,671,675,680,684,688,693,697,702,707,712,717,722,727,732,737,738],{"path":652,"title":653,"description":654,"order":162,"group":433,"section":655,"contentLocale":649},"\u002Fdocs\u002Feditor","创作流程概览","从在《星际争霸II》编辑器中制作，到打包、分发与更新，说明星际枢纽在创作流程里承担的环节。","editor",{"path":108,"title":109,"description":657,"order":162,"group":433,"section":643,"contentLocale":331},"SCNexus is a hub app built for the StarCraft community",{"path":659,"title":660,"description":661,"order":162,"group":442,"section":442,"contentLocale":331},"\u002Fdocs\u002Freference","Overview","The packaging and source conventions that importing, installing and distributing content depends on.",{"path":663,"title":664,"description":665,"order":666,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fcampaign","Campaign management","Import your own campaigns into the library, activate them in the game, and restore the official campaigns at any time",10,{"path":668,"title":669,"description":670,"order":666,"group":436,"section":655,"contentLocale":649},"\u002Fdocs\u002Fpackaging","打包安装包","把编辑器产出的地图、模组与 package.json 组织成一个能被星际枢纽自动识别并安装的压缩包。",{"path":672,"title":673,"description":674,"order":666,"group":442,"section":442,"contentLocale":331},"\u002Fdocs\u002Fscnexus-package","SCNexus package standard","Directory layout, package.json manifest fields, map and mod resource declarations, and how launchers and bundled documents are written for SCNexus work packages.",{"path":676,"title":677,"description":678,"order":679,"group":442,"section":442,"contentLocale":331},"\u002Fdocs\u002Fccm-package","CCM package standard","How CCM describes a campaign in metadata.txt, the key-value format, the directory layout and install targets, and how SCNexus reads these packages.",20,{"path":681,"title":682,"description":683,"order":679,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fcustomize","Custom content","Install maps and mods straight into the game, then pick a launcher map and start in one click",{"path":685,"title":686,"description":687,"order":679,"group":436,"section":655,"contentLocale":649},"\u002Fdocs\u002Ftoolbox","创作工具 · 编码转换","把中文等非 ASCII 文本转成 Galaxy 代码里可用的转义写法，可选直接转码、字符串、文本与触发调试四种输出。",{"path":689,"title":690,"description":691,"order":692,"group":442,"section":442,"contentLocale":331},"\u002Fdocs\u002Fgithub-source","GitHub source standard","The manifest and structural requirements a public GitHub repository has to meet to serve as an install source, and how addresses and branches are written.",30,{"path":694,"title":695,"description":696,"order":692,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fweekly-mutations","Weekly mutations","This week's mutation map, mutators and community rating, plus the full mutator reference",{"path":698,"title":699,"description":700,"order":701,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Freplays","Replays","Index replays by StarCraft profile and replay type, with duplicate detection, bulk export and match data",40,{"path":703,"title":704,"description":705,"order":706,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fworkshop","Workshop","Browse community works, open their details and download reviewed releases",50,{"path":708,"title":709,"description":710,"order":711,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fcreator","Creator center and uploads","Create works, maintain their details, upload new versions and track upload tasks",60,{"path":713,"title":714,"description":715,"order":716,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fdownloads","Downloads","Fetch content from GitHub or the Workshop, then install it once you have checked it",70,{"path":718,"title":719,"description":720,"order":721,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Ftools","Creation tools","Local helpers such as the encoding converter; input is never uploaded or stored",80,{"path":723,"title":724,"description":725,"order":726,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fai-assistant","Smart Assistant","A controlled MCP service connecting local data to AI clients on the same machine",90,{"path":728,"title":729,"description":730,"order":731,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Faccount","Account and personal center","Signing in, your profile and level progression, and setting up and maintaining two-step verification",100,{"path":733,"title":734,"description":735,"order":736,"group":436,"section":643,"contentLocale":331},"\u002Fdocs\u002Fsettings","Settings","Language, game directories, feature switches and logging privacy, tab by tab",110,{"path":642,"title":6,"description":637,"order":641,"group":439,"section":643,"contentLocale":331},{"path":77,"title":78,"description":739,"order":740,"group":439,"section":643,"contentLocale":331},"Where the interface translation files live, how keys are named, how to submit changes, how to verify them locally, and what adding a language touches.",210,1793550744913]