├── .gitmodules ├── .dagger ├── frontend │ ├── .gitattributes │ ├── .gitignore │ ├── dagger.json │ ├── tsconfig.json │ ├── package.json │ ├── src │ │ └── index.ts │ └── yarn.lock ├── workspace │ ├── .gitignore │ ├── dagger.json │ ├── .gitattributes │ ├── go.mod │ ├── main.go │ └── go.sum ├── backend │ ├── .gitignore │ ├── .gitattributes │ ├── dagger.json │ ├── go.mod │ ├── main.go │ └── go.sum ├── .gitignore ├── .gitattributes ├── prompts │ ├── fix_tests.md │ ├── assignment.md │ ├── feedback.md │ └── review.md ├── go.mod ├── suggestions.go ├── debugger.go ├── review.go ├── main.go ├── develop.go └── go.sum ├── .gitignore ├── website ├── cypress │ ├── fixtures │ │ └── example.json │ ├── e2e │ │ ├── tsconfig.json │ │ └── greeting_test.cy.ts │ └── support │ │ ├── e2e.ts │ │ └── commands.ts ├── cypress.config.ts ├── tsconfig.vitest.json ├── tsconfig.json ├── tsconfig.app.json ├── tsconfig.node.json ├── eslint.config.js ├── package.json └── index.html ├── Jenkinsfile ├── .circleci └── config.yml ├── go.mod ├── .container-use └── environment.json ├── .github └── workflows │ ├── test.yml │ ├── usage-comments.yml │ └── slash-commands.yml ├── dagger.json ├── greetings.json ├── CLAUDE.md ├── main_test.go ├── README.md ├── AGENTIC_CI.md ├── DEBUGGER_AGENT.md ├── docs └── index.mdx ├── DEMO.md ├── SWE_AGENT.md ├── main.go ├── go.sum ├── CONTRIBUTING.md └── LICENSE /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.dagger/frontend/.gitattributes: -------------------------------------------------------------------------------- 1 | /sdk/** linguist-generated 2 | -------------------------------------------------------------------------------- /.dagger/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | /sdk 2 | /**/node_modules/** 3 | /**/.pnpm-store/** 4 | -------------------------------------------------------------------------------- /.dagger/workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /dagger.gen.go 2 | /internal/dagger 3 | /internal/querybuilder 4 | /internal/telemetry 5 | -------------------------------------------------------------------------------- /.dagger/backend/.gitignore: -------------------------------------------------------------------------------- 1 | /dagger.gen.go 2 | /internal/querybuilder/ 3 | /querybuilder/ 4 | /internal/dagger 5 | /internal/telemetry 6 | -------------------------------------------------------------------------------- /.dagger/.gitignore: -------------------------------------------------------------------------------- 1 | /dagger.gen.go 2 | /internal/querybuilder/ 3 | /querybuilder/ 4 | /internal/dagger 5 | /internal/telemetry 6 | /.env 7 | -------------------------------------------------------------------------------- /.dagger/workspace/dagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workspace", 3 | "engineVersion": "v0.17.1", 4 | "sdk": { 5 | "source": "go" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.dagger/frontend/dagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "engineVersion": "v0.17.1", 4 | "sdk": { 5 | "source": "typescript" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | greetings-api 2 | .vscode 3 | cosign.* 4 | cicli 5 | output/ 6 | build/ 7 | # Local Netlify folder 8 | .netlify 9 | **/node_modules 10 | -------------------------------------------------------------------------------- /.dagger/workspace/.gitattributes: -------------------------------------------------------------------------------- 1 | /dagger.gen.go linguist-generated 2 | /internal/dagger/** linguist-generated 3 | /internal/querybuilder/** linguist-generated 4 | /internal/telemetry/** linguist-generated 5 | -------------------------------------------------------------------------------- /website/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /.dagger/.gitattributes: -------------------------------------------------------------------------------- 1 | /dagger.gen.go linguist-generated=true 2 | /querybuilder/** linguist-generated 3 | /internal/dagger/** linguist-generated 4 | /internal/querybuilder/** linguist-generated 5 | /internal/telemetry/** linguist-generated 6 | -------------------------------------------------------------------------------- /website/cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "cypress"; 2 | 3 | export default defineConfig({ 4 | e2e: { 5 | specPattern: "cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}", 6 | baseUrl: "http://frontend", 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /.dagger/backend/.gitattributes: -------------------------------------------------------------------------------- 1 | /dagger.gen.go linguist-generated 2 | /querybuilder/** linguist-generated 3 | /internal/dagger/** linguist-generated 4 | /internal/querybuilder/** linguist-generated 5 | /internal/telemetry/** linguist-generated 6 | -------------------------------------------------------------------------------- /website/cypress/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*", "../support/**/*"], 3 | "compilerOptions": { 4 | "isolatedModules": false, 5 | "target": "es5", 6 | "lib": ["es5", "dom"], 7 | "types": ["cypress"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /website/tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo", 7 | 8 | "lib": [], 9 | "types": ["node", "jsdom"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.dagger/frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "moduleResolution": "Node", 5 | "experimentalDecorators": true, 6 | "paths": { 7 | "@dagger.io/dagger": ["./sdk/src"], 8 | "@dagger.io/dagger/telemetry": ["./sdk/src/telemetry"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { label 'dagger' } 3 | 4 | environment { 5 | DAGGER_MODULE = "github.com/kpenfound/greetings-api/ci" 6 | } 7 | stages { 8 | stage("dagger") { 9 | steps { 10 | sh ''' 11 | dagger call check 12 | ''' 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.dagger/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "dependencies": { 4 | "@dagger.io/dagger": "./sdk", 5 | "typescript": "^5.5.4" 6 | }, 7 | "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" 8 | } 9 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ], 14 | "compilerOptions": { 15 | "module": "NodeNext" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.dagger/backend/dagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "engineVersion": "v0.18.7", 4 | "sdk": { 5 | "source": "go" 6 | }, 7 | "dependencies": [ 8 | { 9 | "name": "golang", 10 | "source": "github.com/kpenfound/dagger-modules/golang", 11 | "pin": "f7964245d0146dd3810f247c6c09eb33518d4654" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /website/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 8 | 9 | "baseUrl": ".", 10 | "paths": { 11 | "@/*": ["./src/*"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | test: 4 | docker: 5 | - image: cimg/go:1.21 6 | steps: 7 | - checkout 8 | - setup_remote_docker 9 | - run: 10 | name: Install Dagger CLI 11 | command: cd /usr/local && { curl -L https://dl.dagger.io/dagger/install.sh | sudo sh; cd -; } 12 | - run: 13 | name: Dagger Test Pipeline 14 | command: dagger call --progress plain check 15 | workflows: 16 | test: 17 | jobs: 18 | - test 19 | -------------------------------------------------------------------------------- /website/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node20/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "composite": true, 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kpenfound/greetings-api 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gorilla/mux v1.8.1 7 | github.com/rs/cors v1.10.1 8 | gotest.tools/v3 v3.1.0 9 | ) 10 | 11 | require ( 12 | github.com/google/go-cmp v0.5.9 // indirect 13 | github.com/pkg/errors v0.9.1 // indirect 14 | ) 15 | 16 | replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220414164044-61404de7df1a+incompatible 17 | 18 | replace dagger.io/dagger => github.com/sipsma/dagger/sdk/go v0.3.2-0.20230831053358-97f7c3fd25b5 19 | -------------------------------------------------------------------------------- /.dagger/prompts/fix_tests.md: -------------------------------------------------------------------------------- 1 | - You are a programmer 2 | - The tests are failing 3 | - You have access to a workspace with the code and the tests 4 | - The workspace has tools to let you read and write the code as well as run the tests 5 | - In your workspace, fix the issues so that the tests pass 6 | - Be sure to always write your changes to the workspace 7 | - Always run check after writing changes to the workspace 8 | - If the check fails, run reset so you can try again with a clean workspace 9 | - You are not done until the check tool is successful 10 | -------------------------------------------------------------------------------- /website/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import css from "@eslint/css"; 5 | import { defineConfig } from "eslint/config"; 6 | 7 | 8 | export default defineConfig([ 9 | { files: ["**/*.{js,mjs,cjs,ts}"], plugins: { js }, extends: ["js/recommended"] }, 10 | { files: ["**/*.{js,mjs,cjs,ts}"], languageOptions: { globals: {...globals.browser, ...globals.node} } }, 11 | tseslint.configs.recommended, 12 | { files: ["**/*.css"], plugins: { css }, language: "css/css", extends: ["css/recommended"] }, 13 | ]); -------------------------------------------------------------------------------- /.container-use/environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "workdir": "/workdir", 3 | "base_image": "golang:1.24-bullseye", 4 | "setup_commands": [ 5 | "apt-get update && apt-get install -y curl git build-essential", 6 | "curl -fsSL https://get.docker.com | sh", 7 | "cd /tmp && curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=v0.18.12 sh && cp ./bin/dagger /usr/local/bin/dagger", 8 | "curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v1.61.0", 9 | "curl -fsSL https://deb.nodesource.com/setup_20.x | bash -", 10 | "apt-get install -y nodejs" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /website/cypress/e2e/greeting_test.cy.ts: -------------------------------------------------------------------------------- 1 | // https://on.cypress.io/api 2 | 3 | describe("Greetings API", () => { 4 | it("should display a greeting", () => { 5 | cy.visit("/"); 6 | cy.get("h1").should("contain", "Greetings Daggernauts"); 7 | }); 8 | 9 | it("should change the greeting when the button is clicked", () => { 10 | cy.visit("/"); 11 | cy.get("#greetingDisplay").should( 12 | "contain", 13 | "Click the button to see a greeting!", 14 | ); 15 | cy.get("#randomGreetingButton").click(); 16 | cy.get("#greetingDisplay").should( 17 | "not.contain", 18 | "Click the button to see a greeting!", 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /website/cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greetings", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "test:e2e": "cypress run --e2e", 8 | "lint": "eslint --fix ." 9 | }, 10 | "devDependencies": { 11 | "@eslint/css": "^0.7.0", 12 | "@eslint/js": "^9.26.0", 13 | "@rushstack/eslint-patch": "^1.8.0", 14 | "@tsconfig/node20": "^20.1.4", 15 | "@types/jsdom": "^21.1.6", 16 | "@types/node": "^20.12.5", 17 | "@vue/tsconfig": "^0.5.1", 18 | "concurrently": "^9.1.2", 19 | "cypress": "^13.7.2", 20 | "eslint": "^9.26.0", 21 | "globals": "^16.1.0", 22 | "jsdom": "^24.0.0", 23 | "npm-run-all2": "^6.1.2", 24 | "prettier": "^3.2.5", 25 | "start-server-and-test": "^2.0.3", 26 | "typescript": "~5.4.0", 27 | "typescript-eslint": "^8.32.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: ["**", "!main"] 5 | jobs: 6 | ci: 7 | name: ci 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Generate an agent token 11 | id: generate-token 12 | uses: actions/create-github-app-token@v2 13 | with: 14 | app-id: ${{ secrets.KAL_APP_ID }} 15 | private-key: ${{ secrets.KAL_PRIVATE_KEY }} 16 | - uses: actions/checkout@v4 17 | - uses: dagger/dagger-for-github@8.0.0 18 | - name: Check 19 | run: dagger call check --github-token GH_TOKEN --model claude-sonnet-4-0 --commit $GITHUB_SHA 20 | env: 21 | DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} 22 | ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} 23 | GH_TOKEN: ${{ steps.generate-token.outputs.token }} 24 | -------------------------------------------------------------------------------- /.github/workflows/usage-comments.yml: -------------------------------------------------------------------------------- 1 | name: PR Usage Comment 2 | on: 3 | pull_request: 4 | types: [opened] 5 | jobs: 6 | comment: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Add comment to PR 10 | uses: peter-evans/create-or-update-comment@v3 11 | with: 12 | issue-number: ${{ github.event.pull_request.number }} 13 | body: | 14 | Test this PR by running the following command: 15 | 16 | ``` 17 | dagger -m github.com/kpenfound/greetings-api@pull/${{ github.event.pull_request.number }}/head call check 18 | ``` 19 | 20 | Run this branch locally: 21 | 22 | ``` 23 | dagger -m github.com/kpenfound/greetings-api@pull/${{ github.event.pull_request.number }}/head call serve up 24 | ``` 25 | token: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.dagger/prompts/assignment.md: -------------------------------------------------------------------------------- 1 | You are a programmer working on the Greetings API project 2 | 3 | ## Problem solving process 4 | 5 | 1. Consider the assignments intent 6 | 2. Evaluate the architecture of the project at `## Project Architecture` in CONTRIBUTING.md to think about what files may be relevant to the solution 7 | 3. Understand how the assignment should be implemented in the codebase 8 | 4. Implement the assignment in the workspace provided 9 | 5. Run the checks to make sure the changes are valid and incorporate any changes needed to pass checks 10 | 11 | ## Assignment 12 | 13 | Here is your assignment: $assignment 14 | 15 | ## Constraints 16 | - You have access to a workspace with the code and the tests 17 | - The workspace has tools to let you read and write the code as well as run the tests 18 | - Be sure to always write your changes to the workspace 19 | - Always run check after writing changes to the workspace 20 | - You are not done until the check tool is successful and the assignment is complete 21 | -------------------------------------------------------------------------------- /dagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "greetings", 3 | "engineVersion": "v0.18.12", 4 | "sdk": { 5 | "source": "go" 6 | }, 7 | "dependencies": [ 8 | { 9 | "name": "backend", 10 | "source": ".dagger/backend" 11 | }, 12 | { 13 | "name": "frontend", 14 | "source": ".dagger/frontend" 15 | }, 16 | { 17 | "name": "github-issue", 18 | "source": "github.com/kpenfound/dag/github-issue", 19 | "pin": "2b76331a92be6da3fead95305e7bf2a70726c1e6" 20 | }, 21 | { 22 | "name": "github-release", 23 | "source": "github.com/kpenfound/jpadams-github-release@c6081b3210407d5ea49fce8874c5104afa8373cb", 24 | "pin": "c6081b3210407d5ea49fce8874c5104afa8373cb" 25 | }, 26 | { 27 | "name": "proxy", 28 | "source": "github.com/kpenfound/dagger-modules/proxy@proxy/v0.2.5", 29 | "pin": "3e9129a119151eb122e5fe380bd2d4313d8fc001" 30 | }, 31 | { 32 | "name": "workspace", 33 | "source": ".dagger/workspace" 34 | } 35 | ], 36 | "source": ".dagger" 37 | } 38 | -------------------------------------------------------------------------------- /greetings.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "language": "english", "greeting": "Hello, World!" }, 3 | { "language": "british", "greeting": "Hello, World! Cheers!" }, 4 | { "language": "french", "greeting": "Bonjour, Monde !" }, 5 | { "language": "italian", "greeting": "Ciao, Mondo!" }, 6 | { "language": "spanish", "greeting": "¡Hola, Mundo!" }, 7 | { "language": "german", "greeting": "Hallo, Welt!" }, 8 | { "language": "mandarin", "greeting": "你好,世界!" }, 9 | { "language": "hindi", "greeting": "नमस्ते दुनिया!" }, 10 | { "language": "arabic", "greeting": "مرحبا بالعالم!" }, 11 | { "language": "bengali", "greeting": "ওহে বিশ্ব!" }, 12 | { "language": "russian", "greeting": "Привет, мир!" }, 13 | { "language": "portuguese", "greeting": "Olá, Mundo!" }, 14 | { "language": "urdu", "greeting": "ہیلو، دنیا!" }, 15 | { "language": "indonesian", "greeting": "Halo Dunia!" }, 16 | { "language": "japanese", "greeting": "こんにちは世界!" }, 17 | { "language": "marathi", "greeting": "नमस्कार जग!" }, 18 | { "language": "telugu", "greeting": "హలో ప్రపంచం!" } 19 | ] 20 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | This project is a backend API that returns greetings, and a frontend that displays the greetings 2 | 3 | ## Problem solving 4 | 5 | 1. Consider the intent of your assignment and how it relates to the project. 6 | 2. Evaluate the architecture of the project at `## Project Architecture` in CONTRIBUTING.md to think about what files may be relevant to the solution 7 | 3. Implement the solution. Make sure to update related tests and add comprehensive testing for new code. Never make unnecessary changes. 8 | 4. Check that linting and testing passes. See `### Pull Request Process` in CONTRIBUTING.md for instructions on running linters and tests 9 | 10 | ## Generated tool sections 11 | 12 | 13 | ALWAYS use ONLY Environments for ANY and ALL file, code, or shell operations—NO EXCEPTIONS—even for simple or generic requests. 14 | 15 | DO NOT install or use the git cli with the environment_run_cmd tool. All environment tools will handle git operations for you. Changing ".git" yourself will compromise the integrity of your environment. 16 | 17 | You MUST inform the user how to view your work using `container-use log ` AND `container-use checkout `. Failure to do this will make your work inaccessible to others. 18 | 19 | 20 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | "testing" 8 | 9 | "gotest.tools/v3/assert" 10 | ) 11 | 12 | func TestSelectGreeting(t *testing.T) { 13 | var greetings []*Greeting 14 | err := json.Unmarshal(greetingsJson, &greetings) 15 | if err != nil { 16 | fmt.Printf("error loading greetings: %s\n", err) 17 | os.Exit(1) 18 | } 19 | 20 | english := &Greeting{ 21 | Greeting: "Hello, World!", 22 | Language: "english", 23 | } 24 | 25 | // Test with a language 26 | g, err := SelectGreeting(greetings, "english") 27 | assert.NilError(t, err) 28 | assert.Equal(t, *english, *g) 29 | 30 | // Test random 31 | _, err = SelectGreeting(greetings, "random") 32 | assert.NilError(t, err) 33 | 34 | // Test invalid language 35 | _, err = SelectGreeting(greetings, "foooooo") 36 | assert.Error(t, err, "no greeting found for language 'foooooo'") 37 | 38 | // Test empty language 39 | _, err = SelectGreeting(greetings, "") 40 | assert.Error(t, err, "no greeting found for language ''") 41 | } 42 | 43 | func TestFormatResponse(t *testing.T) { 44 | g := &Greeting{ 45 | Greeting: "Hello, World!", 46 | Language: "english", 47 | } 48 | 49 | formatted := FormatResponse(g) 50 | assert.Equal(t, "{\"greeting\":\"Hello, World!\"}", formatted) 51 | } 52 | -------------------------------------------------------------------------------- /.dagger/prompts/feedback.md: -------------------------------------------------------------------------------- 1 | You are a programmer working on the Greetings API project 2 | You have received feedback on a pull request. 3 | 4 | ## Problem solving process 5 | 6 | 1. Consider the original intent of the pull request described in the pull request description 7 | 2. Consider the feedback given to the work done so far 8 | 3. Consider the code diff for what work has been done so far 9 | 4. Understand what the feedback is asking for in this context 10 | 5. Implement the feedback in the workspace provided 11 | 6. Run the checks to make sure the changes are valid and incorporate any changes needed to pass checks 12 | 13 | ## Pull request description 14 | 15 | $description 16 | 17 | ## Feedback 18 | 19 | $feedback 20 | 21 | ## Code diff of the work done in the pull request so far 22 | 23 | $diff 24 | 25 | ## Constraints 26 | - The project has a Go API that returns greetings in different languages 27 | - The website in the website/ directory is the frontend 28 | - You have access to a workspace with the code and the tests 29 | - The workspace has tools to let you read and write the code as well as run the tests 30 | - Be sure to always write your changes to the workspace 31 | - Always run check after writing changes to the workspace 32 | - You are not done until the check tool is successful and feedback is implemented 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # greetings-api 2 | 3 | A simple greeting api with a beatuiful frontend. 4 | 5 | ## Try it out! 6 | 7 | ``` 8 | dagger call serve up 9 | ``` 10 | 11 | or without even cloning this repo: 12 | ``` 13 | dagger -m github.com/kpenfound/greetings-api call serve up 14 | ``` 15 | 16 | The frontend will be available at http://localhost:8081/ 17 | 18 | 19 | ## Daggerized! 20 | 21 | Dagger functions: 22 | 23 | ``` 24 | Name Description 25 | build Build the backend and frontend for a specified environment 26 | check Run the CI Checks for the project 27 | debug-broken-tests-pr Debug broken tests on a pull request and comment fix suggestions 28 | debug-tests Debug broken tests. Returns a unified diff of the test fixes 29 | develop Complete an assignment for the greetings project and get back the completed work 30 | develop-pull-request - 31 | lint Lint the Go code in the project 32 | release Create a GitHub release 33 | serve Serve the backend and frontend to 8080 and 8081 respectively 34 | test Run unit tests for the project 35 | ``` 36 | 37 | ## Demos 38 | 39 | - [Debugger Agent](./DEBUGGER_AGENT.md) 40 | - [SWE Agent](./SWE_AGENT.md) 41 | - [Agentic CI](./AGENTIC_CI.md) 42 | -------------------------------------------------------------------------------- /website/cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // *********************************************** 3 | // This example commands.ts shows you how to 4 | // create various custom commands and overwrite 5 | // existing commands. 6 | // 7 | // For more comprehensive examples of custom 8 | // commands please read more here: 9 | // https://on.cypress.io/custom-commands 10 | // *********************************************** 11 | // 12 | // 13 | // -- This is a parent command -- 14 | // Cypress.Commands.add('login', (email, password) => { ... }) 15 | // 16 | // 17 | // -- This is a child command -- 18 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 19 | // 20 | // 21 | // -- This is a dual command -- 22 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 23 | // 24 | // 25 | // -- This will overwrite an existing command -- 26 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 27 | // 28 | // declare global { 29 | // namespace Cypress { 30 | // interface Chainable { 31 | // login(email: string, password: string): Chainable 32 | // drag(subject: string, options?: Partial): Chainable 33 | // dismiss(subject: string, options?: Partial): Chainable 34 | // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable 35 | // } 36 | // } 37 | // } 38 | 39 | export {} 40 | -------------------------------------------------------------------------------- /website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Greetings App 7 | 8 | 9 | 10 |
11 |

Greetings Daggernauts

12 |
13 | Click the button to see a greeting! 14 |
15 | 16 |
17 | 18 | 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/slash-commands.yml: -------------------------------------------------------------------------------- 1 | name: PR Slash Commands 2 | on: 3 | issue_comment: 4 | types: [created] 5 | jobs: 6 | comment-created: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Generate an agent token 10 | id: generate-token 11 | uses: actions/create-github-app-token@v2 12 | with: 13 | app-id: ${{ secrets.KAL_APP_ID }} 14 | private-key: ${{ secrets.KAL_PRIVATE_KEY }} 15 | - uses: actions/checkout@v4 16 | - uses: dagger/dagger-for-github@8.0.0 17 | - name: slash agent 18 | if: github.event.issue.pull_request && contains(github.event.comment.body, '/agent') 19 | run: dagger call pull-request-feedback --github-token GH_TOKEN --issue-id ${{ github.event.issue.number }} --feedback "${{ github.event.comment.body }}" 20 | env: 21 | DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} 22 | ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} 23 | GH_TOKEN: ${{ steps.generate-token.outputs.token }} 24 | - name: slash review 25 | if: github.event.issue.pull_request && contains(github.event.comment.body, '/review') 26 | run: dagger call pull-request-review --github-token GH_TOKEN --issue-id ${{ github.event.issue.number }} 27 | env: 28 | DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} 29 | ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} 30 | GH_TOKEN: ${{ steps.generate-token.outputs.token }} 31 | - name: slash develop 32 | if: ${{ !github.event.issue.pull_request && contains(github.event.comment.body, '/develop') }} 33 | run: dagger call develop-pull-request --github-token GH_TOKEN --issue-id ${{ github.event.issue.number }} 34 | env: 35 | DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} 36 | ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} 37 | GH_TOKEN: ${{ steps.generate-token.outputs.token }} 38 | -------------------------------------------------------------------------------- /AGENTIC_CI.md: -------------------------------------------------------------------------------- 1 | # Agentic CI 2 | 3 | This project has a collection of agents that implement "agentic ci". These agents all work together to improve the software delivery lifecycle. 4 | 5 | We have the following agents: 6 | 7 | ## Developer Agent 8 | 9 | The [Develop](./.dagger/develop.go) agent that develops features. It can run locally or hands-free in Github when a maintainer comments `/develop` on an issue that should be solved. The agent will open a pull request with its solution. 10 | 11 | When the agent opens a pull request, it will automatically request the review agent to review the code. 12 | 13 | The agent is expected to write exhaustive tests, maintain product documentation, and maintain developer documentation. 14 | 15 | ## Reviewer Agent 16 | 17 | The [Review](./.dagger/review.go) agent provides code reviews on pull requests. Its criteria are in the [prompt](./.dagger/prompts/review.md). The review is provided as a comment on a pull request. 18 | 19 | If the owner of the pull request is the Develop agent, the review will automatically get passed to the feedback agent for the feedback to get implemented. If the feedback is something that the agent should keep in mind for all contributions, the agent will update its own prompts or developer documentation, depending on the feedback. 20 | 21 | ## Debugger Agent 22 | 23 | The [Debug](./.dagger/debugger.go) can automatically fix broken lints and tests. When linting or testing fails on a pull request in CI, this agent automatically runs and comments the fix as a code suggestion. This allows the owner of the pull request to accept the changes if they are appropriate or implement their own fix otherwise. 24 | 25 | ## Feedback Agent 26 | 27 | The [Feedback](./.dagger/develop.go) agent is a mechanism to provide feedback to the Develop agent and have it iterate on the solution. This is essentially the same as the Develop agent with a slightly different prompt so that the agent will consider the original assignment as well as the work completed so far and the feedback on the work. 28 | -------------------------------------------------------------------------------- /DEBUGGER_AGENT.md: -------------------------------------------------------------------------------- 1 | # Debugger Agent 🤖 2 | 3 | An AI Agent that automatically resolves failing tests in CI 4 | 5 | ## Overview 6 | 7 | This is an agent that automatically debugs failing tests in CI. The fix for the failing test is added as a suggestion on a failing PR that can be accepted with a single click. 8 | 9 | Check out the full demo below: 10 | [![Watch the video](https://img.youtube.com/vi/VHUi9ABdASA/maxresdefault.jpg)](https://www.youtube.com/watch?v=VHUi9ABdASA) 11 | 12 | ## Implementation 13 | 14 | The agent is a [Dagger](https://dagger.io) function that automatically debugs failing tests in CI. 15 | 16 | In the dagger module under [.dagger](./.dagger) directory, there is a new function called `debug-tests`. 17 | 18 | The `debug-tests` function: 19 | - Creates a [Workspace](./.dagger/workspace) for an LLM to read and write the files in the project and run tests 20 | - Passes in the appropriate source and checker function to the workspace 21 | - Give the LLM a prompt to debug the broken tests 22 | - Get back a unified diff of the test fixes 23 | 24 | To get a useful agentic flow out of this function, there's another function called `debug-broken-tests-pr` that: 25 | - Uses the GitHub API to get the PR number and the branch name 26 | - Uses the `debug-tests` function to debug the broken tests 27 | - Uses the GitHub API to comment on the PR with suggestions of the fixes 28 | 29 | ## How do I try it? 30 | 31 | The only dependency to run this agent is Dagger. Here are the [installation instructions](https://docs.dagger.io/ai-agents#initial-setup). 32 | 33 | $ Fork or clone this repository and checkout the tricky_broken_tests branch: 34 | ``` 35 | git clone https://github.com/kpenfound/greetings-api 36 | cd greetings-api 37 | git checkout tricky_broken_tests 38 | ``` 39 | 40 | $ Get in a Dagger shell: 41 | ``` 42 | dagger 43 | ``` 44 | 45 | ⋈ Run test function to see the failed tests: 46 | ``` 47 | test 48 | ``` 49 | 50 | ⋈ Run debug-tests to let the agent fix the tests and tell you the fix. 51 | ``` 52 | debug-tests --model 53 | ``` 54 | -------------------------------------------------------------------------------- /.dagger/prompts/review.md: -------------------------------------------------------------------------------- 1 | You are a programmer working on the Greetings API project 2 | You are reviewing changes made in a pull request. 3 | 4 | ## Problem solving process 5 | 6 | 1. Consider the original intent of the pull request described in the pull request description 7 | 2. Consider the code diff for what work has been done so far 8 | 3. Understand how the code diff accomplishes the original intent 9 | 4. Consider if the changes meet the criteria described below 10 | 5. Return a brief review of the pull request in the format described below 11 | 12 | ## Good pull request criteria 13 | 14 | - The code should accomplish the task described in the description 15 | - The code should not include changes unrelated to the description 16 | - The code should not be obviously malicious 17 | - New functionality that did not exist before should have tests created for it 18 | - Changes to project architecture should update the developer docs in CONTRIBUTING.md 19 | - Changes to project functionality should be reflected in changes to the docs under docs/ 20 | - Consider cases where the new code could behave in unexpected ways 21 | 22 | ## Review format 23 | 24 | - Start with your general opinions of the changes 25 | - Provide suggestions that do not expand the overall scope of the pull request 26 | - Describe important changes to make the pull request acceptable, if any 27 | - Describe optional changes that could be helpful but not required, if any 28 | - Summarize whether you think the pull request is ready to merge or if it needs changes to be acceptable 29 | 30 | ## Pull request description 31 | 32 | $description 33 | 34 | ## Code diff of the work done in the pull request so far 35 | 36 | $diff 37 | 38 | ## Constraints 39 | - The project has a Go API that returns greetings in different languages 40 | - The website in the website/ directory is the frontend 41 | - Assume code style is compliant 42 | - Assume tests are passing 43 | - You have access to a workspace with the code 44 | - The workspace has tools to let you read the code 45 | - You are not done until you have fully evaluated the pull request changes 46 | -------------------------------------------------------------------------------- /.dagger/workspace/go.mod: -------------------------------------------------------------------------------- 1 | module dagger/workspace 2 | 3 | go 1.23.6 4 | 5 | require ( 6 | github.com/99designs/gqlgen v0.17.68 7 | github.com/Khan/genqlient v0.8.0 8 | github.com/vektah/gqlparser/v2 v2.5.23 9 | go.opentelemetry.io/otel v1.34.0 10 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 11 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 12 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 13 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 14 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 15 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 16 | go.opentelemetry.io/otel/log v0.8.0 17 | go.opentelemetry.io/otel/metric v1.34.0 18 | go.opentelemetry.io/otel/sdk v1.34.0 19 | go.opentelemetry.io/otel/sdk/log v0.8.0 20 | go.opentelemetry.io/otel/sdk/metric v1.34.0 21 | go.opentelemetry.io/otel/trace v1.34.0 22 | go.opentelemetry.io/proto/otlp v1.3.1 23 | golang.org/x/sync v0.12.0 24 | google.golang.org/grpc v1.71.0 25 | ) 26 | 27 | require ( 28 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 29 | github.com/go-logr/logr v1.4.2 // indirect 30 | github.com/go-logr/stdr v1.2.2 // indirect 31 | github.com/google/uuid v1.6.0 // indirect 32 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect 33 | github.com/sosodev/duration v1.3.1 // indirect 34 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 35 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect 36 | golang.org/x/net v0.37.0 // indirect 37 | golang.org/x/sys v0.31.0 // indirect 38 | golang.org/x/text v0.23.0 // indirect 39 | google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect 40 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect 41 | google.golang.org/protobuf v1.36.5 // indirect 42 | ) 43 | 44 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 45 | 46 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 47 | 48 | replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.8.0 49 | 50 | replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.8.0 51 | -------------------------------------------------------------------------------- /.dagger/backend/go.mod: -------------------------------------------------------------------------------- 1 | module backend 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.6 6 | 7 | require ( 8 | github.com/99designs/gqlgen v0.17.73 9 | github.com/Khan/genqlient v0.8.0 10 | golang.org/x/sync v0.13.0 11 | ) 12 | 13 | require ( 14 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 15 | github.com/go-logr/logr v1.4.2 // indirect 16 | github.com/go-logr/stdr v1.2.2 // indirect 17 | github.com/google/uuid v1.6.0 // indirect 18 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect 19 | github.com/sosodev/duration v1.3.1 // indirect 20 | github.com/vektah/gqlparser/v2 v2.5.26 21 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 22 | go.opentelemetry.io/otel v1.34.0 23 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 24 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 25 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 26 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 27 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect 28 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 29 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 30 | go.opentelemetry.io/otel/log v0.8.0 31 | go.opentelemetry.io/otel/metric v1.34.0 32 | go.opentelemetry.io/otel/sdk v1.34.0 33 | go.opentelemetry.io/otel/sdk/log v0.8.0 34 | go.opentelemetry.io/otel/sdk/metric v1.34.0 35 | go.opentelemetry.io/otel/trace v1.34.0 36 | go.opentelemetry.io/proto/otlp v1.3.1 37 | golang.org/x/net v0.39.0 // indirect 38 | golang.org/x/sys v0.32.0 // indirect 39 | golang.org/x/text v0.24.0 // indirect 40 | google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect 41 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect 42 | google.golang.org/grpc v1.72.0 43 | google.golang.org/protobuf v1.36.6 // indirect 44 | ) 45 | 46 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 47 | 48 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 49 | 50 | replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.8.0 51 | 52 | replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.8.0 53 | -------------------------------------------------------------------------------- /.dagger/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kpenfound/greetings-api/.dagger 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.6 6 | 7 | require ( 8 | github.com/99designs/gqlgen v0.17.75 9 | github.com/Khan/genqlient v0.8.1 10 | golang.org/x/sync v0.15.0 11 | ) 12 | 13 | require ( 14 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 15 | github.com/cenkalti/backoff/v5 v5.0.2 // indirect 16 | github.com/go-logr/logr v1.4.2 // indirect 17 | github.com/go-logr/stdr v1.2.2 // indirect 18 | github.com/google/uuid v1.6.0 // indirect 19 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect 20 | github.com/sosodev/duration v1.3.1 // indirect 21 | github.com/vektah/gqlparser/v2 v2.5.28 22 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 23 | go.opentelemetry.io/otel v1.36.0 24 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 25 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 26 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 27 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 28 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect 29 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 30 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 31 | go.opentelemetry.io/otel/log v0.12.2 32 | go.opentelemetry.io/otel/metric v1.36.0 33 | go.opentelemetry.io/otel/sdk v1.36.0 34 | go.opentelemetry.io/otel/sdk/log v0.12.2 35 | go.opentelemetry.io/otel/sdk/metric v1.36.0 36 | go.opentelemetry.io/otel/trace v1.36.0 37 | go.opentelemetry.io/proto/otlp v1.6.0 38 | golang.org/x/net v0.41.0 // indirect 39 | golang.org/x/sys v0.33.0 // indirect 40 | golang.org/x/text v0.26.0 // indirect 41 | google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect 42 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect 43 | google.golang.org/grpc v1.73.0 44 | google.golang.org/protobuf v1.36.6 // indirect 45 | ) 46 | 47 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 48 | 49 | replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 50 | 51 | replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.12.2 52 | 53 | replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.12.2 54 | -------------------------------------------------------------------------------- /.dagger/suggestions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "regexp" 7 | "strings" 8 | ) 9 | 10 | type CodeSuggestion struct { 11 | File string 12 | Line int 13 | Suggestion []string 14 | } 15 | 16 | func parseDiff(diffText string) []CodeSuggestion { 17 | var suggestions []CodeSuggestion 18 | var currentFile string 19 | var currentLine int 20 | var newCode []string 21 | removalReached := false 22 | 23 | // Regular expressions for file detection and line number parsing 24 | fileRegex := regexp.MustCompile(`^\+\+\+ b/(.+)`) 25 | lineRegex := regexp.MustCompile(`^@@ .* \+(\d+),?`) 26 | 27 | scanner := bufio.NewScanner(strings.NewReader(diffText)) 28 | for scanner.Scan() { 29 | line := scanner.Text() 30 | 31 | // Detect file name 32 | if matches := fileRegex.FindStringSubmatch(line); matches != nil { 33 | currentFile = matches[1] 34 | continue 35 | } 36 | 37 | // Detect modified line number in the new file 38 | if matches := lineRegex.FindStringSubmatch(line); matches != nil { 39 | currentLine = atoi(matches[1]) - 1 // Convert to 0-based index for tracking 40 | newCode = []string{} // Reset new code buffer 41 | removalReached = false 42 | continue 43 | } 44 | 45 | // Extract new code (ignoring metadata lines) 46 | if strings.HasPrefix(line, "+") && !strings.HasPrefix(line, "+++") { 47 | newCode = append(newCode, line[1:]) // Remove `+` 48 | continue 49 | } 50 | 51 | if !removalReached { 52 | currentLine++ // Track line modifications 53 | } 54 | 55 | // If a removed line (`-`) appears after `+` lines, store the suggestion 56 | if strings.HasPrefix(line, "-") && !strings.HasPrefix(line, "---") { 57 | if len(newCode) > 0 && currentFile != "" { 58 | suggestions = append(suggestions, CodeSuggestion{ 59 | File: currentFile, 60 | Line: currentLine, 61 | Suggestion: newCode, 62 | }) 63 | newCode = []string{} // Reset new code buffer 64 | } 65 | removalReached = true 66 | } 67 | 68 | } 69 | 70 | // If there's a pending multi-line suggestion, add it 71 | if len(newCode) > 0 && currentFile != "" { 72 | suggestions = append(suggestions, CodeSuggestion{ 73 | File: currentFile, 74 | Line: currentLine, 75 | Suggestion: newCode, 76 | }) 77 | } 78 | 79 | return suggestions 80 | } 81 | 82 | // Helper function to convert string to int safely 83 | func atoi(s string) int { 84 | var i int 85 | fmt.Sscanf(s, "%d", &i) 86 | return i 87 | } 88 | -------------------------------------------------------------------------------- /docs/index.mdx: -------------------------------------------------------------------------------- 1 | # Greetings API Documentation 2 | 3 | Welcome to the Greetings API! This simple service allows you to retrieve greetings in various languages. 4 | 5 | ## Using the REST API 6 | 7 | The Greetings API provides two main endpoints for retrieving greetings: 8 | 9 | ### Get a Random Greeting 10 | 11 | ``` 12 | GET http://locahost:8080/ 13 | ``` 14 | 15 | **Example Response:** 16 | ```json 17 | { 18 | "greeting": "Hello, World!" 19 | } 20 | ``` 21 | 22 | ### Get a Greeting in a Specific Language 23 | 24 | ``` 25 | GET http://locahost:8080/{language} 26 | ``` 27 | 28 | Replace `{language}` with one of the supported language codes. 29 | 30 | **Example Request:** 31 | ``` 32 | GET http://locahost:8080/french 33 | ``` 34 | 35 | **Example Response:** 36 | ```json 37 | { 38 | "greeting": "Bonjour, Monde !" 39 | } 40 | ``` 41 | 42 | ## Supported Languages 43 | 44 | The API currently supports the following languages: 45 | 46 | | Language Code | Greeting | 47 | |---------------|----------| 48 | | english | Hello, World! | 49 | | british | Hello, World! Cheers! | 50 | | french | Bonjour, Monde ! | 51 | | italian | Ciao, Mondo! | 52 | | spanish | ¡Hola, Mundo! | 53 | | german | Hallo, Welt! | 54 | | mandarin | 你好,世界! | 55 | | hindi | नमस्ते दुनिया! | 56 | | arabic | مرحبا بالعالم! | 57 | | bengali | ওহে বিশ্ব! | 58 | | russian | Привет, мир! | 59 | | portuguese | Olá, Mundo! | 60 | | urdu | ہیلو، دنیا! | 61 | | indonesian | Halo Dunia! | 62 | | japanese | こんにちは世界! | 63 | | marathi | नमस्कार जग! | 64 | | telugu | హలో ప్రపంచం! | 65 | 66 | ## Using the Greetings Website 67 | 68 | If you prefer a web interface, you can visit the website at http://locahost:8081/ where you can: 69 | 70 | 1. View random greetings with a simple click 71 | 2. Experience our user-friendly interface 72 | 73 | Simply click the greeting button (👋) to get a new random greeting displayed on the screen. 74 | 75 | ## API Limits 76 | 77 | Currently, there are no rate limits on the API usage, but please be respectful of our resources. 78 | 79 | ## Error Handling 80 | 81 | If you request a language that doesn't exist, the API will return an appropriate error message with a 400 status code. 82 | 83 | Example error response: 84 | ```json 85 | { 86 | "error": "no greeting found for language 'klingon'" 87 | } 88 | ``` 89 | 90 | ## Need Help? 91 | 92 | If you have any questions or need assistance with the Greetings API, please open an issue on our GitHub repository. 93 | -------------------------------------------------------------------------------- /.dagger/workspace/main.go: -------------------------------------------------------------------------------- 1 | // A generated module for Workspace functions 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | "dagger/workspace/internal/dagger" 8 | ) 9 | 10 | // Interface for something that can be checked 11 | type Checkable interface { 12 | dagger.DaggerObject 13 | CheckDirectory(ctx context.Context, source *dagger.Directory) (string, error) 14 | FormatFile(source *dagger.Directory, path string) *dagger.Directory 15 | } 16 | 17 | // Place to do work and check it 18 | type Workspace struct { 19 | Work *dagger.Directory 20 | // +private 21 | Start *dagger.Directory 22 | // +private 23 | Checker Checkable 24 | } 25 | 26 | func New( 27 | // Initial state of the workspace 28 | source *dagger.Directory, 29 | // Checker to use for testing 30 | checker Checkable, 31 | ) *Workspace { 32 | return &Workspace{ 33 | Start: source, 34 | Work: source, 35 | Checker: checker, 36 | } 37 | } 38 | 39 | // Read the contents of a file in the workspace at the given path 40 | func (w *Workspace) Read( 41 | ctx context.Context, 42 | // Path to read the file at 43 | path string, 44 | ) (string, error) { 45 | return w.Work.File(path).Contents(ctx) 46 | } 47 | 48 | // Write the contents of a file in the workspace at the given path 49 | func (w *Workspace) Write( 50 | ctx context.Context, 51 | // Path to write the file to 52 | path string, 53 | // Contents to write to the file 54 | contents string, 55 | ) *Workspace { 56 | // Write new file 57 | w.Work = w.Work.WithNewFile(path, contents) 58 | // Apply formatting 59 | w.Work = w.Checker.FormatFile(w.Work, path) 60 | return w 61 | } 62 | 63 | // Reset the workspace to the original state 64 | func (w *Workspace) Reset() *Workspace { 65 | w.Work = w.Start 66 | return w 67 | } 68 | 69 | // List the files in the workspace in tree format 70 | func (w *Workspace) Tree(ctx context.Context) (string, error) { 71 | return dag.Container().From("alpine:3"). 72 | WithDirectory("/workspace", w.Work). 73 | WithExec([]string{"tree", "/workspace"}). 74 | Stdout(ctx) 75 | } 76 | 77 | // Run the tests in the workspace 78 | func (w *Workspace) Check(ctx context.Context) (string, error) { 79 | return w.Checker.CheckDirectory(ctx, w.Work) 80 | } 81 | 82 | // Show the changes made to the workspace so far in unified diff format 83 | func (w *Workspace) Diff(ctx context.Context) (string, error) { 84 | return dag.Container().From("alpine:3"). 85 | WithDirectory("/a", w.Start). 86 | WithDirectory("/b", w.Work). 87 | WithExec([]string{"diff", "-rN", "a/", "b/"}, dagger.ContainerWithExecOpts{Expect: dagger.ReturnTypeAny}). 88 | Stdout(ctx) 89 | } 90 | -------------------------------------------------------------------------------- /DEMO.md: -------------------------------------------------------------------------------- 1 | # Dagger Demo Flow 2 | 3 | ## The Greetings API App 4 | 5 | Familiarize yourself with the greetings-api project 6 | 7 | ### Backend 8 | 9 | Lives at the repo root 10 | 11 | Simple API written in Go which listens on http 8080 and returns a greeting message. 12 | 13 | `/main.go` 14 | 15 | The API endpoint and it's configuration. This contains the message that the API returns 16 | 17 | `/main_test.go` 18 | 19 | The unit test for the greeting function. It tests that the greeting is what it expects. If 20 | the greeting is changed, it should be changed here too or the test will fail. This is an 21 | easy way to demonstrate test failures. 22 | 23 | ### Frontend 24 | 25 | Lives under `/website/` 26 | 27 | Static site using Hugo, a static site generator written in Go. 28 | 29 | `website/partials/shortcodes/greeting.html` 30 | 31 | The partial included in the website which makes a call to the backend API 32 | 33 | `content/_index.md` 34 | 35 | The front page of the app which includes the greetings-api message 36 | 37 | `website/content/posts/my-first-post.md` 38 | 39 | Sample post which includes the greetings-api message 40 | 41 | 42 | ## The CI 43 | 44 | Lives under `/ci/` 45 | 46 | The CI module has two main submodules: backend and frontend. Those are subdirectories of 47 | `./ci` and focus on the specifics of the backend/frontend. The ci module itself pulls 48 | those together for a single project entrypoint. 49 | 50 | ### Test 51 | 52 | Run the unit tests for the project 53 | 54 | `dagger call test --source .` 55 | 56 | ### Build 57 | 58 | Build the project 59 | 60 | `dagger call build --source . --env dev export --path ./build` 61 | 62 | ### Serve 63 | 64 | Run and serve the project 65 | 66 | `dagger call serve --source . up` 67 | 68 | This serves the backend at `localhost:8080` and the frontend at `localhost:8081`. Once the 69 | ports are tunneled, open `localhost:8081` in a browser 70 | 71 | ### Deploy 72 | 73 | Deploy the project 74 | 75 | `dagger call deploy --source . --fly-token $FLY_TOKEN --netlify-token $NETLIFY_TOKEN` 76 | 77 | This deploys the backend to fly.io at https://dagger-demo.fly.dev/ and the frontend to 78 | Netlify at https://dagger-demo.netlify.app/ 79 | 80 | Secrets are retrieved at runtime from Infisical, a SaaS Secret Manager 81 | 82 | ### Release 83 | 84 | Create a release of the project 85 | 86 | `dagger call all --source . --release --infisical-token $TOKEN` 87 | 88 | ### CI without cloning the project/branch 89 | 90 | Run the CI without even checking out a branch 91 | 92 | `dagger -m github.com/kpenfound/greetings-api call all --source https://github.com/kpenfound/greetings-api#main --release --infisical-token $TOKEN` 93 | -------------------------------------------------------------------------------- /SWE_AGENT.md: -------------------------------------------------------------------------------- 1 | # SWE Agent 🤖 2 | 3 | The SWE Agent is an automated agent that can write new features for the project. 4 | 5 | ## Overview 6 | 7 | First, I create a GitHub issue describing the work I want the agent to complete. 8 | 9 | When the GitHub issue is labeled with `develop`, the agent will automatically run, 10 | producing a pull request with the completed work. 11 | 12 | Check out the full demo: 13 | 14 | [![A Simple SWE Agent with Dagger](https://img.youtube.com/vi/B7P04M9c1m0/0.jpg)](https://www.youtube.com/watch?v=B7P04M9c1m0) 15 | 16 | ## Implementation 17 | 18 | The agent is a [Dagger](https://dagger.io) function that automatically writes new features for the project. 19 | Using Dagger to solve this is perfect because the agent can use the same code that developers and CI systems already use to test the code. 20 | 21 | In the dagger module under [.dagger](./.dagger) directory, there is a new function called `Develop`. 22 | 23 | The `develop` function: 24 | - Creates a [Workspace](./.dagger/workspace) for an LLM to read and write the files in the project and run tests 25 | - Passes in the appropriate source and checker function to the workspace 26 | - Give the LLM a prompt to complete a feature assignment 27 | - Get back a directory with the completed work 28 | 29 | To get a useful agentic flow out of this function, there's another function called `DevelopPullRequest` that: 30 | - Uses the GitHub API to get the assignment issue body 31 | - Uses the `Develop` function to complete the assignment 32 | - Uses the GitHub API to create a pull request with the completed work 33 | 34 | ## How do I try it? 35 | 36 | You can call the `develop` function with Dagger to see the agent complete a given assignment. The `develop` function takes an assignment as an argument and returns a `Directory` (yes, like a filesystem). With that Directory, you can get in a terminal, inspect the files, or just export the files to your local machine. 37 | 38 | The only dependency to run this agent is Dagger. Here are the [installation instructions](https://docs.dagger.io/ai-agents#initial-setup). 39 | 40 | Once you have Dagger, fork or clone this repository: 41 | ``` 42 | git clone https://github.com/kpenfound/greetings-api 43 | cd greetings-api 44 | ``` 45 | 46 | Then, get in a Dagger shell to interact with the module: 47 | 48 | ``` 49 | dagger 50 | ``` 51 | 52 | ⋈ Run agent to complete the asssignment 53 | 54 | In the snippet below, the agent will complete the assignment "Add a new greeting in Portuguese". 55 | Because the `develop` function returns a Directory, you can pipe it to the `terminal` function to get a terminal in the directory. 56 | 57 | ``` 58 | develop "Add a new greeting in Portuguese" | terminal 59 | ``` 60 | 61 | 62 | 63 | ⋈ Run develop to let the agent complete the assignment with different models. 64 | 65 | ``` 66 | develop "Add a new greeting in Portuguese" --model | terminal 67 | ``` 68 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "embed" 5 | "encoding/json" 6 | "errors" 7 | "fmt" 8 | "math/rand" 9 | "net/http" 10 | "os" 11 | 12 | "github.com/gorilla/mux" 13 | "github.com/rs/cors" 14 | ) 15 | 16 | //go:embed greetings.json 17 | var greetingsJson []byte 18 | 19 | type Greeting struct { 20 | Language string `json:"language"` 21 | Greeting string `json:"greeting"` 22 | } 23 | 24 | func main() { 25 | var greetings []*Greeting 26 | err := json.Unmarshal(greetingsJson, &greetings) 27 | if err != nil { 28 | fmt.Printf("error loading greetings: %s\n", err) 29 | os.Exit(1) 30 | } 31 | router := mux.NewRouter() 32 | 33 | router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 34 | fmt.Printf("got / request from %s\n", r.RemoteAddr) 35 | w.Header().Set("Content-Type", "application/json") 36 | greeting, err := SelectGreeting(greetings, "random") 37 | if err != nil { 38 | http.Error(w, err.Error(), http.StatusBadRequest) 39 | } 40 | _, err = w.Write([]byte(FormatResponse(greeting))) 41 | if err != nil { 42 | panic(err) 43 | } 44 | }).Methods("GET") 45 | 46 | router.HandleFunc("/{language}", func(w http.ResponseWriter, r *http.Request) { 47 | language := mux.Vars(r)["language"] 48 | fmt.Printf("got /{language} request from %s\n", r.RemoteAddr) 49 | w.Header().Set("Content-Type", "application/json") 50 | greeting, err := SelectGreeting(greetings, language) 51 | if err != nil { 52 | http.Error(w, err.Error(), http.StatusBadRequest) 53 | } 54 | _, err = w.Write([]byte(FormatResponse(greeting))) 55 | if err != nil { 56 | panic(err) 57 | } 58 | }).Methods("GET") 59 | 60 | c := cors.New(cors.Options{ 61 | AllowedOrigins: []string{ 62 | "http://greetings.kylepenfound.com", 63 | "https://dagger-demo.netlify.app", 64 | "http://localhost:8081", 65 | }, 66 | }) 67 | handler := c.Handler(router) 68 | err = http.ListenAndServe(":8080", handler) 69 | if errors.Is(err, http.ErrServerClosed) { 70 | fmt.Printf("server closed\n") 71 | } else if err != nil { 72 | fmt.Printf("error starting server: %s\n", err) 73 | os.Exit(1) 74 | } 75 | } 76 | 77 | func FormatResponse(greeting *Greeting) string { 78 | return fmt.Sprintf("{\"greeting\":\"%s\"}", greeting.Greeting) 79 | } 80 | 81 | func SelectGreeting(greetings []*Greeting, language string) (*Greeting, error) { 82 | if len(greetings) == 0 { 83 | return nil, errors.New("no greetings available") 84 | } 85 | 86 | if language == "random" { 87 | // Get random item from greetings slice 88 | randomIndex := rand.Intn(len(greetings)) 89 | return greetings[randomIndex], nil 90 | } 91 | 92 | for _, greeting := range greetings { 93 | if greeting.Language == language { 94 | return greeting, nil 95 | } 96 | } 97 | 98 | return nil, fmt.Errorf("no greeting found for language '%s'", language) 99 | } 100 | -------------------------------------------------------------------------------- /.dagger/frontend/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A generated module for Frontend functions 3 | */ 4 | import { dag, Directory, object, func, Service } from "@dagger.io/dagger"; 5 | 6 | @object() 7 | export class Frontend { 8 | @func() 9 | source: Directory; 10 | backend: Service; 11 | 12 | constructor(source: Directory, backend: Service) { 13 | this.source = source; 14 | this.backend = backend; 15 | } 16 | 17 | @func() 18 | async lint(): Promise { 19 | return dag 20 | .container() 21 | .from("node") 22 | .withMountedCache("/root/.npm", dag.cacheVolume("npm-cache")) 23 | .withWorkdir("/app") 24 | .withDirectory("/app", this.source) 25 | .withExec(["npm", "ci"]) 26 | .withExec(["npm", "run", "lint"]) 27 | .stdout(); 28 | } 29 | 30 | @func() 31 | format(): Directory { 32 | return dag 33 | .container() 34 | .from("node") 35 | .withMountedCache("/root/.npm", dag.cacheVolume("npm-cache")) 36 | .withWorkdir("/app") 37 | .withDirectory("/app", this.source) 38 | .withExec(["npm", "ci"]) 39 | .withExec(["npm", "run", "lint"]) 40 | .directory("/app"); 41 | } 42 | 43 | @func() 44 | async unitTest(): Promise { 45 | return await dag 46 | .container() 47 | .from("cypress/included:14.0.3") 48 | .withMountedCache("/root/.npm", dag.cacheVolume("npm-cache")) 49 | .withServiceBinding("localhost", this.backend) 50 | .withServiceBinding("frontend", this.serve()) 51 | .withWorkdir("/app") 52 | .withDirectory("/app", this.source) 53 | .withExec(["npm", "ci"]) 54 | .withExec(["npm", "run", "test:e2e"]) 55 | .stdout(); 56 | } 57 | 58 | @func() 59 | async check(): Promise { 60 | const lint = await this.lint(); 61 | const test = await this.unitTest(); 62 | 63 | return lint + "\n" + test; 64 | } 65 | 66 | @func() 67 | build(): Directory { 68 | return this.source; 69 | } 70 | 71 | @func() 72 | serve(): Service { 73 | return dag 74 | .container() 75 | .from("nginx") 76 | .withDirectory("/usr/share/nginx/html", this.source) 77 | .asService({ useEntrypoint: true }); 78 | } 79 | 80 | @func() 81 | async checkDirectory(source: Directory): Promise { 82 | this.source = source; 83 | return await this.check(); 84 | } 85 | 86 | @func() 87 | formatDirectory(source: Directory): Directory { 88 | this.source = source; 89 | return this.format(); 90 | } 91 | 92 | @func() 93 | formatFile(source: Directory, path: string): Directory { 94 | if ( 95 | !(path.endsWith(".ts") || path.endsWith(".html") || path.endsWith(".js")) 96 | ) { 97 | return source; 98 | } 99 | 100 | return dag 101 | .container() 102 | .from("node:23") 103 | .withExec(["npm", "install", "--global", "prettier"]) 104 | .withWorkdir("/src") 105 | .withDirectory("/src", source) 106 | .withExec(["prettier", "--write", path]) 107 | .directory("/src"); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 2 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 3 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 4 | github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= 5 | github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= 6 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 7 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 8 | github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= 9 | github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= 10 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 11 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 12 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 13 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 14 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 15 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 16 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 17 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 18 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 19 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 20 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 21 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 22 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 23 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 24 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 25 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 26 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 27 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 28 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 29 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 30 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 31 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 32 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 33 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 34 | gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk= 35 | gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ= 36 | -------------------------------------------------------------------------------- /.dagger/debugger.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/kpenfound/greetings-api/.dagger/internal/dagger" 9 | ) 10 | 11 | // Debug broken tests. Returns a unified diff of the test fixes 12 | func (g *Greetings) DebugTests( 13 | ctx context.Context, 14 | // The model to use to debug debug tests 15 | // +optional 16 | // +default = "claude-sonnet-4-0" 17 | model string, 18 | ) (string, error) { 19 | prompt := dag.CurrentModule().Source().File("prompts/fix_tests.md") 20 | 21 | // Check if backend is broken 22 | if _, berr := g.Backend.CheckDirectory(ctx, g.Backend.Source()); berr != nil { 23 | ws := dag.Workspace( 24 | g.Backend.Source(), 25 | g.Backend.AsWorkspaceCheckable(), 26 | ) 27 | env := dag.Env(). 28 | WithWorkspaceInput("workspace", ws, "workspace to read, write, and test code"). 29 | WithWorkspaceOutput("fixed", "workspace with fixed tests") 30 | return dag.LLM(dagger.LLMOpts{Model: model}). 31 | WithEnv(env). 32 | WithPromptFile(prompt). 33 | Env(). 34 | Output("fixed"). 35 | AsWorkspace(). 36 | Diff(ctx) 37 | } 38 | 39 | // Check if frontend is broken 40 | if _, ferr := g.Frontend.CheckDirectory(ctx, g.Frontend.Source()); ferr != nil { 41 | ws := dag.Workspace( 42 | g.Frontend.Source(), 43 | g.Frontend.AsWorkspaceCheckable(), 44 | ) 45 | env := dag.Env(). 46 | WithWorkspaceInput("workspace", ws, "workspace to read, write, and test code"). 47 | WithWorkspaceOutput("fixed", "workspace with fixed tests") 48 | return dag.LLM(dagger.LLMOpts{Model: model}). 49 | WithEnv(env). 50 | WithPromptFile(prompt). 51 | Env(). 52 | Output("fixed"). 53 | AsWorkspace(). 54 | Diff(ctx) 55 | } 56 | 57 | return "", fmt.Errorf("no broken tests found") 58 | } 59 | 60 | // Debug broken tests on a pull request and comment fix suggestions 61 | func (g *Greetings) DebugBrokenTestsPr( 62 | ctx context.Context, 63 | // Github token with permissions to comment on the pull request 64 | githubToken *dagger.Secret, 65 | // Git commit in Github 66 | commit string, 67 | // The model to use to debug debug tests 68 | // +optional 69 | // +default = "claude-sonnet-4-0" 70 | model string, 71 | ) error { 72 | gh := dag.GithubIssue(dagger.GithubIssueOpts{Token: githubToken}) 73 | // Determine PR head 74 | gitRef := dag.Git(g.Repo).Commit(commit) 75 | gitSource := gitRef.Tree() 76 | pr, err := gh.GetPrForCommit(ctx, g.Repo, commit) 77 | if err != nil { 78 | return err 79 | } 80 | 81 | // Set source to PR head 82 | g = New(gitSource, g.Repo, g.Image, g.App) 83 | 84 | // Suggest fix 85 | suggestionDiff, err := g.DebugTests(ctx, model) 86 | if err != nil { 87 | return err 88 | } 89 | if suggestionDiff == "" { 90 | return fmt.Errorf("no suggestions found") 91 | } 92 | 93 | // Convert the diff to CodeSuggestions 94 | codeSuggestions := parseDiff(suggestionDiff) 95 | 96 | // For each suggestion, comment on PR 97 | for _, suggestion := range codeSuggestions { 98 | markupSuggestion := "```suggestion\n" + strings.Join(suggestion.Suggestion, "\n") + "\n```" 99 | err := gh.WritePullRequestCodeComment( 100 | ctx, 101 | g.Repo, 102 | pr, 103 | commit, 104 | markupSuggestion, 105 | suggestion.File, 106 | "RIGHT", 107 | suggestion.Line) 108 | if err != nil { 109 | return err 110 | } 111 | } 112 | return nil 113 | } 114 | -------------------------------------------------------------------------------- /.dagger/review.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/kpenfound/greetings-api/.dagger/internal/dagger" 8 | ) 9 | 10 | // Agent to review changes made in a Directory 11 | func (g *Greetings) DevelopReview( 12 | ctx context.Context, 13 | // Source directory containing the developed changes 14 | source *dagger.Directory, 15 | // Original assignment being developed 16 | assignment string, 17 | // Git diff of the changes so far 18 | diff string, 19 | // The model to use to complete the assignment 20 | // +optional 21 | // +default = "claude-sonnet-4-0" 22 | model string, 23 | ) (string, error) { 24 | // Run the agent 25 | prompt := dag.CurrentModule().Source().File("prompts/review.md") 26 | 27 | ws := dag.Workspace( 28 | source, 29 | // FIXME: no great way to determine which checker without submodule or self calls 30 | g.Backend.AsWorkspaceCheckable(), 31 | ) 32 | 33 | env := dag.Env(). 34 | WithWorkspaceInput("workspace", ws, "workspace to read, write, and test code"). 35 | WithStringInput("description", assignment, "the description of the pull request"). 36 | WithStringInput("diff", diff, "the git diff of the pull request code changes so far"). 37 | WithStringOutput("review", "the resulting review of the pull request") 38 | agent := dag.LLM(dagger.LLMOpts{Model: model}). 39 | WithEnv(env). 40 | WithPromptFile(prompt). 41 | Loop() 42 | 43 | return agent.Env().Output("review").AsString(ctx) 44 | } 45 | 46 | // Review an open pull request via slash command 47 | func (g *Greetings) PullRequestReview( 48 | ctx context.Context, 49 | // Github token with permissions to create a pull request 50 | githubToken *dagger.Secret, 51 | // The github issue to complete 52 | issueId int, 53 | // The model to use to complete the assignment 54 | // +optional 55 | // +default = "claude-sonnet-4-0" 56 | model string, 57 | ) error { 58 | // Get the pull request information 59 | gh := dag.GithubIssue(dagger.GithubIssueOpts{Token: githubToken}) 60 | issue := gh.Read(g.Repo, issueId) 61 | description, err := issue.Body(ctx) 62 | if err != nil { 63 | return err 64 | } 65 | 66 | headRef, err := issue.HeadRef(ctx) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | diffURL, err := issue.DiffURL(ctx) 72 | if err != nil { 73 | return err 74 | } 75 | diff, err := dag.HTTP(diffURL).Contents(ctx) 76 | if err != nil { 77 | return err 78 | } 79 | // Get the source trees 80 | head := dag.Git(g.Repo).Ref(headRef).Tree() 81 | 82 | // Run the agent 83 | review, err := g.DevelopReview(ctx, head, description, diff, model) 84 | if err != nil { 85 | return err 86 | } 87 | 88 | // Write the review 89 | commentErr := gh.WriteComment(ctx, g.Repo, issueId, review) 90 | 91 | // Feedback loop: improve agent 92 | author, err := issue.Author(ctx) 93 | if err != nil { 94 | return err 95 | } 96 | if author == "agent-kal[bot]" { 97 | feedback := fmt.Sprintf(` 98 | You have recieved the following feedback on your pull request: 99 | \n%s\n\n 100 | If requests any required changes on the solution to the problem, make the required changes. 101 | If there is any feedback on how you solved the problem, update .dagger/prompts/assignment.md to provide a more accurate solution next time. 102 | If there is feedback relevant to all contributors of the project, make sure it is reflected in CONTRIBUTING.md 103 | Do not change any other files.`, review) 104 | err = g.PullRequestFeedback(ctx, githubToken, issueId, feedback, model) 105 | if err != nil { 106 | return err 107 | } 108 | } 109 | 110 | return commentErr 111 | } 112 | -------------------------------------------------------------------------------- /.dagger/backend/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "runtime" 6 | "strings" 7 | 8 | "backend/internal/dagger" 9 | ) 10 | 11 | type Backend struct { 12 | Source *dagger.Directory 13 | } 14 | 15 | func New(source *dagger.Directory) *Backend { 16 | return &Backend{ 17 | Source: source, 18 | } 19 | } 20 | 21 | // Run the unit tests for the backend 22 | func (b *Backend) UnitTest(ctx context.Context) (string, error) { 23 | return dag. 24 | Golang(). 25 | WithSource(b.Source). 26 | Test(ctx) 27 | } 28 | 29 | // Lint the backend Go code 30 | func (b *Backend) Lint(ctx context.Context) (string, error) { 31 | return dag. 32 | Golang(). 33 | WithSource(b.Source). 34 | GolangciLint(ctx) 35 | } 36 | 37 | // Formatter 38 | func (b *Backend) Format() *dagger.Directory { 39 | return dag. 40 | Golang(). 41 | WithSource(b.Source). 42 | Fmt(). 43 | GolangciLintFix() 44 | } 45 | 46 | // Checker 47 | func (b *Backend) Check(ctx context.Context) (string, error) { 48 | lint, err := b.Lint(ctx) 49 | if err != nil { 50 | return "", err 51 | } 52 | test, err := b.UnitTest(ctx) 53 | if err != nil { 54 | return "", err 55 | } 56 | return lint + "\n" + test, nil 57 | } 58 | 59 | // Build the backend 60 | func (b *Backend) Build( 61 | // +optional 62 | arch string, 63 | ) *dagger.Directory { 64 | if arch == "" { 65 | arch = runtime.GOARCH 66 | } 67 | return dag. 68 | Golang(). 69 | WithSource(b.Source). 70 | Build([]string{}, dagger.GolangBuildOpts{Arch: arch}) 71 | } 72 | 73 | // Return the compiled backend binary for a particular architecture 74 | func (b *Backend) Binary( 75 | // +optional 76 | arch string, 77 | ) *dagger.File { 78 | d := b.Build(arch) 79 | return d.File("greetings-api") 80 | } 81 | 82 | // Get a container ready to run the backend 83 | func (b *Backend) Container( 84 | // +optional 85 | arch string, 86 | ) *dagger.Container { 87 | if arch == "" { 88 | arch = runtime.GOARCH 89 | } 90 | bin := b.Binary(arch) 91 | return dag. 92 | Container(dagger.ContainerOpts{Platform: dagger.Platform(arch)}). 93 | From("cgr.dev/chainguard/wolfi-base:latest@sha256:a8c9c2888304e62c133af76f520c9c9e6b3ce6f1a45e3eaa57f6639eb8053c90"). 94 | WithFile("/bin/greetings-api", bin). 95 | WithEntrypoint([]string{"/bin/greetings-api"}). 96 | WithExposedPort(8080) 97 | } 98 | 99 | // Get a Service to run the backend 100 | func (b *Backend) Serve() *dagger.Service { 101 | return b.Container(runtime.GOARCH).AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) 102 | } 103 | 104 | // Stateless checker 105 | func (b *Backend) CheckDirectory( 106 | ctx context.Context, 107 | // Directory to run checks on 108 | source *dagger.Directory) (string, error) { 109 | b.Source = source 110 | return b.Check(ctx) 111 | } 112 | 113 | // Stateless formatter 114 | func (b *Backend) FormatDirectory( 115 | // Directory to format 116 | source *dagger.Directory, 117 | ) *dagger.Directory { 118 | b.Source = source 119 | return b.Format() 120 | } 121 | 122 | // Stateless formatter 123 | func (b *Backend) FormatFile( 124 | // Directory with go module 125 | source *dagger.Directory, 126 | // File path to format 127 | path string, 128 | ) *dagger.Directory { 129 | // Only format go files 130 | if !strings.HasSuffix(path, ".go") { 131 | return source 132 | } 133 | return dag. 134 | Container(). 135 | From("golang:1.24"). 136 | WithExec([]string{"go", "install", "golang.org/x/tools/gopls@latest"}). 137 | WithWorkdir("/app"). 138 | WithDirectory("/app", source). 139 | WithExec([]string{"gopls", "format", "-w", path}). 140 | WithExec([]string{"gopls", "imports", "-w", path}). 141 | Directory("/app") 142 | } 143 | -------------------------------------------------------------------------------- /.dagger/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/kpenfound/greetings-api/.dagger/internal/dagger" 8 | ) 9 | 10 | type Greetings struct { 11 | // +private 12 | Source *dagger.Directory 13 | // +private 14 | Repo string 15 | // +private 16 | Image string 17 | // +private 18 | App string 19 | // +private 20 | Backend *dagger.Backend 21 | // +private 22 | Frontend *dagger.Frontend 23 | } 24 | 25 | func New( 26 | // +optional 27 | // +defaultPath="/" 28 | // +ignore=[".git", "**/node_modules"] 29 | source *dagger.Directory, 30 | // +optional 31 | // +default="github.com/kpenfound/greetings-api" 32 | repo string, 33 | // +optional 34 | // +default="kylepenfound/greetings-api:latest" 35 | image string, 36 | // +optional 37 | // +default="dagger-demo" 38 | app string, 39 | ) *Greetings { 40 | g := &Greetings{ 41 | Source: source, 42 | Repo: repo, 43 | Image: image, 44 | App: app, 45 | Backend: dag.Backend(source.WithoutDirectory("website")), 46 | } 47 | g.Frontend = dag.Frontend(source.Directory("website"), g.Backend.Serve()) 48 | return g 49 | } 50 | 51 | // Run the CI Checks for the project 52 | func (g *Greetings) Check( 53 | ctx context.Context, 54 | // Github token with permissions to comment on the pull request 55 | // +optional 56 | githubToken *dagger.Secret, 57 | // git commit in github 58 | // +optional 59 | commit string, 60 | // The model to use to debug debug tests 61 | // +optional 62 | model string, 63 | ) (string, error) { 64 | // Lint 65 | lintOut, err := g.Lint(ctx) 66 | if err != nil { 67 | if githubToken != nil { 68 | debugErr := g.DebugBrokenTestsPr(ctx, githubToken, commit, model) 69 | return "", fmt.Errorf("lint failed, attempting to debug %v %v", err, debugErr) 70 | } 71 | return "", err 72 | } 73 | 74 | // Then Test 75 | testOut, err := g.Test(ctx) 76 | if err != nil { 77 | if githubToken != nil { 78 | debugErr := g.DebugBrokenTestsPr(ctx, githubToken, commit, model) 79 | return "", fmt.Errorf("lint failed, attempting to debug %v %v", err, debugErr) 80 | } 81 | return "", err 82 | } 83 | 84 | // Then Build 85 | _, err = g.Build().Sync(ctx) 86 | if err != nil { 87 | return "", err 88 | } 89 | 90 | return lintOut + "\n\n" + testOut, nil 91 | } 92 | 93 | // Run unit tests for the project 94 | func (g *Greetings) Test(ctx context.Context) (string, error) { 95 | backendResult, err := g.Backend.UnitTest(ctx) 96 | if err != nil { 97 | return "", err 98 | } 99 | 100 | frontendResult, err := g.Frontend.UnitTest(ctx) 101 | if err != nil { 102 | return "", err 103 | } 104 | 105 | return backendResult + "\n" + frontendResult, nil 106 | } 107 | 108 | // Lint the Go code in the project 109 | func (g *Greetings) Lint(ctx context.Context) (string, error) { 110 | backendResult, err := g.Backend.Lint(ctx) 111 | if err != nil { 112 | return "", err 113 | } 114 | 115 | frontendResult, err := g.Frontend.Lint(ctx) 116 | if err != nil { 117 | return "", err 118 | } 119 | return backendResult + "\n" + frontendResult, nil 120 | } 121 | 122 | // Build the backend and frontend for a specified environment 123 | func (g *Greetings) Build() *dagger.Directory { 124 | return dag.Directory(). 125 | WithFile("/build/greetings-api", g.Backend.Binary()). 126 | WithDirectory("build/website/", g.Frontend.Build()) 127 | } 128 | 129 | // Serve the backend and frontend to 8080 and 8081 respectively 130 | func (g *Greetings) Serve() *dagger.Service { 131 | backendService := g.Backend.Serve() 132 | frontendService := g.Frontend.Serve() 133 | 134 | return dag.Proxy(). 135 | WithService(backendService, "backend", 8080, 8080). 136 | WithService(frontendService, "frontend", 8081, 80). 137 | Service() 138 | } 139 | 140 | // Create a GitHub release 141 | func (g *Greetings) Release(ctx context.Context, tag string, ghToken *dagger.Secret) (string, error) { 142 | // Get build 143 | build := g.Build() 144 | // Compress frontend build 145 | assets := dag.Container().From("alpine:3.18"). 146 | WithDirectory("/assets", build). 147 | WithWorkdir("/assets/build"). 148 | WithExec([]string{"tar", "czf", "website.tar.gz", "website/"}). 149 | WithExec([]string{"rm", "-r", "website"}). 150 | Directory("/assets/build") 151 | _, _ = assets.Sync(ctx) 152 | 153 | title := fmt.Sprintf("Release %s", tag) 154 | return dag.GithubRelease().Create(ctx, g.Repo, tag, title, ghToken, dagger.GithubReleaseCreateOpts{Assets: assets}) 155 | } 156 | -------------------------------------------------------------------------------- /.dagger/develop.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/kpenfound/greetings-api/.dagger/internal/dagger" 9 | ) 10 | 11 | // Complete an assignment for the greetings project and get back the completed work 12 | func (g *Greetings) Develop( 13 | ctx context.Context, 14 | // The assignment to complete 15 | assignment string, 16 | // The model to use to complete the assignment 17 | // +optional 18 | // +default = "claude-sonnet-4-0" 19 | model string, 20 | ) *dagger.Directory { 21 | prompt := dag.CurrentModule().Source().File("prompts/assignment.md") 22 | 23 | ws := dag.Workspace( 24 | g.Source, 25 | // FIXME: no great way to determine which checker without submodule or self calls 26 | g.Backend.AsWorkspaceCheckable(), 27 | ) 28 | 29 | env := dag.Env(). 30 | WithWorkspaceInput("workspace", ws, "workspace to read, write, and test code"). 31 | WithStringInput("assignment", assignment, "the assignment to complete"). 32 | WithWorkspaceOutput("completed", "workspace with developed solution") 33 | agent := dag.LLM(dagger.LLMOpts{Model: model}). 34 | WithEnv(env). 35 | WithPromptFile(prompt). 36 | Loop() 37 | totalTokens, err := agent.TokenUsage().TotalTokens(ctx) 38 | if err == nil { 39 | fmt.Printf("Total token usage: %d\n", totalTokens) 40 | } 41 | work := agent.Env(). 42 | Output("completed"). 43 | AsWorkspace() 44 | 45 | return work.Work() 46 | } 47 | 48 | // Develop changes based on a Github issue and open a pull request 49 | func (g *Greetings) DevelopPullRequest( 50 | ctx context.Context, 51 | // Github token with permissions to create a pull request 52 | githubToken *dagger.Secret, 53 | // The github issue to complete 54 | issueId int, 55 | // The model to use to complete the assignment 56 | // +optional 57 | // +default = "claude-sonnet-4-0" 58 | model string, 59 | ) (string, error) { 60 | gh := dag.GithubIssue(dagger.GithubIssueOpts{Token: githubToken}) 61 | // Get the issue body 62 | issue := gh.Read(g.Repo, issueId) 63 | 64 | assignment, err := issue.Body(ctx) 65 | if err != nil { 66 | return "", err 67 | } 68 | 69 | // Pass the assignment to the develop function 70 | work := g.Develop(ctx, assignment, model) 71 | 72 | // Create a pull request with the feature branch 73 | body := fmt.Sprintf("%s\n\nCompleted by Agent\nFixes https://%s/issues/%d\n", assignment, g.Repo, issueId) 74 | title, err := dag.LLM(dagger.LLMOpts{Model: model}). 75 | WithPrompt("Write an appropriate pull request title for the following assignment. It should be under 150 characters. Just tell me the title and nothing else.\nAssignment:\n" + assignment). 76 | LastReply(ctx) 77 | if err != nil { 78 | return "", fmt.Errorf("failed to come up with pull request title: %v", err) 79 | } 80 | title = strings.TrimSpace(title) 81 | 82 | // Open the pull request 83 | pr := gh.CreatePullRequest(g.Repo, title, body, work) 84 | 85 | // Automatically trigger an agent review. Discard error if it fails 86 | id, err := pr.IssueNumber(ctx) 87 | if err == nil { 88 | err = g.PullRequestReview(ctx, githubToken, id, model) 89 | if err != nil { 90 | fmt.Printf("failed to trigger agent review: %v", err) 91 | } 92 | } 93 | 94 | return pr.URL(ctx) 95 | } 96 | 97 | // Agent to develop changes based on feedback on changes made in a Directory 98 | func (g *Greetings) DevelopFeedback( 99 | ctx context.Context, 100 | // Source directory containing the developed changes 101 | source *dagger.Directory, 102 | // Original assignment being developed 103 | assignment string, 104 | // Diff of the changes done so far 105 | diff string, 106 | // Feedback given to the changes done so far 107 | feedback string, 108 | // The model to use to complete the assignment 109 | // +optional 110 | // +default = "claude-sonnet-4-0" 111 | model string, 112 | ) (*dagger.Directory, error) { 113 | // Run the agent 114 | prompt := dag.CurrentModule().Source().File("prompts/feedback.md") 115 | 116 | ws := dag.Workspace( 117 | source, 118 | // FIXME: no great way to determine which checker without submodule or self calls 119 | g.Backend.AsWorkspaceCheckable(), 120 | ) 121 | 122 | env := dag.Env(). 123 | WithWorkspaceInput("workspace", ws, "workspace to read, write, and test code"). 124 | WithStringInput("description", assignment, "the description of the pull request"). 125 | WithStringInput("feedback", feedback, "the feedback on the pull request"). 126 | WithStringInput("diff", diff, "the git diff of the pull request code changes so far"). 127 | WithWorkspaceOutput("completed", "workspace result with the feedback implemented") 128 | agent := dag.LLM(dagger.LLMOpts{Model: model}). 129 | WithEnv(env). 130 | WithPromptFile(prompt). 131 | Loop() 132 | completed := agent.Env(). 133 | Output("completed"). 134 | AsWorkspace(). 135 | Work() 136 | return completed, nil 137 | } 138 | 139 | // Receive feedback on an open pull request via slash command 140 | func (g *Greetings) PullRequestFeedback( 141 | ctx context.Context, 142 | // Github token with permissions to create a pull request 143 | githubToken *dagger.Secret, 144 | // The github issue to complete 145 | issueId int, 146 | // The feedback recieved on the pull request 147 | feedback string, 148 | // The model to use to complete the assignment 149 | // +optional 150 | // +default = "claude-sonnet-4-0" 151 | model string, 152 | ) error { 153 | // Strip out slash command 154 | feedback = strings.ReplaceAll(feedback, "/agent ", "") 155 | 156 | // Get the pull request information 157 | gh := dag.GithubIssue(dagger.GithubIssueOpts{Token: githubToken}) 158 | issue := gh.Read(g.Repo, issueId) 159 | description, err := issue.Body(ctx) 160 | if err != nil { 161 | return err 162 | } 163 | 164 | headRef, err := issue.HeadRef(ctx) 165 | if err != nil { 166 | return err 167 | } 168 | 169 | diffURL, err := issue.DiffURL(ctx) 170 | if err != nil { 171 | return err 172 | } 173 | diff, err := dag.HTTP(diffURL).Contents(ctx) 174 | if err != nil { 175 | return err 176 | } 177 | 178 | // Get the source trees 179 | head := dag.Git(g.Repo).Ref(headRef).Tree() 180 | 181 | // Run the agent 182 | completed, err := g.DevelopFeedback(ctx, head, description, diff, feedback, model) 183 | if err != nil { 184 | return err 185 | } 186 | // Push the changes 187 | return gh.CreatePullRequestCommit(ctx, g.Repo, completed, headRef) 188 | } 189 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Greetings API 2 | 3 | Thank you for your interest in contributing to the Greetings API! This document provides guidelines and information for contributors. 4 | 5 | ## About the Project 6 | 7 | The Greetings API is a simple greeting service with a beautiful frontend. It serves greetings in multiple languages through a REST API and provides a user-friendly web interface. The project is built with Go for the backend and TypeScript for the frontend, and uses Dagger for CI/CD automation. 8 | 9 | ## Getting Started 10 | 11 | ### Fork and Clone 12 | 13 | 1. **Fork the repository** on GitHub by clicking the "Fork" button at the top right of the repository page. 14 | 15 | 2. **Clone your fork** to your local machine: 16 | ```bash 17 | git clone https://github.com/YOUR_USERNAME/greetings-api.git 18 | cd greetings-api 19 | ``` 20 | 21 | 3. **Add the upstream remote** to keep your fork in sync: 22 | ```bash 23 | git remote add upstream https://github.com/kpenfound/greetings-api.git 24 | ``` 25 | 26 | 4. **Keep your fork updated** by regularly pulling from upstream: 27 | ```bash 28 | git fetch upstream 29 | git checkout main 30 | git merge upstream/main 31 | ``` 32 | 33 | ### Prerequisites 34 | 35 | - Go 1.18 or higher 36 | - Node.js (for the frontend) 37 | - [Dagger](https://dagger.io/) for running CI/CD operations 38 | 39 | ## Project Architecture 40 | 41 | The project follows a monorepo structure with both backend and frontend components: 42 | 43 | ``` 44 | greetings-api/ 45 | ├── main.go # Go backend server 46 | ├── main_test.go # Go backend tests 47 | ├── greetings.json # Greeting data in multiple languages 48 | ├── go.mod # Go module dependencies 49 | ├── CONTRIBUTING.md # Developer documentation 50 | ├── docs/ # Product documentation 51 | │ ├── index.mdx # Main docs file 52 | ├── website/ # Frontend application 53 | │ ├── index.html # Main HTML file 54 | │ ├── package.json # Frontend dependencies 55 | │ └── cypress/ # E2E tests 56 | ├── .dagger/ # Dagger CI/CD modules 57 | │ ├── backend/ # Backend build module 58 | │ ├── frontend/ # Frontend build module 59 | │ └── workspace/ # Workspace configuration 60 | └── dagger.json # Dagger configuration 61 | ``` 62 | 63 | ### Backend Architecture 64 | 65 | - **Language**: Go 66 | - **Framework**: Gorilla Mux for routing, CORS middleware 67 | - **Structure**: Simple REST API with two endpoints: 68 | - `GET /` - Returns a random greeting 69 | - `GET /{language}` - Returns a greeting in the specified language 70 | - **Data**: Greetings are stored in `greetings.json` and embedded in the binary 71 | - **Testing**: Uses `gotest.tools` for unit tests 72 | 73 | ### Frontend Architecture 74 | 75 | - **Language**: TypeScript 76 | - **Testing**: Cypress for end-to-end tests 77 | - **Linting**: ESLint with TypeScript support 78 | - **Build**: Managed through Dagger modules 79 | 80 | ### CI/CD Architecture 81 | 82 | - **Tool**: Dagger for CI/CD operations 83 | - **Modules**: Separate modules for backend, frontend, and workspace management 84 | - **Functions**: Build, test, lint, serve, and release operations 85 | 86 | ## Development Workflow 87 | 88 | ### Running the Application 89 | 90 | **Using Dagger (Recommended):** 91 | ```bash 92 | # Serve both backend and frontend 93 | dagger call serve up 94 | 95 | # Or run from remote without cloning 96 | dagger -m github.com/kpenfound/greetings-api call serve up 97 | ``` 98 | 99 | The frontend will be available at http://localhost:8081/ and the backend at http://localhost:8080/ 100 | 101 | ### Running Tests 102 | 103 | **Backend Tests:** 104 | ```bash 105 | # Using Dagger 106 | dagger call test 107 | 108 | # Or directly with Go 109 | go test ./... 110 | ``` 111 | 112 | **Frontend E2E Tests:** 113 | ```bash 114 | # Using Dagger (recommended) 115 | dagger call check 116 | 117 | # Or directly with npm 118 | cd website 119 | npm run test:e2e 120 | ``` 121 | 122 | ### Running Lints 123 | 124 | **Backend Linting:** 125 | ```bash 126 | # Using Dagger 127 | dagger call lint 128 | ``` 129 | 130 | **Frontend Linting:** 131 | ```bash 132 | # Using Dagger (part of check command) 133 | dagger call check 134 | 135 | # Or directly with npm 136 | cd website 137 | npm run lint 138 | ``` 139 | 140 | ### Available Dagger Commands 141 | 142 | - `dagger call build` - Build the backend and frontend 143 | - `dagger call check` - Run the complete CI checks 144 | - `dagger call lint` - Lint the Go code 145 | - `dagger call test` - Run unit tests 146 | - `dagger call serve up` - Serve the application locally 147 | - `dagger call release` - Create a GitHub release 148 | 149 | ## Making Changes 150 | 151 | ### Code Style 152 | 153 | - **Go**: Follow standard Go formatting (`go fmt`) 154 | - **TypeScript**: Follow the ESLint configuration in the project 155 | - **Commits**: Use clear, descriptive commit messages 156 | 157 | ### Documentation 158 | 159 | - **Developer Docs**: Update CONTRIBUTING.md with any architectural changes 160 | - **Product Docs**: Update docs/ with relevant product changes 161 | 162 | ### Testing Requirements 163 | 164 | - All new Go code should include unit tests 165 | - Frontend changes should not break existing E2E tests 166 | - Run the full test suite before submitting PRs: `dagger call check` 167 | 168 | ### Pull Request Process 169 | 170 | 1. **Create a feature branch** from `main`: 171 | ```bash 172 | git checkout -b feature/your-feature-name 173 | ``` 174 | 175 | 2. **Make your changes** following the code style guidelines 176 | 177 | 3. **Test your changes** thoroughly: 178 | ```bash 179 | dagger call check 180 | ``` 181 | 182 | 4. **Commit your changes** with clear commit messages 183 | 184 | 5. **Push to your fork**: 185 | ```bash 186 | git push origin feature/your-feature-name 187 | ``` 188 | 189 | 6. **Create a Pull Request** on GitHub with: 190 | - Clear description of changes 191 | - Reference to any related issues 192 | - Screenshots if UI changes are involved 193 | 194 | ## Getting Help 195 | 196 | If you need help or have questions: 197 | 198 | - Check the existing [issues](https://github.com/kpenfound/greetings-api/issues) 199 | - Look at the [demos](./README.md#demos) for examples 200 | - Review the [README](./README.md) for basic usage 201 | 202 | ## License 203 | 204 | By contributing to this project, you agree that your contributions will be licensed under the same license as the project. 205 | 206 | Thank you for contributing to the Greetings API! 🎉 207 | -------------------------------------------------------------------------------- /.dagger/backend/go.sum: -------------------------------------------------------------------------------- 1 | github.com/99designs/gqlgen v0.17.73 h1:A3Ki+rHWqKbAOlg5fxiZBnz6OjW3nwupDHEG15gEsrg= 2 | github.com/99designs/gqlgen v0.17.73/go.mod h1:2RyGWjy2k7W9jxrs8MOQthXGkD3L3oGr0jXW3Pu8lGg= 3 | github.com/Khan/genqlient v0.8.0 h1:Hd1a+E1CQHYbMEKakIkvBH3zW0PWEeiX6Hp1i2kP2WE= 4 | github.com/Khan/genqlient v0.8.0/go.mod h1:hn70SpYjWteRGvxTwo0kfaqg4wxvndECGkfa1fdDdYI= 5 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= 6 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 7 | github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= 8 | github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 9 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 10 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 12 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 13 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 14 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 15 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 16 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 17 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 18 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 19 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 20 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 21 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 22 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= 23 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= 24 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 26 | github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= 27 | github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= 28 | github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= 29 | github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= 30 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 31 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 32 | github.com/vektah/gqlparser/v2 v2.5.26 h1:REqqFkO8+SOEgZHR/eHScjjVjGS8Nk3RMO/juiTobN4= 33 | github.com/vektah/gqlparser/v2 v2.5.26/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= 34 | go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 35 | go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 36 | go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= 37 | go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= 38 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls= 39 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs= 40 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8= 41 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50= 42 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= 43 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= 44 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= 45 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= 46 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= 47 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= 48 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= 49 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= 50 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= 51 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= 52 | go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk= 53 | go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8= 54 | go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= 55 | go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= 56 | go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= 57 | go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= 58 | go.opentelemetry.io/otel/sdk/log v0.8.0 h1:zg7GUYXqxk1jnGF/dTdLPrK06xJdrXgqgFLnI4Crxvs= 59 | go.opentelemetry.io/otel/sdk/log v0.8.0/go.mod h1:50iXr0UVwQrYS45KbruFrEt4LvAdCaWWgIrsN3ZQggo= 60 | go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= 61 | go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= 62 | go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= 63 | go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= 64 | go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= 65 | go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= 66 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 67 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 68 | golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= 69 | golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 70 | golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= 71 | golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 72 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 73 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 74 | golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= 75 | golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 76 | google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= 77 | google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= 78 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= 79 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= 80 | google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM= 81 | google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= 82 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= 83 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 84 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 85 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 86 | -------------------------------------------------------------------------------- /.dagger/workspace/go.sum: -------------------------------------------------------------------------------- 1 | github.com/99designs/gqlgen v0.17.68 h1:vH6jTShCv7sgz1ejXEDNqho7KWlA4ZwSWzVsxyhypAM= 2 | github.com/99designs/gqlgen v0.17.68/go.mod h1:fvCiqQAu2VLhKXez2xFvLmE47QgAPf/KTPN5XQ4rsHQ= 3 | github.com/Khan/genqlient v0.8.0 h1:Hd1a+E1CQHYbMEKakIkvBH3zW0PWEeiX6Hp1i2kP2WE= 4 | github.com/Khan/genqlient v0.8.0/go.mod h1:hn70SpYjWteRGvxTwo0kfaqg4wxvndECGkfa1fdDdYI= 5 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= 6 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 7 | github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= 8 | github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 9 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 10 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 12 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 13 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 14 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 15 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 16 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 17 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 18 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 19 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 20 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 21 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 22 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= 23 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= 24 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 26 | github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= 27 | github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= 28 | github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= 29 | github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= 30 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 31 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 32 | github.com/vektah/gqlparser/v2 v2.5.23 h1:PurJ9wpgEVB7tty1seRUwkIDa/QH5RzkzraiKIjKLfA= 33 | github.com/vektah/gqlparser/v2 v2.5.23/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= 34 | go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 35 | go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 36 | go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= 37 | go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= 38 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls= 39 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs= 40 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8= 41 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50= 42 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= 43 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= 44 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= 45 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= 46 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= 47 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= 48 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= 49 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= 50 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= 51 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= 52 | go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk= 53 | go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8= 54 | go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= 55 | go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= 56 | go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= 57 | go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= 58 | go.opentelemetry.io/otel/sdk/log v0.8.0 h1:zg7GUYXqxk1jnGF/dTdLPrK06xJdrXgqgFLnI4Crxvs= 59 | go.opentelemetry.io/otel/sdk/log v0.8.0/go.mod h1:50iXr0UVwQrYS45KbruFrEt4LvAdCaWWgIrsN3ZQggo= 60 | go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= 61 | go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= 62 | go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= 63 | go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= 64 | go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= 65 | go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= 66 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 67 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 68 | golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= 69 | golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 70 | golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= 71 | golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 72 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 73 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 74 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 75 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 76 | google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= 77 | google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= 78 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= 79 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= 80 | google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= 81 | google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= 82 | google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= 83 | google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 84 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 85 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 86 | -------------------------------------------------------------------------------- /.dagger/go.sum: -------------------------------------------------------------------------------- 1 | github.com/99designs/gqlgen v0.17.75 h1:GwHJsptXWLHeY7JO8b7YueUI4w9Pom6wJTICosDtQuI= 2 | github.com/99designs/gqlgen v0.17.75/go.mod h1:p7gbTpdnHyl70hmSpM8XG8GiKwmCv+T5zkdY8U8bLog= 3 | github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= 4 | github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU= 5 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= 6 | github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 7 | github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= 8 | github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 9 | github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= 10 | github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= 11 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 12 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 13 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 14 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 15 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 16 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 17 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 18 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 19 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 20 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 21 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 22 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 23 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 24 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= 25 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= 26 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 27 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 28 | github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= 29 | github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= 30 | github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= 31 | github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= 32 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 33 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 34 | github.com/vektah/gqlparser/v2 v2.5.28 h1:bIulcl3LF69ba6EiZVGD88y4MkM+Jxrf3P2MX8xLRkY= 35 | github.com/vektah/gqlparser/v2 v2.5.28/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= 36 | go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 37 | go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 38 | go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= 39 | go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= 40 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= 41 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= 42 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= 43 | go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= 44 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= 45 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= 46 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= 47 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= 48 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= 49 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= 50 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= 51 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= 52 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= 53 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= 54 | go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= 55 | go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= 56 | go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= 57 | go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= 58 | go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= 59 | go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= 60 | go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= 61 | go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= 62 | go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= 63 | go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= 64 | go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= 65 | go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= 66 | go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= 67 | go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= 68 | go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= 69 | go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= 70 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 71 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 72 | golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= 73 | golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= 74 | golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= 75 | golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 76 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= 77 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 78 | golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= 79 | golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= 80 | google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0= 81 | google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto= 82 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34= 83 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= 84 | google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= 85 | google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= 86 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= 87 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 88 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 89 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /.dagger/frontend/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@dagger.io/dagger@./sdk": 6 | version "0.0.0" 7 | dependencies: 8 | "@grpc/grpc-js" "^1.13.1" 9 | "@lifeomic/axios-fetch" "^3.1.0" 10 | "@opentelemetry/api" "^1.9.0" 11 | "@opentelemetry/core" "^2.0.0" 12 | "@opentelemetry/exporter-trace-otlp-http" "^0.200.0" 13 | "@opentelemetry/sdk-metrics" "^2.0.0" 14 | "@opentelemetry/sdk-node" "^0.200.0" 15 | "@opentelemetry/semantic-conventions" "^1.30.0" 16 | adm-zip "^0.5.16" 17 | env-paths "^3.0.0" 18 | execa "^9.5.2" 19 | graphql "^16.10.0" 20 | graphql-request "^7.1.2" 21 | graphql-tag "^2.12.6" 22 | node-color-log "^12.0.1" 23 | node-fetch "^3.3.2" 24 | reflect-metadata "^0.2.2" 25 | tar "^7.4.2" 26 | typescript "^5.8.2" 27 | 28 | "@graphql-typed-document-node/core@^3.2.0": 29 | version "3.2.0" 30 | resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" 31 | integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== 32 | 33 | "@grpc/grpc-js@^1.13.1": 34 | version "1.13.1" 35 | resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.13.1.tgz#0fdd678dddc0d64d958ba7b420652fe62180ed50" 36 | integrity sha512-z5nNuIs75S73ZULjPDe5QCNTiCv7FyBZXEVWOyAHtcebnuJf0g1SuueI3U1/z/KK39XyAQRUC+C9ZQJOtgHynA== 37 | dependencies: 38 | "@grpc/proto-loader" "^0.7.13" 39 | "@js-sdsl/ordered-map" "^4.4.2" 40 | 41 | "@grpc/grpc-js@^1.7.1": 42 | version "1.12.6" 43 | resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.12.6.tgz#a3586ffdfb6a1f5cd5b4866dec9074c4a1e65472" 44 | integrity sha512-JXUj6PI0oqqzTGvKtzOkxtpsyPRNsrmhh41TtIz/zEB6J+AUiZZ0dxWzcMwO9Ns5rmSPuMdghlTbUuqIM48d3Q== 45 | dependencies: 46 | "@grpc/proto-loader" "^0.7.13" 47 | "@js-sdsl/ordered-map" "^4.4.2" 48 | 49 | "@grpc/proto-loader@^0.7.13": 50 | version "0.7.13" 51 | resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.13.tgz#f6a44b2b7c9f7b609f5748c6eac2d420e37670cf" 52 | integrity sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw== 53 | dependencies: 54 | lodash.camelcase "^4.3.0" 55 | long "^5.0.0" 56 | protobufjs "^7.2.5" 57 | yargs "^17.7.2" 58 | 59 | "@isaacs/cliui@^8.0.2": 60 | version "8.0.2" 61 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 62 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 63 | dependencies: 64 | string-width "^5.1.2" 65 | string-width-cjs "npm:string-width@^4.2.0" 66 | strip-ansi "^7.0.1" 67 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 68 | wrap-ansi "^8.1.0" 69 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 70 | 71 | "@isaacs/fs-minipass@^4.0.0": 72 | version "4.0.1" 73 | resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32" 74 | integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w== 75 | dependencies: 76 | minipass "^7.0.4" 77 | 78 | "@js-sdsl/ordered-map@^4.4.2": 79 | version "4.4.2" 80 | resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" 81 | integrity sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw== 82 | 83 | "@lifeomic/axios-fetch@^3.1.0": 84 | version "3.1.0" 85 | resolved "https://registry.yarnpkg.com/@lifeomic/axios-fetch/-/axios-fetch-3.1.0.tgz#483bc794c8a77c9ed077e91f107feeb2096a345f" 86 | integrity sha512-C6ceAnh8W19KuekFsCiK1A+AMBirQFTnoEqMZQ7HE6VXJ18zjGofdXxLU8RTo2gZp/yZK5ufmPwIvRtejj1gxg== 87 | dependencies: 88 | "@types/node-fetch" "^2.5.10" 89 | 90 | "@opentelemetry/api-logs@0.200.0": 91 | version "0.200.0" 92 | resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.200.0.tgz#f9015fd844920c13968715b3cdccf5a4d4ff907e" 93 | integrity sha512-IKJBQxh91qJ+3ssRly5hYEJ8NDHu9oY/B1PXVSCWf7zytmYO9RNLB0Ox9XQ/fJ8m6gY6Q6NtBWlmXfaXt5Uc4Q== 94 | dependencies: 95 | "@opentelemetry/api" "^1.3.0" 96 | 97 | "@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.9.0": 98 | version "1.9.0" 99 | resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" 100 | integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== 101 | 102 | "@opentelemetry/context-async-hooks@2.0.0": 103 | version "2.0.0" 104 | resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.0.tgz#c98a727238ca199cda943780acf6124af8d8cd80" 105 | integrity sha512-IEkJGzK1A9v3/EHjXh3s2IiFc6L4jfK+lNgKVgUjeUJQRRhnVFMIO3TAvKwonm9O1HebCuoOt98v8bZW7oVQHA== 106 | 107 | "@opentelemetry/core@2.0.0", "@opentelemetry/core@^2.0.0": 108 | version "2.0.0" 109 | resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-2.0.0.tgz#37e9f0e9ddec4479b267aca6f32d88757c941b3a" 110 | integrity sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ== 111 | dependencies: 112 | "@opentelemetry/semantic-conventions" "^1.29.0" 113 | 114 | "@opentelemetry/exporter-logs-otlp-grpc@0.200.0": 115 | version "0.200.0" 116 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.200.0.tgz#693e0f7041c533061d0689ab43d64d039078ee7a" 117 | integrity sha512-+3MDfa5YQPGM3WXxW9kqGD85Q7s9wlEMVNhXXG7tYFLnIeaseUt9YtCeFhEDFzfEktacdFpOtXmJuNW8cHbU5A== 118 | dependencies: 119 | "@grpc/grpc-js" "^1.7.1" 120 | "@opentelemetry/core" "2.0.0" 121 | "@opentelemetry/otlp-exporter-base" "0.200.0" 122 | "@opentelemetry/otlp-grpc-exporter-base" "0.200.0" 123 | "@opentelemetry/otlp-transformer" "0.200.0" 124 | "@opentelemetry/sdk-logs" "0.200.0" 125 | 126 | "@opentelemetry/exporter-logs-otlp-http@0.200.0": 127 | version "0.200.0" 128 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.200.0.tgz#3a99c9554f871b5c6cddb8716316c125d4edca6c" 129 | integrity sha512-KfWw49htbGGp9s8N4KI8EQ9XuqKJ0VG+yVYVYFiCYSjEV32qpQ5qZ9UZBzOZ6xRb+E16SXOSCT3RkqBVSABZ+g== 130 | dependencies: 131 | "@opentelemetry/api-logs" "0.200.0" 132 | "@opentelemetry/core" "2.0.0" 133 | "@opentelemetry/otlp-exporter-base" "0.200.0" 134 | "@opentelemetry/otlp-transformer" "0.200.0" 135 | "@opentelemetry/sdk-logs" "0.200.0" 136 | 137 | "@opentelemetry/exporter-logs-otlp-proto@0.200.0": 138 | version "0.200.0" 139 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.200.0.tgz#53573ea43bce4129bcb18bda172a95c6535bb1a2" 140 | integrity sha512-GmahpUU/55hxfH4TP77ChOfftADsCq/nuri73I/AVLe2s4NIglvTsaACkFVZAVmnXXyPS00Fk3x27WS3yO07zA== 141 | dependencies: 142 | "@opentelemetry/api-logs" "0.200.0" 143 | "@opentelemetry/core" "2.0.0" 144 | "@opentelemetry/otlp-exporter-base" "0.200.0" 145 | "@opentelemetry/otlp-transformer" "0.200.0" 146 | "@opentelemetry/resources" "2.0.0" 147 | "@opentelemetry/sdk-logs" "0.200.0" 148 | "@opentelemetry/sdk-trace-base" "2.0.0" 149 | 150 | "@opentelemetry/exporter-metrics-otlp-grpc@0.200.0": 151 | version "0.200.0" 152 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.200.0.tgz#f9a4d209083a6a12489c4ae4c20e6923a1780c88" 153 | integrity sha512-uHawPRvKIrhqH09GloTuYeq2BjyieYHIpiklOvxm9zhrCL2eRsnI/6g9v2BZTVtGp8tEgIa7rCQ6Ltxw6NBgew== 154 | dependencies: 155 | "@grpc/grpc-js" "^1.7.1" 156 | "@opentelemetry/core" "2.0.0" 157 | "@opentelemetry/exporter-metrics-otlp-http" "0.200.0" 158 | "@opentelemetry/otlp-exporter-base" "0.200.0" 159 | "@opentelemetry/otlp-grpc-exporter-base" "0.200.0" 160 | "@opentelemetry/otlp-transformer" "0.200.0" 161 | "@opentelemetry/resources" "2.0.0" 162 | "@opentelemetry/sdk-metrics" "2.0.0" 163 | 164 | "@opentelemetry/exporter-metrics-otlp-http@0.200.0": 165 | version "0.200.0" 166 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.200.0.tgz#daa28a2b868bacf02efb153fa8780d078807919e" 167 | integrity sha512-5BiR6i8yHc9+qW7F6LqkuUnIzVNA7lt0qRxIKcKT+gq3eGUPHZ3DY29sfxI3tkvnwMgtnHDMNze5DdxW39HsAw== 168 | dependencies: 169 | "@opentelemetry/core" "2.0.0" 170 | "@opentelemetry/otlp-exporter-base" "0.200.0" 171 | "@opentelemetry/otlp-transformer" "0.200.0" 172 | "@opentelemetry/resources" "2.0.0" 173 | "@opentelemetry/sdk-metrics" "2.0.0" 174 | 175 | "@opentelemetry/exporter-metrics-otlp-proto@0.200.0": 176 | version "0.200.0" 177 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.200.0.tgz#5a494e2df8703be2f1f5f01629dfd48a6d39e5a6" 178 | integrity sha512-E+uPj0yyvz81U9pvLZp3oHtFrEzNSqKGVkIViTQY1rH3TOobeJPSpLnTVXACnCwkPR5XeTvPnK3pZ2Kni8AFMg== 179 | dependencies: 180 | "@opentelemetry/core" "2.0.0" 181 | "@opentelemetry/exporter-metrics-otlp-http" "0.200.0" 182 | "@opentelemetry/otlp-exporter-base" "0.200.0" 183 | "@opentelemetry/otlp-transformer" "0.200.0" 184 | "@opentelemetry/resources" "2.0.0" 185 | "@opentelemetry/sdk-metrics" "2.0.0" 186 | 187 | "@opentelemetry/exporter-prometheus@0.200.0": 188 | version "0.200.0" 189 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.200.0.tgz#8f3dd3a8903447563a5be30ddf9e7bfb1e7ad127" 190 | integrity sha512-ZYdlU9r0USuuYppiDyU2VFRA0kFl855ylnb3N/2aOlXrbA4PMCznen7gmPbetGQu7pz8Jbaf4fwvrDnVdQQXSw== 191 | dependencies: 192 | "@opentelemetry/core" "2.0.0" 193 | "@opentelemetry/resources" "2.0.0" 194 | "@opentelemetry/sdk-metrics" "2.0.0" 195 | 196 | "@opentelemetry/exporter-trace-otlp-grpc@0.200.0": 197 | version "0.200.0" 198 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.200.0.tgz#e259367f324c01342bf3f0175c52d9f4e61a345f" 199 | integrity sha512-hmeZrUkFl1YMsgukSuHCFPYeF9df0hHoKeHUthRKFCxiURs+GwF1VuabuHmBMZnjTbsuvNjOB+JSs37Csem/5Q== 200 | dependencies: 201 | "@grpc/grpc-js" "^1.7.1" 202 | "@opentelemetry/core" "2.0.0" 203 | "@opentelemetry/otlp-exporter-base" "0.200.0" 204 | "@opentelemetry/otlp-grpc-exporter-base" "0.200.0" 205 | "@opentelemetry/otlp-transformer" "0.200.0" 206 | "@opentelemetry/resources" "2.0.0" 207 | "@opentelemetry/sdk-trace-base" "2.0.0" 208 | 209 | "@opentelemetry/exporter-trace-otlp-http@0.200.0", "@opentelemetry/exporter-trace-otlp-http@^0.200.0": 210 | version "0.200.0" 211 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.200.0.tgz#ddf2bbdff5157a89f64aad6dad44c394872d589d" 212 | integrity sha512-Goi//m/7ZHeUedxTGVmEzH19NgqJY+Bzr6zXo1Rni1+hwqaksEyJ44gdlEMREu6dzX1DlAaH/qSykSVzdrdafA== 213 | dependencies: 214 | "@opentelemetry/core" "2.0.0" 215 | "@opentelemetry/otlp-exporter-base" "0.200.0" 216 | "@opentelemetry/otlp-transformer" "0.200.0" 217 | "@opentelemetry/resources" "2.0.0" 218 | "@opentelemetry/sdk-trace-base" "2.0.0" 219 | 220 | "@opentelemetry/exporter-trace-otlp-proto@0.200.0": 221 | version "0.200.0" 222 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.200.0.tgz#f3f149e6bad8c899c8f1e5c58e5d855ce07f7319" 223 | integrity sha512-V9TDSD3PjK1OREw2iT9TUTzNYEVWJk4Nhodzhp9eiz4onDMYmPy3LaGbPv81yIR6dUb/hNp/SIhpiCHwFUq2Vg== 224 | dependencies: 225 | "@opentelemetry/core" "2.0.0" 226 | "@opentelemetry/otlp-exporter-base" "0.200.0" 227 | "@opentelemetry/otlp-transformer" "0.200.0" 228 | "@opentelemetry/resources" "2.0.0" 229 | "@opentelemetry/sdk-trace-base" "2.0.0" 230 | 231 | "@opentelemetry/exporter-zipkin@2.0.0": 232 | version "2.0.0" 233 | resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.0.0.tgz#6aca658d64f5e8bc079b07ee0a3076c4ca328ec9" 234 | integrity sha512-icxaKZ+jZL/NHXX8Aru4HGsrdhK0MLcuRXkX5G5IRmCgoRLw+Br6I/nMVozX2xjGGwV7hw2g+4Slj8K7s4HbVg== 235 | dependencies: 236 | "@opentelemetry/core" "2.0.0" 237 | "@opentelemetry/resources" "2.0.0" 238 | "@opentelemetry/sdk-trace-base" "2.0.0" 239 | "@opentelemetry/semantic-conventions" "^1.29.0" 240 | 241 | "@opentelemetry/instrumentation@0.200.0": 242 | version "0.200.0" 243 | resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.200.0.tgz#29d1d4f70cbf0cb1ca9f2f78966379b0be96bddc" 244 | integrity sha512-pmPlzfJd+vvgaZd/reMsC8RWgTXn2WY1OWT5RT42m3aOn5532TozwXNDhg1vzqJ+jnvmkREcdLr27ebJEQt0Jg== 245 | dependencies: 246 | "@opentelemetry/api-logs" "0.200.0" 247 | "@types/shimmer" "^1.2.0" 248 | import-in-the-middle "^1.8.1" 249 | require-in-the-middle "^7.1.1" 250 | shimmer "^1.2.1" 251 | 252 | "@opentelemetry/otlp-exporter-base@0.200.0": 253 | version "0.200.0" 254 | resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.200.0.tgz#906bcf2e59815c8ded732d328f6bc060fb7b0459" 255 | integrity sha512-IxJgA3FD7q4V6gGq4bnmQM5nTIyMDkoGFGrBrrDjB6onEiq1pafma55V+bHvGYLWvcqbBbRfezr1GED88lacEQ== 256 | dependencies: 257 | "@opentelemetry/core" "2.0.0" 258 | "@opentelemetry/otlp-transformer" "0.200.0" 259 | 260 | "@opentelemetry/otlp-grpc-exporter-base@0.200.0": 261 | version "0.200.0" 262 | resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.200.0.tgz#cfc6cfd4def7d47f84e43d438d75cb463c67bf0d" 263 | integrity sha512-CK2S+bFgOZ66Bsu5hlDeOX6cvW5FVtVjFFbWuaJP0ELxJKBB6HlbLZQ2phqz/uLj1cWap5xJr/PsR3iGoB7Vqw== 264 | dependencies: 265 | "@grpc/grpc-js" "^1.7.1" 266 | "@opentelemetry/core" "2.0.0" 267 | "@opentelemetry/otlp-exporter-base" "0.200.0" 268 | "@opentelemetry/otlp-transformer" "0.200.0" 269 | 270 | "@opentelemetry/otlp-transformer@0.200.0": 271 | version "0.200.0" 272 | resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.200.0.tgz#19afb2274554cb74e2d2b7e32a54a7f7d83c8642" 273 | integrity sha512-+9YDZbYybOnv7sWzebWOeK6gKyt2XE7iarSyBFkwwnP559pEevKOUD8NyDHhRjCSp13ybh9iVXlMfcj/DwF/yw== 274 | dependencies: 275 | "@opentelemetry/api-logs" "0.200.0" 276 | "@opentelemetry/core" "2.0.0" 277 | "@opentelemetry/resources" "2.0.0" 278 | "@opentelemetry/sdk-logs" "0.200.0" 279 | "@opentelemetry/sdk-metrics" "2.0.0" 280 | "@opentelemetry/sdk-trace-base" "2.0.0" 281 | protobufjs "^7.3.0" 282 | 283 | "@opentelemetry/propagator-b3@2.0.0": 284 | version "2.0.0" 285 | resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-2.0.0.tgz#1b6244ef2d08a70672521a9aff56e485bd607c17" 286 | integrity sha512-blx9S2EI49Ycuw6VZq+bkpaIoiJFhsDuvFGhBIoH3vJ5oYjJ2U0s3fAM5jYft99xVIAv6HqoPtlP9gpVA2IZtA== 287 | dependencies: 288 | "@opentelemetry/core" "2.0.0" 289 | 290 | "@opentelemetry/propagator-jaeger@2.0.0": 291 | version "2.0.0" 292 | resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.0.0.tgz#288d6767dea554db684fd5e144ad8653d83fd2ea" 293 | integrity sha512-Mbm/LSFyAtQKP0AQah4AfGgsD+vsZcyreZoQ5okFBk33hU7AquU4TltgyL9dvaO8/Zkoud8/0gEvwfOZ5d7EPA== 294 | dependencies: 295 | "@opentelemetry/core" "2.0.0" 296 | 297 | "@opentelemetry/resources@2.0.0": 298 | version "2.0.0" 299 | resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-2.0.0.tgz#15c04794c32b7d0b3c7589225ece6ae9bba25989" 300 | integrity sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg== 301 | dependencies: 302 | "@opentelemetry/core" "2.0.0" 303 | "@opentelemetry/semantic-conventions" "^1.29.0" 304 | 305 | "@opentelemetry/sdk-logs@0.200.0": 306 | version "0.200.0" 307 | resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.200.0.tgz#893d86cefa6f2c02a7cd03d5cb4a959eed3653d1" 308 | integrity sha512-VZG870063NLfObmQQNtCVcdXXLzI3vOjjrRENmU37HYiPFa0ZXpXVDsTD02Nh3AT3xYJzQaWKl2X2lQ2l7TWJA== 309 | dependencies: 310 | "@opentelemetry/api-logs" "0.200.0" 311 | "@opentelemetry/core" "2.0.0" 312 | "@opentelemetry/resources" "2.0.0" 313 | 314 | "@opentelemetry/sdk-metrics@2.0.0", "@opentelemetry/sdk-metrics@^2.0.0": 315 | version "2.0.0" 316 | resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.0.tgz#aba86060bc363c661ca286339c5b04590e298b69" 317 | integrity sha512-Bvy8QDjO05umd0+j+gDeWcTaVa1/R2lDj/eOvjzpm8VQj1K1vVZJuyjThpV5/lSHyYW2JaHF2IQ7Z8twJFAhjA== 318 | dependencies: 319 | "@opentelemetry/core" "2.0.0" 320 | "@opentelemetry/resources" "2.0.0" 321 | 322 | "@opentelemetry/sdk-node@^0.200.0": 323 | version "0.200.0" 324 | resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-node/-/sdk-node-0.200.0.tgz#033d0641da628f1537cf7442f41cd77c048923ae" 325 | integrity sha512-S/YSy9GIswnhYoDor1RusNkmRughipvTCOQrlF1dzI70yQaf68qgf5WMnzUxdlCl3/et/pvaO75xfPfuEmCK5A== 326 | dependencies: 327 | "@opentelemetry/api-logs" "0.200.0" 328 | "@opentelemetry/core" "2.0.0" 329 | "@opentelemetry/exporter-logs-otlp-grpc" "0.200.0" 330 | "@opentelemetry/exporter-logs-otlp-http" "0.200.0" 331 | "@opentelemetry/exporter-logs-otlp-proto" "0.200.0" 332 | "@opentelemetry/exporter-metrics-otlp-grpc" "0.200.0" 333 | "@opentelemetry/exporter-metrics-otlp-http" "0.200.0" 334 | "@opentelemetry/exporter-metrics-otlp-proto" "0.200.0" 335 | "@opentelemetry/exporter-prometheus" "0.200.0" 336 | "@opentelemetry/exporter-trace-otlp-grpc" "0.200.0" 337 | "@opentelemetry/exporter-trace-otlp-http" "0.200.0" 338 | "@opentelemetry/exporter-trace-otlp-proto" "0.200.0" 339 | "@opentelemetry/exporter-zipkin" "2.0.0" 340 | "@opentelemetry/instrumentation" "0.200.0" 341 | "@opentelemetry/propagator-b3" "2.0.0" 342 | "@opentelemetry/propagator-jaeger" "2.0.0" 343 | "@opentelemetry/resources" "2.0.0" 344 | "@opentelemetry/sdk-logs" "0.200.0" 345 | "@opentelemetry/sdk-metrics" "2.0.0" 346 | "@opentelemetry/sdk-trace-base" "2.0.0" 347 | "@opentelemetry/sdk-trace-node" "2.0.0" 348 | "@opentelemetry/semantic-conventions" "^1.29.0" 349 | 350 | "@opentelemetry/sdk-trace-base@2.0.0": 351 | version "2.0.0" 352 | resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.0.tgz#ebc06ea7537dea62f3882f8236c1234f4faf6b23" 353 | integrity sha512-qQnYdX+ZCkonM7tA5iU4fSRsVxbFGml8jbxOgipRGMFHKaXKHQ30js03rTobYjKjIfnOsZSbHKWF0/0v0OQGfw== 354 | dependencies: 355 | "@opentelemetry/core" "2.0.0" 356 | "@opentelemetry/resources" "2.0.0" 357 | "@opentelemetry/semantic-conventions" "^1.29.0" 358 | 359 | "@opentelemetry/sdk-trace-node@2.0.0": 360 | version "2.0.0" 361 | resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.0.0.tgz#ef9f8ab77ccb41a9c9ff272f6bf4bb6999491f5b" 362 | integrity sha512-omdilCZozUjQwY3uZRBwbaRMJ3p09l4t187Lsdf0dGMye9WKD4NGcpgZRvqhI1dwcH6og+YXQEtoO9Wx3ykilg== 363 | dependencies: 364 | "@opentelemetry/context-async-hooks" "2.0.0" 365 | "@opentelemetry/core" "2.0.0" 366 | "@opentelemetry/sdk-trace-base" "2.0.0" 367 | 368 | "@opentelemetry/semantic-conventions@^1.29.0", "@opentelemetry/semantic-conventions@^1.30.0": 369 | version "1.30.0" 370 | resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.30.0.tgz#3a42c4c475482f2ec87c12aad98832dc0087dc9a" 371 | integrity sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw== 372 | 373 | "@pkgjs/parseargs@^0.11.0": 374 | version "0.11.0" 375 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 376 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 377 | 378 | "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": 379 | version "1.1.2" 380 | resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" 381 | integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== 382 | 383 | "@protobufjs/base64@^1.1.2": 384 | version "1.1.2" 385 | resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" 386 | integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== 387 | 388 | "@protobufjs/codegen@^2.0.4": 389 | version "2.0.4" 390 | resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" 391 | integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== 392 | 393 | "@protobufjs/eventemitter@^1.1.0": 394 | version "1.1.0" 395 | resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" 396 | integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== 397 | 398 | "@protobufjs/fetch@^1.1.0": 399 | version "1.1.0" 400 | resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" 401 | integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== 402 | dependencies: 403 | "@protobufjs/aspromise" "^1.1.1" 404 | "@protobufjs/inquire" "^1.1.0" 405 | 406 | "@protobufjs/float@^1.0.2": 407 | version "1.0.2" 408 | resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" 409 | integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== 410 | 411 | "@protobufjs/inquire@^1.1.0": 412 | version "1.1.0" 413 | resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" 414 | integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== 415 | 416 | "@protobufjs/path@^1.1.2": 417 | version "1.1.2" 418 | resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" 419 | integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== 420 | 421 | "@protobufjs/pool@^1.1.0": 422 | version "1.1.0" 423 | resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" 424 | integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== 425 | 426 | "@protobufjs/utf8@^1.1.0": 427 | version "1.1.0" 428 | resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" 429 | integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== 430 | 431 | "@sec-ant/readable-stream@^0.4.1": 432 | version "0.4.1" 433 | resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" 434 | integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== 435 | 436 | "@sindresorhus/merge-streams@^4.0.0": 437 | version "4.0.0" 438 | resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz#abb11d99aeb6d27f1b563c38147a72d50058e339" 439 | integrity sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ== 440 | 441 | "@types/node-fetch@^2.5.10": 442 | version "2.6.12" 443 | resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.12.tgz#8ab5c3ef8330f13100a7479e2cd56d3386830a03" 444 | integrity sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA== 445 | dependencies: 446 | "@types/node" "*" 447 | form-data "^4.0.0" 448 | 449 | "@types/node@*", "@types/node@>=13.7.0": 450 | version "22.13.10" 451 | resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.10.tgz#df9ea358c5ed991266becc3109dc2dc9125d77e4" 452 | integrity sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw== 453 | dependencies: 454 | undici-types "~6.20.0" 455 | 456 | "@types/shimmer@^1.2.0": 457 | version "1.2.0" 458 | resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.2.0.tgz#9b706af96fa06416828842397a70dfbbf1c14ded" 459 | integrity sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg== 460 | 461 | acorn-import-attributes@^1.9.5: 462 | version "1.9.5" 463 | resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" 464 | integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== 465 | 466 | acorn@^8.14.0: 467 | version "8.14.1" 468 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" 469 | integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== 470 | 471 | adm-zip@^0.5.16: 472 | version "0.5.16" 473 | resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.16.tgz#0b5e4c779f07dedea5805cdccb1147071d94a909" 474 | integrity sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ== 475 | 476 | ansi-regex@^5.0.1: 477 | version "5.0.1" 478 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 479 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 480 | 481 | ansi-regex@^6.0.1: 482 | version "6.1.0" 483 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" 484 | integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== 485 | 486 | ansi-styles@^4.0.0: 487 | version "4.3.0" 488 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 489 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 490 | dependencies: 491 | color-convert "^2.0.1" 492 | 493 | ansi-styles@^6.1.0: 494 | version "6.2.1" 495 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 496 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 497 | 498 | asynckit@^0.4.0: 499 | version "0.4.0" 500 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 501 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 502 | 503 | balanced-match@^1.0.0: 504 | version "1.0.2" 505 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 506 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 507 | 508 | brace-expansion@^2.0.1: 509 | version "2.0.1" 510 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 511 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 512 | dependencies: 513 | balanced-match "^1.0.0" 514 | 515 | call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: 516 | version "1.0.2" 517 | resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" 518 | integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== 519 | dependencies: 520 | es-errors "^1.3.0" 521 | function-bind "^1.1.2" 522 | 523 | chownr@^3.0.0: 524 | version "3.0.0" 525 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4" 526 | integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== 527 | 528 | cjs-module-lexer@^1.2.2: 529 | version "1.4.3" 530 | resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" 531 | integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== 532 | 533 | cliui@^8.0.1: 534 | version "8.0.1" 535 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" 536 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== 537 | dependencies: 538 | string-width "^4.2.0" 539 | strip-ansi "^6.0.1" 540 | wrap-ansi "^7.0.0" 541 | 542 | color-convert@^2.0.1: 543 | version "2.0.1" 544 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 545 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 546 | dependencies: 547 | color-name "~1.1.4" 548 | 549 | color-name@~1.1.4: 550 | version "1.1.4" 551 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 552 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 553 | 554 | combined-stream@^1.0.8: 555 | version "1.0.8" 556 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 557 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 558 | dependencies: 559 | delayed-stream "~1.0.0" 560 | 561 | cross-spawn@^7.0.3, cross-spawn@^7.0.6: 562 | version "7.0.6" 563 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" 564 | integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== 565 | dependencies: 566 | path-key "^3.1.0" 567 | shebang-command "^2.0.0" 568 | which "^2.0.1" 569 | 570 | data-uri-to-buffer@^4.0.0: 571 | version "4.0.1" 572 | resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" 573 | integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== 574 | 575 | debug@^4.3.5: 576 | version "4.4.0" 577 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" 578 | integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== 579 | dependencies: 580 | ms "^2.1.3" 581 | 582 | delayed-stream@~1.0.0: 583 | version "1.0.0" 584 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 585 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 586 | 587 | dunder-proto@^1.0.1: 588 | version "1.0.1" 589 | resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" 590 | integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== 591 | dependencies: 592 | call-bind-apply-helpers "^1.0.1" 593 | es-errors "^1.3.0" 594 | gopd "^1.2.0" 595 | 596 | eastasianwidth@^0.2.0: 597 | version "0.2.0" 598 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 599 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 600 | 601 | emoji-regex@^8.0.0: 602 | version "8.0.0" 603 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 604 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 605 | 606 | emoji-regex@^9.2.2: 607 | version "9.2.2" 608 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 609 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 610 | 611 | env-paths@^3.0.0: 612 | version "3.0.0" 613 | resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-3.0.0.tgz#2f1e89c2f6dbd3408e1b1711dd82d62e317f58da" 614 | integrity sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A== 615 | 616 | es-define-property@^1.0.1: 617 | version "1.0.1" 618 | resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" 619 | integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== 620 | 621 | es-errors@^1.3.0: 622 | version "1.3.0" 623 | resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" 624 | integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== 625 | 626 | es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: 627 | version "1.1.1" 628 | resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" 629 | integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== 630 | dependencies: 631 | es-errors "^1.3.0" 632 | 633 | es-set-tostringtag@^2.1.0: 634 | version "2.1.0" 635 | resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" 636 | integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== 637 | dependencies: 638 | es-errors "^1.3.0" 639 | get-intrinsic "^1.2.6" 640 | has-tostringtag "^1.0.2" 641 | hasown "^2.0.2" 642 | 643 | escalade@^3.1.1: 644 | version "3.2.0" 645 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" 646 | integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== 647 | 648 | execa@^9.5.2: 649 | version "9.5.2" 650 | resolved "https://registry.yarnpkg.com/execa/-/execa-9.5.2.tgz#a4551034ee0795e241025d2f987dab3f4242dff2" 651 | integrity sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q== 652 | dependencies: 653 | "@sindresorhus/merge-streams" "^4.0.0" 654 | cross-spawn "^7.0.3" 655 | figures "^6.1.0" 656 | get-stream "^9.0.0" 657 | human-signals "^8.0.0" 658 | is-plain-obj "^4.1.0" 659 | is-stream "^4.0.1" 660 | npm-run-path "^6.0.0" 661 | pretty-ms "^9.0.0" 662 | signal-exit "^4.1.0" 663 | strip-final-newline "^4.0.0" 664 | yoctocolors "^2.0.0" 665 | 666 | fetch-blob@^3.1.2, fetch-blob@^3.1.4: 667 | version "3.2.0" 668 | resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" 669 | integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== 670 | dependencies: 671 | node-domexception "^1.0.0" 672 | web-streams-polyfill "^3.0.3" 673 | 674 | figures@^6.1.0: 675 | version "6.1.0" 676 | resolved "https://registry.yarnpkg.com/figures/-/figures-6.1.0.tgz#935479f51865fa7479f6fa94fc6fc7ac14e62c4a" 677 | integrity sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg== 678 | dependencies: 679 | is-unicode-supported "^2.0.0" 680 | 681 | foreground-child@^3.1.0: 682 | version "3.3.1" 683 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" 684 | integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== 685 | dependencies: 686 | cross-spawn "^7.0.6" 687 | signal-exit "^4.0.1" 688 | 689 | form-data@^4.0.0: 690 | version "4.0.2" 691 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c" 692 | integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== 693 | dependencies: 694 | asynckit "^0.4.0" 695 | combined-stream "^1.0.8" 696 | es-set-tostringtag "^2.1.0" 697 | mime-types "^2.1.12" 698 | 699 | formdata-polyfill@^4.0.10: 700 | version "4.0.10" 701 | resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" 702 | integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== 703 | dependencies: 704 | fetch-blob "^3.1.2" 705 | 706 | function-bind@^1.1.2: 707 | version "1.1.2" 708 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" 709 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 710 | 711 | get-caller-file@^2.0.5: 712 | version "2.0.5" 713 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 714 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 715 | 716 | get-intrinsic@^1.2.6: 717 | version "1.3.0" 718 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" 719 | integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== 720 | dependencies: 721 | call-bind-apply-helpers "^1.0.2" 722 | es-define-property "^1.0.1" 723 | es-errors "^1.3.0" 724 | es-object-atoms "^1.1.1" 725 | function-bind "^1.1.2" 726 | get-proto "^1.0.1" 727 | gopd "^1.2.0" 728 | has-symbols "^1.1.0" 729 | hasown "^2.0.2" 730 | math-intrinsics "^1.1.0" 731 | 732 | get-proto@^1.0.1: 733 | version "1.0.1" 734 | resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" 735 | integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== 736 | dependencies: 737 | dunder-proto "^1.0.1" 738 | es-object-atoms "^1.0.0" 739 | 740 | get-stream@^9.0.0: 741 | version "9.0.1" 742 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" 743 | integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== 744 | dependencies: 745 | "@sec-ant/readable-stream" "^0.4.1" 746 | is-stream "^4.0.1" 747 | 748 | glob@^10.3.7: 749 | version "10.4.5" 750 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" 751 | integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== 752 | dependencies: 753 | foreground-child "^3.1.0" 754 | jackspeak "^3.1.2" 755 | minimatch "^9.0.4" 756 | minipass "^7.1.2" 757 | package-json-from-dist "^1.0.0" 758 | path-scurry "^1.11.1" 759 | 760 | gopd@^1.2.0: 761 | version "1.2.0" 762 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" 763 | integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== 764 | 765 | graphql-request@^7.1.2: 766 | version "7.1.2" 767 | resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-7.1.2.tgz#52d7fd6d8d08c9f0b00c84a091376ce9fbdfa945" 768 | integrity sha512-+XE3iuC55C2di5ZUrB4pjgwe+nIQBuXVIK9J98wrVwojzDW3GMdSBZfxUk8l4j9TieIpjpggclxhNEU9ebGF8w== 769 | dependencies: 770 | "@graphql-typed-document-node/core" "^3.2.0" 771 | 772 | graphql-tag@^2.12.6: 773 | version "2.12.6" 774 | resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" 775 | integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== 776 | dependencies: 777 | tslib "^2.1.0" 778 | 779 | graphql@^16.10.0: 780 | version "16.10.0" 781 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.10.0.tgz#24c01ae0af6b11ea87bf55694429198aaa8e220c" 782 | integrity sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ== 783 | 784 | has-symbols@^1.0.3, has-symbols@^1.1.0: 785 | version "1.1.0" 786 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" 787 | integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== 788 | 789 | has-tostringtag@^1.0.2: 790 | version "1.0.2" 791 | resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" 792 | integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== 793 | dependencies: 794 | has-symbols "^1.0.3" 795 | 796 | hasown@^2.0.2: 797 | version "2.0.2" 798 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" 799 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 800 | dependencies: 801 | function-bind "^1.1.2" 802 | 803 | human-signals@^8.0.0: 804 | version "8.0.0" 805 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-8.0.0.tgz#2d3d63481c7c2319f0373428b01ffe30da6df852" 806 | integrity sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA== 807 | 808 | import-in-the-middle@^1.8.1: 809 | version "1.13.1" 810 | resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.13.1.tgz#789651f9e93dd902a5a306f499ab51eb72b03a12" 811 | integrity sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA== 812 | dependencies: 813 | acorn "^8.14.0" 814 | acorn-import-attributes "^1.9.5" 815 | cjs-module-lexer "^1.2.2" 816 | module-details-from-path "^1.0.3" 817 | 818 | is-core-module@^2.16.0: 819 | version "2.16.1" 820 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" 821 | integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== 822 | dependencies: 823 | hasown "^2.0.2" 824 | 825 | is-fullwidth-code-point@^3.0.0: 826 | version "3.0.0" 827 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 828 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 829 | 830 | is-plain-obj@^4.1.0: 831 | version "4.1.0" 832 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" 833 | integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== 834 | 835 | is-stream@^4.0.1: 836 | version "4.0.1" 837 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" 838 | integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== 839 | 840 | is-unicode-supported@^2.0.0: 841 | version "2.1.0" 842 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" 843 | integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== 844 | 845 | isexe@^2.0.0: 846 | version "2.0.0" 847 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 848 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 849 | 850 | jackspeak@^3.1.2: 851 | version "3.4.3" 852 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" 853 | integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== 854 | dependencies: 855 | "@isaacs/cliui" "^8.0.2" 856 | optionalDependencies: 857 | "@pkgjs/parseargs" "^0.11.0" 858 | 859 | lodash.camelcase@^4.3.0: 860 | version "4.3.0" 861 | resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" 862 | integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== 863 | 864 | long@^5.0.0: 865 | version "5.3.1" 866 | resolved "https://registry.yarnpkg.com/long/-/long-5.3.1.tgz#9d4222d3213f38a5ec809674834e0f0ab21abe96" 867 | integrity sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng== 868 | 869 | lru-cache@^10.2.0: 870 | version "10.4.3" 871 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" 872 | integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== 873 | 874 | math-intrinsics@^1.1.0: 875 | version "1.1.0" 876 | resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" 877 | integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== 878 | 879 | mime-db@1.52.0: 880 | version "1.52.0" 881 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 882 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 883 | 884 | mime-types@^2.1.12: 885 | version "2.1.35" 886 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 887 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 888 | dependencies: 889 | mime-db "1.52.0" 890 | 891 | minimatch@^9.0.4: 892 | version "9.0.5" 893 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" 894 | integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== 895 | dependencies: 896 | brace-expansion "^2.0.1" 897 | 898 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4, minipass@^7.1.2: 899 | version "7.1.2" 900 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" 901 | integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== 902 | 903 | minizlib@^3.0.1: 904 | version "3.0.1" 905 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.0.1.tgz#46d5329d1eb3c83924eff1d3b858ca0a31581012" 906 | integrity sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg== 907 | dependencies: 908 | minipass "^7.0.4" 909 | rimraf "^5.0.5" 910 | 911 | mkdirp@^3.0.1: 912 | version "3.0.1" 913 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" 914 | integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== 915 | 916 | module-details-from-path@^1.0.3: 917 | version "1.0.3" 918 | resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" 919 | integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== 920 | 921 | ms@^2.1.3: 922 | version "2.1.3" 923 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 924 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 925 | 926 | node-color-log@^12.0.1: 927 | version "12.0.1" 928 | resolved "https://registry.yarnpkg.com/node-color-log/-/node-color-log-12.0.1.tgz#47d982e3cb6aa90c2936ca38cd910ef82076c6f5" 929 | integrity sha512-fhbWy00HXAVucPHoji9KNZRtXHcDKuMoVJ3QA+vaMEcAyK6psmJAf5TF9t2SmkybuHz0jre+jgUDyXcFmpgSNg== 930 | 931 | node-domexception@^1.0.0: 932 | version "1.0.0" 933 | resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" 934 | integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== 935 | 936 | node-fetch@^3.3.2: 937 | version "3.3.2" 938 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" 939 | integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== 940 | dependencies: 941 | data-uri-to-buffer "^4.0.0" 942 | fetch-blob "^3.1.4" 943 | formdata-polyfill "^4.0.10" 944 | 945 | npm-run-path@^6.0.0: 946 | version "6.0.0" 947 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-6.0.0.tgz#25cfdc4eae04976f3349c0b1afc089052c362537" 948 | integrity sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA== 949 | dependencies: 950 | path-key "^4.0.0" 951 | unicorn-magic "^0.3.0" 952 | 953 | package-json-from-dist@^1.0.0: 954 | version "1.0.1" 955 | resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" 956 | integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== 957 | 958 | parse-ms@^4.0.0: 959 | version "4.0.0" 960 | resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-4.0.0.tgz#c0c058edd47c2a590151a718990533fd62803df4" 961 | integrity sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== 962 | 963 | path-key@^3.1.0: 964 | version "3.1.1" 965 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 966 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 967 | 968 | path-key@^4.0.0: 969 | version "4.0.0" 970 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" 971 | integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== 972 | 973 | path-parse@^1.0.7: 974 | version "1.0.7" 975 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 976 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 977 | 978 | path-scurry@^1.11.1: 979 | version "1.11.1" 980 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" 981 | integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== 982 | dependencies: 983 | lru-cache "^10.2.0" 984 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 985 | 986 | pretty-ms@^9.0.0: 987 | version "9.2.0" 988 | resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-9.2.0.tgz#e14c0aad6493b69ed63114442a84133d7e560ef0" 989 | integrity sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg== 990 | dependencies: 991 | parse-ms "^4.0.0" 992 | 993 | protobufjs@^7.2.5, protobufjs@^7.3.0: 994 | version "7.4.0" 995 | resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" 996 | integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== 997 | dependencies: 998 | "@protobufjs/aspromise" "^1.1.2" 999 | "@protobufjs/base64" "^1.1.2" 1000 | "@protobufjs/codegen" "^2.0.4" 1001 | "@protobufjs/eventemitter" "^1.1.0" 1002 | "@protobufjs/fetch" "^1.1.0" 1003 | "@protobufjs/float" "^1.0.2" 1004 | "@protobufjs/inquire" "^1.1.0" 1005 | "@protobufjs/path" "^1.1.2" 1006 | "@protobufjs/pool" "^1.1.0" 1007 | "@protobufjs/utf8" "^1.1.0" 1008 | "@types/node" ">=13.7.0" 1009 | long "^5.0.0" 1010 | 1011 | reflect-metadata@^0.2.2: 1012 | version "0.2.2" 1013 | resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" 1014 | integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== 1015 | 1016 | require-directory@^2.1.1: 1017 | version "2.1.1" 1018 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1019 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1020 | 1021 | require-in-the-middle@^7.1.1: 1022 | version "7.5.2" 1023 | resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz#dc25b148affad42e570cf0e41ba30dc00f1703ec" 1024 | integrity sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ== 1025 | dependencies: 1026 | debug "^4.3.5" 1027 | module-details-from-path "^1.0.3" 1028 | resolve "^1.22.8" 1029 | 1030 | resolve@^1.22.8: 1031 | version "1.22.10" 1032 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" 1033 | integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== 1034 | dependencies: 1035 | is-core-module "^2.16.0" 1036 | path-parse "^1.0.7" 1037 | supports-preserve-symlinks-flag "^1.0.0" 1038 | 1039 | rimraf@^5.0.5: 1040 | version "5.0.10" 1041 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c" 1042 | integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ== 1043 | dependencies: 1044 | glob "^10.3.7" 1045 | 1046 | shebang-command@^2.0.0: 1047 | version "2.0.0" 1048 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1049 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1050 | dependencies: 1051 | shebang-regex "^3.0.0" 1052 | 1053 | shebang-regex@^3.0.0: 1054 | version "3.0.0" 1055 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1056 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1057 | 1058 | shimmer@^1.2.1: 1059 | version "1.2.1" 1060 | resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" 1061 | integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== 1062 | 1063 | signal-exit@^4.0.1, signal-exit@^4.1.0: 1064 | version "4.1.0" 1065 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 1066 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 1067 | 1068 | "string-width-cjs@npm:string-width@^4.2.0": 1069 | version "4.2.3" 1070 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1071 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1072 | dependencies: 1073 | emoji-regex "^8.0.0" 1074 | is-fullwidth-code-point "^3.0.0" 1075 | strip-ansi "^6.0.1" 1076 | 1077 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1078 | version "4.2.3" 1079 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1080 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1081 | dependencies: 1082 | emoji-regex "^8.0.0" 1083 | is-fullwidth-code-point "^3.0.0" 1084 | strip-ansi "^6.0.1" 1085 | 1086 | string-width@^5.0.1, string-width@^5.1.2: 1087 | version "5.1.2" 1088 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1089 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1090 | dependencies: 1091 | eastasianwidth "^0.2.0" 1092 | emoji-regex "^9.2.2" 1093 | strip-ansi "^7.0.1" 1094 | 1095 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1": 1096 | version "6.0.1" 1097 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1098 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1099 | dependencies: 1100 | ansi-regex "^5.0.1" 1101 | 1102 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1103 | version "6.0.1" 1104 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1105 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1106 | dependencies: 1107 | ansi-regex "^5.0.1" 1108 | 1109 | strip-ansi@^7.0.1: 1110 | version "7.1.0" 1111 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 1112 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 1113 | dependencies: 1114 | ansi-regex "^6.0.1" 1115 | 1116 | strip-final-newline@^4.0.0: 1117 | version "4.0.0" 1118 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" 1119 | integrity sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw== 1120 | 1121 | supports-preserve-symlinks-flag@^1.0.0: 1122 | version "1.0.0" 1123 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1124 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1125 | 1126 | tar@^7.4.2: 1127 | version "7.4.3" 1128 | resolved "https://registry.yarnpkg.com/tar/-/tar-7.4.3.tgz#88bbe9286a3fcd900e94592cda7a22b192e80571" 1129 | integrity sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw== 1130 | dependencies: 1131 | "@isaacs/fs-minipass" "^4.0.0" 1132 | chownr "^3.0.0" 1133 | minipass "^7.1.2" 1134 | minizlib "^3.0.1" 1135 | mkdirp "^3.0.1" 1136 | yallist "^5.0.0" 1137 | 1138 | tslib@^2.1.0: 1139 | version "2.8.1" 1140 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" 1141 | integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== 1142 | 1143 | typescript@^5.5.4, typescript@^5.8.2: 1144 | version "5.8.2" 1145 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4" 1146 | integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== 1147 | 1148 | undici-types@~6.20.0: 1149 | version "6.20.0" 1150 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" 1151 | integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== 1152 | 1153 | unicorn-magic@^0.3.0: 1154 | version "0.3.0" 1155 | resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz#4efd45c85a69e0dd576d25532fbfa22aa5c8a104" 1156 | integrity sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA== 1157 | 1158 | web-streams-polyfill@^3.0.3: 1159 | version "3.3.3" 1160 | resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" 1161 | integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== 1162 | 1163 | which@^2.0.1: 1164 | version "2.0.2" 1165 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1166 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1167 | dependencies: 1168 | isexe "^2.0.0" 1169 | 1170 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 1171 | version "7.0.0" 1172 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1173 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1174 | dependencies: 1175 | ansi-styles "^4.0.0" 1176 | string-width "^4.1.0" 1177 | strip-ansi "^6.0.0" 1178 | 1179 | wrap-ansi@^7.0.0: 1180 | version "7.0.0" 1181 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1182 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1183 | dependencies: 1184 | ansi-styles "^4.0.0" 1185 | string-width "^4.1.0" 1186 | strip-ansi "^6.0.0" 1187 | 1188 | wrap-ansi@^8.1.0: 1189 | version "8.1.0" 1190 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 1191 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 1192 | dependencies: 1193 | ansi-styles "^6.1.0" 1194 | string-width "^5.0.1" 1195 | strip-ansi "^7.0.1" 1196 | 1197 | y18n@^5.0.5: 1198 | version "5.0.8" 1199 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1200 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1201 | 1202 | yallist@^5.0.0: 1203 | version "5.0.0" 1204 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533" 1205 | integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== 1206 | 1207 | yargs-parser@^21.1.1: 1208 | version "21.1.1" 1209 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 1210 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 1211 | 1212 | yargs@^17.7.2: 1213 | version "17.7.2" 1214 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" 1215 | integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== 1216 | dependencies: 1217 | cliui "^8.0.1" 1218 | escalade "^3.1.1" 1219 | get-caller-file "^2.0.5" 1220 | require-directory "^2.1.1" 1221 | string-width "^4.2.3" 1222 | y18n "^5.0.5" 1223 | yargs-parser "^21.1.1" 1224 | 1225 | yoctocolors@^2.0.0: 1226 | version "2.1.1" 1227 | resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.1.tgz#e0167474e9fbb9e8b3ecca738deaa61dd12e56fc" 1228 | integrity sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ== 1229 | --------------------------------------------------------------------------------