From 7648978cfa78e15c62fcb79a1b30b39bbb95d98d Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 29 Apr 2026 19:22:46 +0530 Subject: [PATCH 1/7] Add codex plugin to SDKs --- app/config/sdks.php | 20 ++++++++++++++++++++ src/Appwrite/Platform/Tasks/SDKs.php | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/app/config/sdks.php b/app/config/sdks.php index e89265b05e..cbfe76dce4 100644 --- a/app/config/sdks.php +++ b/app/config/sdks.php @@ -320,6 +320,26 @@ return [ 'repoBranch' => 'main', 'changelog' => \realpath(__DIR__ . '/../../docs/sdks/claude-plugin/CHANGELOG.md'), ], + [ + 'key' => 'codex-plugin', + 'name' => 'CodexPlugin', + 'version' => '0.1.0', + 'url' => 'https://github.com/appwrite/codex-plugin.git', + 'enabled' => true, + 'beta' => false, + 'dev' => false, + 'hidden' => false, + 'spec' => 'static', + 'family' => APP_SDK_PLATFORM_STATIC, + 'prism' => 'codex-plugin', + 'source' => \realpath(__DIR__ . '/../sdks/static-codex-plugin'), + 'gitUrl' => 'git@github.com:appwrite/codex-plugin.git', + 'gitRepoName' => 'codex-plugin', + 'gitUserName' => 'appwrite', + 'gitBranch' => 'dev', + 'repoBranch' => 'main', + 'changelog' => \realpath(__DIR__ . '/../../docs/sdks/codex-plugin/CHANGELOG.md'), + ], ], ], diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index b1580f0e68..fbf965bd00 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -7,6 +7,7 @@ use Appwrite\SDK\Language\Android; use Appwrite\SDK\Language\Apple; use Appwrite\SDK\Language\ClaudePlugin; use Appwrite\SDK\Language\CLI; +use Appwrite\SDK\Language\CodexPlugin; use Appwrite\SDK\Language\CursorPlugin; use Appwrite\SDK\Language\Dart; use Appwrite\SDK\Language\Deno; @@ -455,6 +456,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND case 'claude-plugin': $config = new ClaudePlugin(); break; + case 'codex-plugin': + $config = new CodexPlugin(); + break; default: throw new \Exception('Language "' . $language['key'] . '" not supported'); } From 5f6b1dda1a408d3e3faf6f69f885b445bbe94f2c Mon Sep 17 00:00:00 2001 From: Aditya Oberai Date: Fri, 8 May 2026 09:35:38 +0000 Subject: [PATCH 2/7] update composer lock --- composer.lock | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index d356362788..7600e305d2 100644 --- a/composer.lock +++ b/composer.lock @@ -4539,16 +4539,16 @@ }, { "name": "utopia-php/migration", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "759d6d61b327313cbeeeb4ea0c3e2459164b4827" + "reference": "211d01b90ccab9729029151c6c61f543bd755c2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/759d6d61b327313cbeeeb4ea0c3e2459164b4827", - "reference": "759d6d61b327313cbeeeb4ea0c3e2459164b4827", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/211d01b90ccab9729029151c6c61f543bd755c2e", + "reference": "211d01b90ccab9729029151c6c61f543bd755c2e", "shasum": "" }, "require": { @@ -4574,25 +4574,7 @@ "Utopia\\Migration\\": "src/Migration" } }, - "autoload-dev": { - "psr-4": { - "Utopia\\Tests\\": "tests/Migration" - } - }, - "scripts": { - "test": [ - "./vendor/bin/phpunit" - ], - "lint": [ - "./vendor/bin/pint --test" - ], - "format": [ - "./vendor/bin/pint" - ], - "check": [ - "./vendor/bin/phpstan analyse --level 3 src tests --memory-limit 2G" - ] - }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -4605,10 +4587,10 @@ "utopia" ], "support": { - "source": "https://github.com/utopia-php/migration/tree/1.10.1", - "issues": "https://github.com/utopia-php/migration/issues" + "issues": "https://github.com/utopia-php/migration/issues", + "source": "https://github.com/utopia-php/migration/tree/1.10.2" }, - "time": "2026-05-07T07:23:57+00:00" + "time": "2026-05-08T06:25:47+00:00" }, { "name": "utopia-php/mongo", @@ -5492,16 +5474,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.27.5", + "version": "1.28.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "9faa38b48d422f3da764a719712905c83b3922cb" + "reference": "e363fffd220172c5f1a5032038fa3fdafeeb2dfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9faa38b48d422f3da764a719712905c83b3922cb", - "reference": "9faa38b48d422f3da764a719712905c83b3922cb", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/e363fffd220172c5f1a5032038fa3fdafeeb2dfb", + "reference": "e363fffd220172c5f1a5032038fa3fdafeeb2dfb", "shasum": "" }, "require": { @@ -5537,9 +5519,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/1.27.5" + "source": "https://github.com/appwrite/sdk-generator/tree/1.28.0" }, - "time": "2026-05-05T12:09:40+00:00" + "time": "2026-05-08T03:37:44+00:00" }, { "name": "brianium/paratest", From 6ee2196fae1f0b27c694b65acfc2320beb91d556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 9 May 2026 09:54:54 +0200 Subject: [PATCH 3/7] Fix git hint regnerating nonstop --- src/Appwrite/Vcs/Comment.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Vcs/Comment.php b/src/Appwrite/Vcs/Comment.php index 4dc0174e50..8741ecff6c 100644 --- a/src/Appwrite/Vcs/Comment.php +++ b/src/Appwrite/Vcs/Comment.php @@ -50,6 +50,8 @@ class Comment protected string $statePrefix = '[appwrite]: #'; + protected ?string $tip = null; + /** * @var mixed[] $builds */ @@ -81,7 +83,14 @@ class Comment public function generateComment(): string { - $json = \json_encode($this->builds); + if ($this->tip === null) { + $this->tip = $this->tips[\array_rand($this->tips)]; + } + + $json = \json_encode([ + 'builds' => $this->builds, + 'tip' => $this->tip, + ]); $text = $this->statePrefix . \base64_encode($json) . "\n\n"; @@ -226,8 +235,7 @@ class Comment $i++; } - $tip = $this->tips[array_rand($this->tips)]; - $text .= "\n
\n\n> [!TIP]\n> $tip\n\n"; + $text .= "\n
\n\n> [!TIP]\n> {$this->tip}\n\n"; return $text; } @@ -252,8 +260,15 @@ class Comment $json = \base64_decode($state); - $builds = \json_decode($json, true); - $this->builds = \is_array($builds) ? $builds : []; + $data = \json_decode($json, true); + + if (\is_array($data) && \array_key_exists('builds', $data)) { + $this->builds = \is_array($data['builds']) ? $data['builds'] : []; + $this->tip = $data['tip'] ?? null; + } else { + // Backward compatibility with old state format (builds array only) + $this->builds = \is_array($data) ? $data : []; + } return $this; } From 43777ee6d99b79cc940c98be080247c8b3cd46d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 9 May 2026 10:16:19 +0200 Subject: [PATCH 4/7] Add unit tests for github hints --- tests/unit/Vcs/CommentTest.php | 144 +++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 tests/unit/Vcs/CommentTest.php diff --git a/tests/unit/Vcs/CommentTest.php b/tests/unit/Vcs/CommentTest.php new file mode 100644 index 0000000000..c6f69e2f1b --- /dev/null +++ b/tests/unit/Vcs/CommentTest.php @@ -0,0 +1,144 @@ + 'localhost']); + $comment->addBuild( + new Document(['$id' => 'project1', 'name' => 'Test Project', 'region' => 'default']), + new Document(['$id' => 'func1', 'name' => 'Test Function']), + 'function', + 'ready', + 'dep1', + ['type' => 'logs'], + '' + ); + + $first = $comment->generateComment(); + $firstTip = $this->extractTip($first); + + $this->assertNotNull($firstTip); + $this->assertNotEmpty($firstTip); + + $second = $comment->generateComment(); + $secondTip = $this->extractTip($second); + + $this->assertEquals($firstTip, $secondTip); + } + + public function testTipIsRestoredFromParsedComment(): void + { + $comment = new Comment(['consoleHostname' => 'localhost']); + $comment->addBuild( + new Document(['$id' => 'project1', 'name' => 'Test Project', 'region' => 'default']), + new Document(['$id' => 'func1', 'name' => 'Test Function']), + 'function', + 'ready', + 'dep1', + ['type' => 'logs'], + '' + ); + + $original = $comment->generateComment(); + $originalTip = $this->extractTip($original); + + $parsed = new Comment(['consoleHostname' => 'localhost']); + $parsed->parseComment($original); + $parsed->addBuild( + new Document(['$id' => 'project1', 'name' => 'Test Project', 'region' => 'default']), + new Document(['$id' => 'func2', 'name' => 'Another Function']), + 'function', + 'building', + 'dep2', + ['type' => 'logs'], + '' + ); + + $regenerated = $parsed->generateComment(); + $regeneratedTip = $this->extractTip($regenerated); + + $this->assertEquals($originalTip, $regeneratedTip); + } + + public function testBackwardCompatibilityWithOldStateFormat(): void + { + $oldBuilds = [ + 'project1_func1' => [ + 'projectName' => 'Test Project', + 'projectId' => 'project1', + 'region' => 'default', + 'resourceName' => 'Test Function', + 'resourceId' => 'func1', + 'resourceType' => 'function', + 'buildStatus' => 'ready', + 'deploymentId' => 'dep1', + 'action' => ['type' => 'logs'], + 'previewUrl' => '', + ], + ]; + + $oldState = '[appwrite]: #' . \base64_encode(\json_encode($oldBuilds)) . "\n\n"; + $oldState .= "> [!TIP]\n> Old tip that should be ignored\n\n"; + + $comment = new Comment(['consoleHostname' => 'localhost']); + $comment->parseComment($oldState); + + $new = $comment->generateComment(); + $newTip = $this->extractTip($new); + + $this->assertNotNull($newTip); + $this->assertNotEquals('Old tip that should be ignored', $newTip); + } + + public function testParseOldStateFormatWithOnlyBuilds(): void + { + $oldBuilds = [ + 'project1_func1' => [ + 'projectName' => 'Test Project', + 'projectId' => 'project1', + 'region' => 'default', + 'resourceName' => 'Test Function', + 'resourceId' => 'func1', + 'resourceType' => 'function', + 'buildStatus' => 'ready', + 'deploymentId' => 'dep1', + 'action' => ['type' => 'logs'], + 'previewUrl' => '', + ], + ]; + + $state = '[appwrite]: #' . \base64_encode(\json_encode($oldBuilds)) . "\n\n"; + + $comment = new Comment(['consoleHostname' => 'localhost']); + $comment->parseComment($state); + + $this->assertEquals(false, $comment->isEmpty()); + + $first = $comment->generateComment(); + $firstTip = $this->extractTip($first); + + $this->assertNotNull($firstTip); + $this->assertNotEmpty($firstTip); + + $second = $comment->generateComment(); + $secondTip = $this->extractTip($second); + + $this->assertEquals($firstTip, $secondTip); + } + + private function extractTip(string $comment): ?string + { + if (\preg_match('/> \[!TIP\]\n> (.+)/', $comment, $matches)) { + return $matches[1]; + } + + return null; + } +} From 76a41d70b0150b59081e0087c8954e16bfad6a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 9 May 2026 10:51:46 +0200 Subject: [PATCH 5/7] Dual read for google oauth secret Will allow future support for more params --- src/Appwrite/Auth/OAuth2/Google.php | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Google.php b/src/Appwrite/Auth/OAuth2/Google.php index 79894c2422..0ee495df7d 100644 --- a/src/Appwrite/Auth/OAuth2/Google.php +++ b/src/Appwrite/Auth/OAuth2/Google.php @@ -72,7 +72,7 @@ class Google extends OAuth2 'https://oauth2.googleapis.com/token?' . \http_build_query([ 'code' => $code, 'client_id' => $this->appID, - 'client_secret' => $this->appSecret, + 'client_secret' => $this->getClientSecret(), 'redirect_uri' => $this->callback, 'scope' => null, 'grant_type' => 'authorization_code' @@ -95,7 +95,7 @@ class Google extends OAuth2 'https://oauth2.googleapis.com/token?' . \http_build_query([ 'refresh_token' => $refreshToken, 'client_id' => $this->appID, - 'client_secret' => $this->appSecret, + 'client_secret' => $this->getClientSecret(), 'grant_type' => 'refresh_token' ]) ), true); @@ -177,4 +177,33 @@ class Google extends OAuth2 return $this->user; } + + /** + * Extracts the Client Secret from the JSON stored in appSecret + * + * @return string + */ + protected function getClientSecret(): string + { + $secret = $this->getAppSecret(); + + return $secret['clientSecret'] ?? ''; + } + + /** + * Decode the JSON stored in appSecret. + * Falls back to treating the raw string as the client secret for backwards compatibility. + * + * @return array + */ + protected function getAppSecret(): array + { + try { + $secret = \json_decode($this->appSecret, true, 512, JSON_THROW_ON_ERROR); + } catch (\Throwable $th) { + return ['clientSecret' => $this->appSecret]; + } + + return $secret; + } } From a5ddc465e6112fddc756a9532d71bb4ec485158e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 9 May 2026 12:53:11 +0200 Subject: [PATCH 6/7] PR review fixes --- tests/unit/Vcs/CommentTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/Vcs/CommentTest.php b/tests/unit/Vcs/CommentTest.php index c6f69e2f1b..29973089c6 100644 --- a/tests/unit/Vcs/CommentTest.php +++ b/tests/unit/Vcs/CommentTest.php @@ -95,6 +95,7 @@ class CommentTest extends TestCase $this->assertNotNull($newTip); $this->assertNotEquals('Old tip that should be ignored', $newTip); + $this->assertContains($newTip, $this->getTips()); } public function testParseOldStateFormatWithOnlyBuilds(): void @@ -126,6 +127,7 @@ class CommentTest extends TestCase $this->assertNotNull($firstTip); $this->assertNotEmpty($firstTip); + $this->assertContains($firstTip, $this->getTips()); $second = $comment->generateComment(); $secondTip = $this->extractTip($second); @@ -141,4 +143,12 @@ class CommentTest extends TestCase return null; } + + private function getTips(): array + { + $reflection = new \ReflectionClass(Comment::class); + $property = $reflection->getProperty('tips'); + + return $property->getValue(new Comment(['consoleHostname' => 'localhost'])); + } } From 0e939ea9d747c1bf38ace4555623acc92927e010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 9 May 2026 12:58:47 +0200 Subject: [PATCH 7/7] PR review fixes --- src/Appwrite/Auth/OAuth2/Google.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Google.php b/src/Appwrite/Auth/OAuth2/Google.php index 0ee495df7d..6028bd109b 100644 --- a/src/Appwrite/Auth/OAuth2/Google.php +++ b/src/Appwrite/Auth/OAuth2/Google.php @@ -187,7 +187,7 @@ class Google extends OAuth2 { $secret = $this->getAppSecret(); - return $secret['clientSecret'] ?? ''; + return $secret['clientSecret'] ?? $this->appSecret; } /** @@ -204,6 +204,10 @@ class Google extends OAuth2 return ['clientSecret' => $this->appSecret]; } + if (!\is_array($secret)) { + return ['clientSecret' => $this->appSecret]; + } + return $secret; } }