Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"name": "deploygate",
"source": "./plugin",
"description": "Upload apps, manage distribution pages, add team members, and set up CI/CD integration with DeployGate",
"version": "1.3.1"
"version": "1.4.0"
}
]
}
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.3.1"
".": "1.4.0"
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [1.4.0](https://github.com/DeployGate/deploygate-agent-plugin/compare/deploygate--v1.3.1...deploygate--v1.4.0) (2026-05-15)


### Features

* send User-Agent header on DeployGate API requests ([#17](https://github.com/DeployGate/deploygate-agent-plugin/issues/17)) ([0756a9f](https://github.com/DeployGate/deploygate-agent-plugin/commit/0756a9fd0079c87be184737022f877e7bd6e3982))


### Bug Fixes

* **ci:** avoid fromJSON in step env so the bundle-commit step skips cleanly ([#19](https://github.com/DeployGate/deploygate-agent-plugin/issues/19)) ([de3df07](https://github.com/DeployGate/deploygate-agent-plugin/commit/de3df0736c3d67647bb85c474de172d97223ca0b))

## [1.3.1](https://github.com/DeployGate/deploygate-agent-plugin/compare/deploygate--v1.3.0...deploygate--v1.3.1) (2026-05-15)


Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deploygate-agent-plugin",
"version": "1.3.1",
"version": "1.4.0",
"description": "DeployGate agent integration: upload mobile apps, manage distribution pages, set up CI/CD, and onboard your team. Supports iOS (IPA) and Android (APK/AAB).",
"type": "module",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deploygate",
"version": "1.3.1",
"version": "1.4.0",
"description": "DeployGate agent integration: upload mobile apps, manage distribution pages, set up CI/CD, and onboard your team. Supports iOS (IPA) and Android (APK/AAB).",
"author": {
"name": "DeployGate",
Expand Down
2 changes: 1 addition & 1 deletion plugin/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deploygate",
"version": "1.3.1",
"version": "1.4.0",
"description": "DeployGate agent integration: upload mobile apps, manage distribution pages, set up CI/CD, and onboard your team. Supports iOS (IPA) and Android (APK/AAB).",
"author": {
"name": "DeployGate",
Expand Down
183 changes: 140 additions & 43 deletions plugin/scripts/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3105,6 +3105,9 @@ var require_utils = __commonJS({
"use strict";
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
function stringArrayToHexStripped(input) {
let acc = "";
let code = 0;
Expand Down Expand Up @@ -3297,27 +3300,77 @@ var require_utils = __commonJS({
}
return output.join("");
}
function normalizeComponentEncoding(component, esc2) {
const func = esc2 !== true ? escape : unescape;
if (component.scheme !== void 0) {
component.scheme = func(component.scheme);
}
if (component.userinfo !== void 0) {
component.userinfo = func(component.userinfo);
}
if (component.host !== void 0) {
component.host = func(component.host);
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
var HOST_DELIM_RE = /[@/?#:]/g;
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
function reescapeHostDelimiters(host, isIP) {
const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
re.lastIndex = 0;
return host.replace(re, (ch) => HOST_DELIMS[ch]);
}
function normalizePercentEncoding(input, decodeUnreserved = false) {
if (input.indexOf("%") === -1) {
return input;
}
if (component.path !== void 0) {
component.path = func(component.path);
let output = "";
for (let i = 0; i < input.length; i++) {
if (input[i] === "%" && i + 2 < input.length) {
const hex3 = input.slice(i + 1, i + 3);
if (isHexPair(hex3)) {
const normalizedHex = hex3.toUpperCase();
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
if (decodeUnreserved && isUnreserved(decoded)) {
output += decoded;
} else {
output += "%" + normalizedHex;
}
i += 2;
continue;
}
}
output += input[i];
}
if (component.query !== void 0) {
component.query = func(component.query);
return output;
}
function normalizePathEncoding(input) {
let output = "";
for (let i = 0; i < input.length; i++) {
if (input[i] === "%" && i + 2 < input.length) {
const hex3 = input.slice(i + 1, i + 3);
if (isHexPair(hex3)) {
const normalizedHex = hex3.toUpperCase();
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
if (decoded !== "." && isUnreserved(decoded)) {
output += decoded;
} else {
output += "%" + normalizedHex;
}
i += 2;
continue;
}
}
if (isPathCharacter(input[i])) {
output += input[i];
} else {
output += escape(input[i]);
}
}
if (component.fragment !== void 0) {
component.fragment = func(component.fragment);
return output;
}
function escapePreservingEscapes(input) {
let output = "";
for (let i = 0; i < input.length; i++) {
if (input[i] === "%" && i + 2 < input.length) {
const hex3 = input.slice(i + 1, i + 3);
if (isHexPair(hex3)) {
output += "%" + hex3.toUpperCase();
i += 2;
continue;
}
}
output += escape(input[i]);
}
return component;
return output;
}
function recomposeAuthority(component) {
const uriTokens = [];
Expand All @@ -3332,7 +3385,7 @@ var require_utils = __commonJS({
if (ipV6res.isIPV6 === true) {
host = `[${ipV6res.escapedHost}]`;
} else {
host = component.host;
host = reescapeHostDelimiters(host, false);
}
}
uriTokens.push(host);
Expand All @@ -3346,7 +3399,10 @@ var require_utils = __commonJS({
module.exports = {
nonSimpleDomain,
recomposeAuthority,
normalizeComponentEncoding,
reescapeHostDelimiters,
normalizePercentEncoding,
normalizePathEncoding,
escapePreservingEscapes,
removeDotSegments,
isIPv4,
isUUID,
Expand Down Expand Up @@ -3570,12 +3626,12 @@ var require_schemes = __commonJS({
var require_fast_uri = __commonJS({
"node_modules/fast-uri/index.js"(exports, module) {
"use strict";
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
var { SCHEMES, getSchemeHandler } = require_schemes();
function normalize(uri, options) {
if (typeof uri === "string") {
uri = /** @type {T} */
serialize(parse3(uri, options), options);
normalizeString(uri, options);
} else if (typeof uri === "object") {
uri = /** @type {T} */
parse3(serialize(uri, options), options);
Expand Down Expand Up @@ -3642,19 +3698,9 @@ var require_fast_uri = __commonJS({
return target;
}
function equal(uriA, uriB, options) {
if (typeof uriA === "string") {
uriA = unescape(uriA);
uriA = serialize(normalizeComponentEncoding(parse3(uriA, options), true), { ...options, skipEscape: true });
} else if (typeof uriA === "object") {
uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
}
if (typeof uriB === "string") {
uriB = unescape(uriB);
uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
} else if (typeof uriB === "object") {
uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
}
return uriA.toLowerCase() === uriB.toLowerCase();
const normalizedA = normalizeComparableURI(uriA, options);
const normalizedB = normalizeComparableURI(uriB, options);
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
}
function serialize(cmpts, opts) {
const component = {
Expand All @@ -3679,12 +3725,12 @@ var require_fast_uri = __commonJS({
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
if (component.path !== void 0) {
if (!options.skipEscape) {
component.path = escape(component.path);
component.path = escapePreservingEscapes(component.path);
if (component.scheme !== void 0) {
component.path = component.path.split("%3A").join(":");
}
} else {
component.path = unescape(component.path);
component.path = normalizePercentEncoding(component.path);
}
}
if (options.reference !== "suffix" && component.scheme) {
Expand Down Expand Up @@ -3719,7 +3765,16 @@ var require_fast_uri = __commonJS({
return uriTokens.join("");
}
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
function parse3(uri, opts) {
function getParseError(parsed, matches) {
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
return 'URI path must start with "/" when authority is present.';
}
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
return "URI port is malformed.";
}
return void 0;
}
function parseWithStatus(uri, opts) {
const options = Object.assign({}, opts);
const parsed = {
scheme: void 0,
Expand All @@ -3730,6 +3785,7 @@ var require_fast_uri = __commonJS({
query: void 0,
fragment: void 0
};
let malformedAuthorityOrPort = false;
let isIP = false;
if (options.reference === "suffix") {
if (options.scheme) {
Expand All @@ -3750,6 +3806,11 @@ var require_fast_uri = __commonJS({
if (isNaN(parsed.port)) {
parsed.port = matches[5];
}
const parseError = getParseError(parsed, matches);
if (parseError !== void 0) {
parsed.error = parsed.error || parseError;
malformedAuthorityOrPort = true;
}
if (parsed.host) {
const ipv4result = isIPv4(parsed.host);
if (ipv4result === false) {
Expand Down Expand Up @@ -3788,14 +3849,18 @@ var require_fast_uri = __commonJS({
parsed.scheme = unescape(parsed.scheme);
}
if (parsed.host !== void 0) {
parsed.host = unescape(parsed.host);
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
}
}
if (parsed.path) {
parsed.path = escape(unescape(parsed.path));
parsed.path = normalizePathEncoding(parsed.path);
}
if (parsed.fragment) {
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
try {
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
} catch {
parsed.error = parsed.error || "URI malformed";
}
}
}
if (schemeHandler && schemeHandler.parse) {
Expand All @@ -3804,7 +3869,29 @@ var require_fast_uri = __commonJS({
} else {
parsed.error = parsed.error || "URI can not be parsed.";
}
return parsed;
return { parsed, malformedAuthorityOrPort };
}
function parse3(uri, opts) {
return parseWithStatus(uri, opts).parsed;
}
function normalizeString(uri, opts) {
return normalizeStringWithStatus(uri, opts).normalized;
}
function normalizeStringWithStatus(uri, opts) {
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
return {
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
malformedAuthorityOrPort
};
}
function normalizeComparableURI(uri, opts) {
if (typeof uri === "string") {
const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
return malformedAuthorityOrPort ? void 0 : normalized;
}
if (typeof uri === "object") {
return serialize(uri, opts);
}
}
var fastUri = {
SCHEMES,
Expand Down Expand Up @@ -30864,7 +30951,13 @@ var StdioServerTransport = class {
// dist/client.js
import { readFile } from "node:fs/promises";
import { basename } from "node:path";

// dist/version.js
var VERSION = true ? "1.4.0" : "dev";

// dist/client.js
var BASE_URL = "https://deploygate.com";
var USER_AGENT = `deploygate-agent-plugin/${VERSION}`;
var DeployGateApiError = class extends Error {
errorType;
because;
Expand All @@ -30890,7 +30983,10 @@ var DeployGateClient = class {
}
async requestRaw(method, path, options) {
const url2 = `${BASE_URL}${path}`;
const headers = { ...options.headers ?? {} };
const headers = {
"User-Agent": USER_AGENT,
...options.headers ?? {}
};
if (options.authenticated) {
if (!this.token) {
throw new Error("API token is not set. Run the `login_start` tool to obtain one.");
Expand All @@ -30915,6 +31011,7 @@ var DeployGateClient = class {
}
const url2 = `${BASE_URL}${path}`;
const headers = {
"User-Agent": USER_AGENT,
Authorization: `Bearer ${this.token}`
};
const fetchOptions = { method, headers };
Expand Down Expand Up @@ -31675,7 +31772,7 @@ var stored = await tokenStore.load();
var client = new DeployGateClient(stored?.token);
var server = new McpServer({
name: "deploygate",
version: "1.3.0"
version: VERSION
});
registerAuthTools(server, client, tokenStore);
registerUploadTools(server, client);
Expand Down