@follenfang/fupload 0.0.22 → 0.0.24
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/fupload/SKILL.md +2 -2
- package/fupload/references/dd.md +1 -1
- package/fupload/references/modus.md +4 -4
- package/fupload/scripts/fupload_cli/__init__.py +1 -1
- package/fupload/scripts/fupload_cli/cli.py +1 -1
- package/fupload/scripts/fupload_cli/dd.py +1 -1
- package/fupload/scripts/fupload_cli/modus.py +7 -4
- package/fupload/scripts/fupload_cli/modus_zip.py +75 -11
- package/fupload/scripts/fupload_cli/schema.py +3 -0
- package/npm/skill-manifest.json +20 -20
- package/package.json +1 -1
package/fupload/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: fupload
|
|
3
3
|
description: Explicit author-publishing workflow for World of Warcraft plugins, configuration shares, and WA/strings on NewBeeBox, NetEase DD, CurseForge, Heybox Workshop, and ModUs.Creator, including local Creator login reuse and plugin ZIP publishing. Use only when the user explicitly invokes `$fupload`, explicitly asks to use the Fupload Skill, or loads this Skill by path. Do not trigger from ordinary mentions of publishing, NewBeeBox, DD, CurseForge, Heybox, ModUs, plugins, configurations, or WA.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "0.0.
|
|
5
|
+
version: "0.0.24"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Fupload
|
|
@@ -22,7 +22,7 @@ Map natural language consistently:
|
|
|
22
22
|
|
|
23
23
|
- `create`: create the main record. If first content is a separate platform action, plan it as a following atomic step.
|
|
24
24
|
- `update`: publish a plugin version, change selected configuration-backup content, or publish a WA/string version.
|
|
25
|
-
- `edit`: change fields allowed by the target platform's action allowlist. For DD plugins, this includes `description`, `html_desc`, and existing-record commercial, association, room/channel, and creation-statement settings; other first-publication metadata, categories, media, and version fields are create/update-only.
|
|
25
|
+
- `edit`: change fields allowed by the target platform's action allowlist. For DD plugins, this includes `description`, `html_desc`, `update_desc`, and existing-record commercial, association, room/channel, and creation-statement settings; other first-publication metadata, categories, media, and version fields are create/update-only. Announcement edits preserve the published version and package; this edits the current plugin announcement, not an arbitrary historical version. Edits read both detail and author-list projections; either may confirm the value, but if neither matches, report verification-required.
|
|
26
26
|
- `delete`: delete one main record only. It never deletes an individual version, media object, or associated record.
|
|
27
27
|
|
|
28
28
|
Never offer bulk delete, drafts, guides, messages, or GUI control automation. Heybox supports individual version deletion with asynchronous readback; whole-module deletion is not supported. The DD task-session command may close verified official GUI processes only after the consent flow below.
|
package/fupload/references/dd.md
CHANGED
|
@@ -73,7 +73,7 @@ A published version's `update_desc` cannot be corrected through the CLI: `plugin
|
|
|
73
73
|
|
|
74
74
|
Every path in `detail_img_files` must exist as a regular local file. Validation reports the exact indexed path, such as `$.detail_img_files[0]`, before any upload or mutation.
|
|
75
75
|
|
|
76
|
-
`game_type` and the outer free/paid state are create-only. `plugin update` requires `sn`, `game_versions`, `version`, and `update_desc`; optional `file`, `detail_url`, and `release_type` publish a new version. `plugin edit` requires `sn` and accepts `description`, `html_desc`, plus the official existing-record commercial and association controls (`scope`, payment/lifetime/VIP fields, room/channel linkage, `creation_statement`, and associated content). Other first-publication metadata (`addon_type`, `name`, logo, detail images, and categories) and version fields are not edit fields. The CLI verifies description edits through both detail and author-list readback; if DD accepts the request but leaves the remote value unchanged, it reports a verification-required error rather than false success.
|
|
76
|
+
`game_type` and the outer free/paid state are create-only. `plugin update` requires `sn`, `game_versions`, `version`, and `update_desc`; optional `file`, `detail_url`, and `release_type` publish a new version. `plugin edit` requires `sn` and accepts `description`, `html_desc`, `update_desc`, plus the official existing-record commercial and association controls (`scope`, payment/lifetime/VIP fields, room/channel linkage, `creation_statement`, and associated content). Other first-publication metadata (`addon_type`, `name`, logo, detail images, and categories) and package/version fields are not edit fields. To repair the current announcement, supply only `sn` and HTML `update_desc` (at most 1000 characters including tags) to `plugin edit`; the existing published version and package URL are preserved. This does not edit arbitrary rows in version history. The CLI verifies description edits through both detail and author-list readback; if DD accepts the request but leaves the remote value unchanged, it reports a verification-required error rather than false success.
|
|
77
77
|
|
|
78
78
|
When `assign_user_sn` is present, the official UI exposes only the public scope option. Python validates the final rebuilt form and rejects a private scope before upload or mutation.
|
|
79
79
|
|
|
@@ -131,12 +131,12 @@ PUT are separate stages.
|
|
|
131
131
|
| `file_id` | `fileId` | positive integer | update/edit/delete required; upload allocates | `GET /game/data/author/project/fileId/{projectId}` | allocated ID is used by signature; create metadata omits it | update/delete/signature | `id`/`fileId` in release detail |
|
|
132
132
|
| `version` | `version` | non-empty string, max 120 | create/upload required after ZIP preflight | ZIP `.toc` plus caller label | caller value preserved | metadata create/update | `version` |
|
|
133
133
|
| `type` | `type` | non-empty string, max 40 | create/upload required | Creator release-type choices/API | must be a server-supported value | metadata create/update | `type` |
|
|
134
|
-
| `supported_game_versions` | `supportedGameVersionsReqs[]` | non-empty object array | required; ZIP-derived | installed `.toc` `Interface` values and game config | each entry requires string `gameVersion` and `server`; explicit caller value must
|
|
134
|
+
| `supported_game_versions` | `supportedGameVersionsReqs[]` | non-empty object array | required; ZIP-derived | installed `.toc` `Interface` values and game config | each entry requires string `gameVersion` and `server`; explicit caller value must be a nonempty subset of ZIP and live `wow_builds` choices | metadata create/update | `supportedGameVersionsReqs`/version compatibility rows |
|
|
135
135
|
| `md5` | `md5` | hex string, max 64 | derived from exact ZIP bytes | local ZIP preflight | must describe bytes later PUT | metadata create/update | `md5` |
|
|
136
136
|
| `zip_size` | `zipSize` | non-negative integer | derived | local ZIP stat | must describe exact ZIP | metadata create/update | `zipSize` |
|
|
137
137
|
| `unzip_size` | `unzipSize` | non-negative integer | derived | ZIP central directory | bounded by ZIP preflight | metadata create/update | `unzipSize` |
|
|
138
138
|
| `path` | `path` | string, max 500 | metadata optional | Creator/object response | local path is never binary upload | metadata create/update | `path` |
|
|
139
|
-
| `toc_version` | `tocVersion` | string, max 80 | derived |
|
|
139
|
+
| `toc_version` | `tocVersion` | string, max 80 | derived | each addon `.toc` `Interface`; TOCs under a `Libs` directory are ignored | recognized flavor TOCs form an addon union; missing values and conflicting independent addons fail before write | metadata create/update | `tocVersion` |
|
|
140
140
|
| `changelog` | `changelog` | string/null, max 10000 | optional | free text | omitted/empty behavior is action-specific | metadata create/update | `changelog` |
|
|
141
141
|
| `file` | not in JSON; raw bytes | local path | create/upload required | local filesystem | valid ZIP, max 200 MiB; bytes PUT only after metadata/signature | signed URL from `GET .../upload/signature/{projectId}/{fileId}`, then HTTP `PUT` | object upload status plus release detail hashes/sizes |
|
|
142
142
|
| `transaction_log` | not sent | local path string | optional | caller | redacted durable stage record | local record only | transaction JSON |
|
|
@@ -147,9 +147,9 @@ binary upload stages that ran; failed records include `failed_stage`, a redacted
|
|
|
147
147
|
error, and whether the ZIP was retained. The transaction record is established
|
|
148
148
|
before file-ID allocation and ZIP preflight, so those early failures are also
|
|
149
149
|
durable. Binary-upload errors expose only a query-free endpoint identifier,
|
|
150
|
-
status when available, and a bounded redacted response summary. The provider parses
|
|
150
|
+
status when available, and a bounded redacted response summary. The provider parses each addon `.toc`
|
|
151
151
|
`Interface` value to derive
|
|
152
|
-
`toc_version` and `supported_game_versions
|
|
152
|
+
`toc_version` and `supported_game_versions`, and ignores TOCs under a `Libs` directory. Explicit `toc_version` must match. Known clients absent from live `wow_builds` are excluded from automatic selection; unknown Interface codes still fail. Explicit `supported_game_versions` may narrow selection to a product's supported scope, but must be a nonempty subset of both ZIP and live choices. Creator `plugin get/versions` uses the Creator session; main-client addon reads retain their separate session.
|
|
153
153
|
The provider validates the ZIP, computes `md5`, `zip_size`, and `unzip_size`,
|
|
154
154
|
registers metadata, obtains a signed URL, then uploads the ZIP bytes with HTTP
|
|
155
155
|
`PUT` and `Content-Type: application/zip`. A local path is metadata only; it is
|
|
@@ -400,7 +400,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
400
400
|
write_output(platform, operation, data)
|
|
401
401
|
return 0
|
|
402
402
|
modus_doctor = platform == "modus" and resource == "session" and action == "doctor"
|
|
403
|
-
modus_main_session = resource in ("addon", "
|
|
403
|
+
modus_main_session = resource in ("addon", "config", "wa", "builds") or (
|
|
404
404
|
modus_doctor and getattr(args, "client", "creator") == "main"
|
|
405
405
|
)
|
|
406
406
|
provider = NewBee() if platform == "newbee" else (DD() if platform == "dd" else (Blackbox() if platform == "blackbox" else (CurseForge() if platform == "curseforge" else _modus_provider(authenticate=not modus_doctor, main_session=modus_main_session))))
|
|
@@ -1469,7 +1469,7 @@ PLUGIN_CREATE_DEFAULTS = {
|
|
|
1469
1469
|
# exceptions and are verified by detail and author-list readback after every
|
|
1470
1470
|
# edit. Other first-publication metadata remains create-only.
|
|
1471
1471
|
PLUGIN_EDIT_FIELDS = (
|
|
1472
|
-
"description", "html_desc",
|
|
1472
|
+
"description", "html_desc", "update_desc",
|
|
1473
1473
|
"scope", "share_code_life_type", "need_buy", "price_fen", "buy_life_type",
|
|
1474
1474
|
"jump_room", "room_id", "channel_id", "channel_type", "sync_room",
|
|
1475
1475
|
"creation_statement", "with_associate", "associated_acts", "need_anchor_vip",
|
|
@@ -24,7 +24,7 @@ from typing import Any, Dict, Mapping, Optional
|
|
|
24
24
|
|
|
25
25
|
from .errors import FuploadError, ValidationError, redact
|
|
26
26
|
from .state_machine import COMPLETE, ProjectStateMachine
|
|
27
|
-
from .modus_zip import parse_modus_zip
|
|
27
|
+
from .modus_zip import parse_modus_zip, select_game_versions
|
|
28
28
|
from .transport import json_request, multipart_request
|
|
29
29
|
|
|
30
30
|
|
|
@@ -1289,14 +1289,17 @@ class ModUs:
|
|
|
1289
1289
|
supplied_games = doc.get("supported_game_versions")
|
|
1290
1290
|
if supplied_toc is not None and str(supplied_toc) != derived["toc_version"]:
|
|
1291
1291
|
raise ValidationError("toc_version does not match the ZIP Interface field", path="$.toc_version")
|
|
1292
|
-
|
|
1293
|
-
|
|
1292
|
+
selected_games = select_game_versions(
|
|
1293
|
+
derived["supported_game_versions"],
|
|
1294
|
+
self.options("game-versions", keys=["wow_builds"]),
|
|
1295
|
+
_supported_game_versions(supplied_games) if supplied_games is not None else None,
|
|
1296
|
+
)
|
|
1294
1297
|
metadata.update({
|
|
1295
1298
|
"md5": md5,
|
|
1296
1299
|
"zip_size": size,
|
|
1297
1300
|
"unzip_size": unzip_size,
|
|
1298
1301
|
"toc_version": derived["toc_version"],
|
|
1299
|
-
"supported_game_versions":
|
|
1302
|
+
"supported_game_versions": selected_games,
|
|
1300
1303
|
"path": doc.get("path") or archive.name,
|
|
1301
1304
|
})
|
|
1302
1305
|
current_stage = "release_metadata_update" if update else "release_metadata"
|
|
@@ -14,6 +14,7 @@ of being silently classified.
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
import io
|
|
17
|
+
import json
|
|
17
18
|
import os
|
|
18
19
|
import re
|
|
19
20
|
import zipfile
|
|
@@ -38,14 +39,33 @@ INTERFACE_GAME_VERSION_MAP: Mapping[str, Mapping[str, str]] = {
|
|
|
38
39
|
"11507": {"gameVersion": "Classic Era", "server": "wow_classic_era"},
|
|
39
40
|
"11508": {"gameVersion": "Classic Era", "server": "wow_classic_era"},
|
|
40
41
|
"40401": {"gameVersion": "Cataclysm Classic", "server": "wow_classic_cata"},
|
|
41
|
-
"
|
|
42
|
+
"11509": {"gameVersion": "1.15.9", "server": "wow_classic_era"},
|
|
43
|
+
"20506": {"gameVersion": "2.5.6", "server": "wow_anniversary"},
|
|
44
|
+
"38002": {"gameVersion": "3.80.2", "server": "wow_classic_titan"},
|
|
45
|
+
"40402": {"gameVersion": "4.4.2", "server": "wow_classic_cata"},
|
|
46
|
+
"50504": {"gameVersion": "5.5.4", "server": "wow_classic"},
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
# Recognized WoW clients in universal ZIPs which currently have no Creator
|
|
50
|
+
# server mapping. Preserve their Interface codes, without inventing wire keys.
|
|
51
|
+
KNOWN_UNMAPPED_INTERFACES = {"16001", "30405"}
|
|
52
|
+
|
|
44
53
|
_INTERFACE_RE = re.compile(r"^\s*##\s*Interface\s*:\s*(.*?)\s*$", re.IGNORECASE)
|
|
45
54
|
_INTERFACE_VALUE_RE = re.compile(r"^\d+$")
|
|
46
55
|
_SOURCE = Union[str, os.PathLike[str], bytes, bytearray, memoryview, BinaryIO]
|
|
47
56
|
|
|
48
57
|
|
|
58
|
+
def _is_library_toc(name: str) -> bool:
|
|
59
|
+
"""Return whether ``name`` is an embedded library TOC.
|
|
60
|
+
|
|
61
|
+
Creator's release form reads the addon TOC. Libraries such as Ace3 and
|
|
62
|
+
LibDeflate live under a ``Libs`` directory and declare their own Interface
|
|
63
|
+
values, so treating them as addons rejects packages the Creator accepts.
|
|
64
|
+
"""
|
|
65
|
+
parts = name.replace("\\", "/").split("/")
|
|
66
|
+
return any(part.casefold() == "libs" for part in parts[:-1])
|
|
67
|
+
|
|
68
|
+
|
|
49
69
|
def _read_source(source: _SOURCE) -> Tuple[bytes, str]:
|
|
50
70
|
"""Read a path, byte buffer, or seekable stream without leaking content."""
|
|
51
71
|
if isinstance(source, (bytes, bytearray, memoryview)):
|
|
@@ -127,27 +147,43 @@ def _zip_entries(raw: bytes, source_name: str) -> Iterable[Tuple[str, bytes]]:
|
|
|
127
147
|
def parse_modus_zip(source: _SOURCE) -> Dict[str, Any]:
|
|
128
148
|
"""Return ModUs metadata inferred from ``source``.
|
|
129
149
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
Each addon's base and recognized flavor TOCs form one Interface union.
|
|
151
|
+
Independent addons must declare the same union. This avoids
|
|
152
|
+
choosing an arbitrary addon when a multi-addon archive contains
|
|
153
|
+
incompatible game versions. TOCs under a ``Libs`` directory are ignored.
|
|
154
|
+
Multiple Interface values in one TOC are supported and become a
|
|
155
|
+
deterministic comma-separated ``toc_version``.
|
|
134
156
|
|
|
135
157
|
Returned keys are JSON-ready and use the exact snake_case names accepted
|
|
136
158
|
by the Fupload ModUs schema. ``interface_values`` and ``toc_files`` are
|
|
137
159
|
diagnostic fields for callers and can be omitted from the wire request.
|
|
138
160
|
"""
|
|
139
161
|
raw, source_name = _read_source(source)
|
|
162
|
+
addon_entries = [
|
|
163
|
+
(name, toc_raw)
|
|
164
|
+
for name, toc_raw in _zip_entries(raw, source_name)
|
|
165
|
+
if not _is_library_toc(name)
|
|
166
|
+
]
|
|
167
|
+
if not addon_entries:
|
|
168
|
+
raise ValidationError("ZIP contains no addon .toc file outside a Libs directory", path="$.file")
|
|
140
169
|
signatures: List[Tuple[str, Tuple[str, ...]]] = []
|
|
141
|
-
for name, toc_raw in
|
|
170
|
+
for name, toc_raw in addon_entries:
|
|
142
171
|
values = tuple(_interface_values(_decode_toc(toc_raw, name), name))
|
|
143
172
|
signatures.append((name, values))
|
|
144
|
-
|
|
145
|
-
|
|
173
|
+
groups: Dict[str, set[str]] = {}
|
|
174
|
+
for name, values in signatures:
|
|
175
|
+
normalized = name.replace("\\", "/").casefold()
|
|
176
|
+
addon = re.sub(r"_(?:mainline|vanilla|classic|bcc|tbc|wrath|cata|mists)\.toc$", ".toc", normalized)
|
|
177
|
+
groups.setdefault(addon, set()).update(values)
|
|
178
|
+
first = next(iter(groups))
|
|
179
|
+
expected = tuple(sorted(groups[first], key=lambda item: (int(item), item)))
|
|
180
|
+
mismatches = [name for name, values in groups.items() if values != set(expected)]
|
|
146
181
|
if mismatches:
|
|
147
|
-
names = ", ".join([
|
|
182
|
+
names = ", ".join([first, *mismatches])
|
|
148
183
|
raise ValidationError("addon TOC Interface values are ambiguous across files: %s" % names, path="$.file")
|
|
149
184
|
|
|
150
|
-
unknown = [value for value in expected
|
|
185
|
+
unknown = [value for value in expected
|
|
186
|
+
if value not in INTERFACE_GAME_VERSION_MAP and value not in KNOWN_UNMAPPED_INTERFACES]
|
|
151
187
|
if unknown:
|
|
152
188
|
raise ValidationError(
|
|
153
189
|
"unsupported addon TOC Interface value(s): %s" % ", ".join(unknown),
|
|
@@ -156,6 +192,8 @@ def parse_modus_zip(source: _SOURCE) -> Dict[str, Any]:
|
|
|
156
192
|
|
|
157
193
|
games: List[Dict[str, str]] = []
|
|
158
194
|
for interface in expected:
|
|
195
|
+
if interface in KNOWN_UNMAPPED_INTERFACES:
|
|
196
|
+
continue
|
|
159
197
|
candidate = dict(INTERFACE_GAME_VERSION_MAP[interface])
|
|
160
198
|
if candidate not in games:
|
|
161
199
|
games.append(candidate)
|
|
@@ -164,6 +202,7 @@ def parse_modus_zip(source: _SOURCE) -> Dict[str, Any]:
|
|
|
164
202
|
"supported_game_versions": games,
|
|
165
203
|
"interface_values": list(expected),
|
|
166
204
|
"toc_files": [name for name, _ in signatures],
|
|
205
|
+
"unmapped_interface_values": [value for value in expected if value in KNOWN_UNMAPPED_INTERFACES],
|
|
167
206
|
}
|
|
168
207
|
|
|
169
208
|
|
|
@@ -172,4 +211,29 @@ def parse_modus_zip(source: _SOURCE) -> Dict[str, Any]:
|
|
|
172
211
|
parse_zip_metadata = parse_modus_zip
|
|
173
212
|
|
|
174
213
|
|
|
175
|
-
|
|
214
|
+
def select_game_versions(derived: Sequence[Mapping[str, str]], config: Any,
|
|
215
|
+
supplied: Any = None) -> List[Dict[str, str]]:
|
|
216
|
+
"""Intersect known ZIP clients with live Creator choices and caller scope."""
|
|
217
|
+
rows = config if isinstance(config, list) else []
|
|
218
|
+
row = next((item for item in rows if isinstance(item, Mapping) and item.get("key") == "wow_builds"), None)
|
|
219
|
+
try:
|
|
220
|
+
builds = json.loads(row["value"]) if row and isinstance(row.get("value"), str) else None
|
|
221
|
+
except (ValueError, TypeError):
|
|
222
|
+
builds = None
|
|
223
|
+
if not isinstance(builds, Mapping) or not builds or any(
|
|
224
|
+
not isinstance(value, Mapping) or not isinstance(value.get("versions"), list)
|
|
225
|
+
or any(not isinstance(version, str) or not version.strip() for version in value["versions"])
|
|
226
|
+
for value in builds.values()
|
|
227
|
+
):
|
|
228
|
+
raise ValidationError("live wow_builds config is missing or malformed", path="$.supported_game_versions")
|
|
229
|
+
available = [dict(item) for item in derived
|
|
230
|
+
if item["server"] in builds and item["gameVersion"] in builds[item["server"]]["versions"]]
|
|
231
|
+
selected = available if supplied is None else supplied
|
|
232
|
+
if not isinstance(selected, list) or not selected or any(item not in available for item in selected):
|
|
233
|
+
raise ValidationError("supported_game_versions must be a nonempty subset of ZIP and live Creator choices", path="$.supported_game_versions")
|
|
234
|
+
if len({(item["server"], item["gameVersion"]) for item in selected}) != len(selected):
|
|
235
|
+
raise ValidationError("supported_game_versions must not contain duplicates", path="$.supported_game_versions")
|
|
236
|
+
return [dict(item) for item in selected]
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
__all__ = ["INTERFACE_GAME_VERSION_MAP", "parse_modus_zip", "parse_zip_metadata", "select_game_versions"]
|
|
@@ -591,6 +591,9 @@ DD_PLUGIN_VERSION = {
|
|
|
591
591
|
"version": f("string", nonempty=True, max_length=80),
|
|
592
592
|
"update_desc": f("string", nonempty=True, max_length=1000),
|
|
593
593
|
}
|
|
594
|
+
# The official existing-plugin editor includes the update announcement in
|
|
595
|
+
# its /addon/modify payload. Editing it does not require a new ZIP/version.
|
|
596
|
+
DD_PLUGIN_EDIT_META["update_desc"] = DD_PLUGIN_VERSION["update_desc"]
|
|
594
597
|
|
|
595
598
|
DD_CONFIG_META = {
|
|
596
599
|
"scope": DD_COMMERCIAL["scope"], "title": f("string", nonempty=True, max_length=40),
|
package/npm/skill-manifest.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "fupload.npm-skill-manifest.v1",
|
|
3
3
|
"package_name": "@follenfang/fupload",
|
|
4
|
-
"package_version": "0.0.
|
|
5
|
-
"skill_version": "0.0.
|
|
6
|
-
"tree_sha256": "
|
|
4
|
+
"package_version": "0.0.24",
|
|
5
|
+
"skill_version": "0.0.24",
|
|
6
|
+
"tree_sha256": "53bc8cdcaab317ddace896026d8668614dfaeb19f421cf0195fe4846f6e9933c",
|
|
7
7
|
"files": [
|
|
8
8
|
{
|
|
9
9
|
"path": "agents/openai.yaml",
|
|
@@ -87,13 +87,13 @@
|
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
"path": "references/dd.md",
|
|
90
|
-
"bytes":
|
|
91
|
-
"sha256": "
|
|
90
|
+
"bytes": 21111,
|
|
91
|
+
"sha256": "18895d95e5221b3c2243922bbfc6f2e826f9084a0d5d11c37c3eb923a9dd7547"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"path": "references/modus.md",
|
|
95
|
-
"bytes":
|
|
96
|
-
"sha256": "
|
|
95
|
+
"bytes": 37716,
|
|
96
|
+
"sha256": "f462731d05d786cdfd290eceaea9104b0f28814c9a5bd793358e4dc1a7abcdce"
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"path": "references/newbee-official-cli.md",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
{
|
|
114
114
|
"path": "scripts/fupload_cli/__init__.py",
|
|
115
115
|
"bytes": 50,
|
|
116
|
-
"sha256": "
|
|
116
|
+
"sha256": "8903ed57cd646124d87b730c4c5923b97cacd906cef920de53c6b91acfb554f4"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"path": "scripts/fupload_cli/blackbox_web.py",
|
|
@@ -127,8 +127,8 @@
|
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
"path": "scripts/fupload_cli/cli.py",
|
|
130
|
-
"bytes":
|
|
131
|
-
"sha256": "
|
|
130
|
+
"bytes": 37410,
|
|
131
|
+
"sha256": "97ce8e53f916f619a16351c636d90b9ddf4a64ebb301a2cf28da81d65522863d"
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
"path": "scripts/fupload_cli/curseforge.py",
|
|
@@ -147,8 +147,8 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"path": "scripts/fupload_cli/dd.py",
|
|
150
|
-
"bytes":
|
|
151
|
-
"sha256": "
|
|
150
|
+
"bytes": 117387,
|
|
151
|
+
"sha256": "01051273f0e03010c88590305583f404de9588e60fc708999222aa80263ebb31"
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
"path": "scripts/fupload_cli/errors.py",
|
|
@@ -162,13 +162,13 @@
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
"path": "scripts/fupload_cli/modus_zip.py",
|
|
165
|
-
"bytes":
|
|
166
|
-
"sha256": "
|
|
165
|
+
"bytes": 11445,
|
|
166
|
+
"sha256": "ddf603cb24d5e9758be0428446f134e02aa1a44a8be39f697b8985ac34463e2f"
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
169
|
"path": "scripts/fupload_cli/modus.py",
|
|
170
|
-
"bytes":
|
|
171
|
-
"sha256": "
|
|
170
|
+
"bytes": 74167,
|
|
171
|
+
"sha256": "f4ac5820476593f3db0a621faac61cbed319b0a046fb35945f9a684f292d0e5f"
|
|
172
172
|
},
|
|
173
173
|
{
|
|
174
174
|
"path": "scripts/fupload_cli/newbee_auth.py",
|
|
@@ -182,8 +182,8 @@
|
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"path": "scripts/fupload_cli/schema.py",
|
|
185
|
-
"bytes":
|
|
186
|
-
"sha256": "
|
|
185
|
+
"bytes": 55131,
|
|
186
|
+
"sha256": "b651963c504896cfef46f65b61d5fb638884aacb14a8e09593162526e239133f"
|
|
187
187
|
},
|
|
188
188
|
{
|
|
189
189
|
"path": "scripts/fupload_cli/state_machine.py",
|
|
@@ -207,8 +207,8 @@
|
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
209
|
"path": "SKILL.md",
|
|
210
|
-
"bytes":
|
|
211
|
-
"sha256": "
|
|
210
|
+
"bytes": 28729,
|
|
211
|
+
"sha256": "9625fb102b1fcc347978d0b9fe73a51703ec8296d344550938e8a2dbe593565f"
|
|
212
212
|
}
|
|
213
213
|
]
|
|
214
214
|
}
|