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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/actions/release/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ inputs:
required: false
description: 'Whether to create a prerelease release'
default: 'true'
node-auth-token:
required: true
description: 'The NPM token to use for authentication'

runs:
using: 'composite'
Expand All @@ -44,6 +41,4 @@ runs:

- name: Publish to NPM
shell: bash
env:
NODE_AUTH_TOKEN: ${{ inputs.node-auth-token }}
run: npm publish --access public
3 changes: 1 addition & 2 deletions .github/workflows/cli-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Set Secrets
uses: DevCycleHQ/aws-secrets-action@main
with:
secrets_map: '{"CLI_NPMJS_TOKEN": "DEVCYCLE_GITHUB_CLI_NPM_TOKEN", "MCP_KEY": "DEVCYCLE_GITHUB_cli_MCP_REGISTRY_PKEY"}'
secrets_map: '{"MCP_KEY": "DEVCYCLE_GITHUB_cli_MCP_REGISTRY_PKEY"}'
aws_account_id: '134377926370'
- name: Set Git author
run: |
Expand Down Expand Up @@ -97,7 +97,6 @@ jobs:
release-tag: ${{ env.LATEST_TAG }}
draft: ${{ inputs.draft-release }}
prerelease: ${{ inputs.prerelease }}
node-auth-token: ${{ env.CLI_NPMJS_TOKEN }}

# --- Official MCP Registry (registry.modelcontextprotocol.io) Publish ---
- name: Install MCP Publisher (registry.modelcontextprotocol.io)
Expand Down
134 changes: 67 additions & 67 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import eslintConfigPrettier from 'eslint-config-prettier';
import js from '@eslint/js'
import tseslint from 'typescript-eslint'
import eslintConfigPrettier from 'eslint-config-prettier'

export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
},
plugins: {
'@typescript-eslint': tseslint.plugin,
},
rules: {
'no-param-reassign': 'error',
'no-case-declarations': 'off',
'@typescript-eslint/no-this-alias': [
'error',
{
allowDestructuring: true,
allowedNames: ['engine'],
js.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
},
plugins: {
'@typescript-eslint': tseslint.plugin,
},
rules: {
'no-param-reassign': 'error',
'no-case-declarations': 'off',
'@typescript-eslint/no-this-alias': [
'error',
{
allowDestructuring: true,
allowedNames: ['engine'],
},
],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-unused-expressions': 'error',
},
],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-unused-expressions': 'error',
},
},
{
files: ['**/*.test.ts', '**/*.test.tsx'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
{
files: ['**/*.test.ts', '**/*.test.tsx'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
},
},
},
{
files: ['**/*.js', '**/*.mjs'],
languageOptions: {
globals: {
require: 'readonly',
process: 'readonly',
global: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
module: 'readonly',
exports: 'readonly',
Buffer: 'readonly',
},
{
files: ['**/*.js', '**/*.mjs'],
languageOptions: {
globals: {
require: 'readonly',
process: 'readonly',
global: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
module: 'readonly',
exports: 'readonly',
Buffer: 'readonly',
},
},
rules: {
'@typescript-eslint/no-require-imports': 'off',
},
},
rules: {
'@typescript-eslint/no-require-imports': 'off',
{
ignores: [
'dist/**',
'node_modules/**',
'.yarn/**',
'oclif.manifest.json',
'test-utils/fixtures/**/*.js',
'bin/**',
],
},
},
{
ignores: [
'dist/**',
'node_modules/**',
'.yarn/**',
'oclif.manifest.json',
'test-utils/fixtures/**/*.js',
'bin/**',
],
}
);
)
56 changes: 28 additions & 28 deletions mcp-worker/package.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
{
"name": "@devcycle/mcp-worker",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "wrangler dev --env dev",
"deploy:prod": "wrangler deploy --env prod",
"deploy:dev": "wrangler deploy --env dev",
"build": "tsc",
"type-check": "tsc --noEmit",
"cf-typegen": "wrangler types",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@cloudflare/workers-oauth-provider": "^0.0.10",
"ably": "^1.2.48",
"agents": "^0.1.4",
"hono": "^4.9.8",
"jose": "^6.1.0",
"oauth4webapi": "^3.8.1"
},
"devDependencies": {
"@types/node": "^24.5.2",
"vitest": "^3.2.4",
"wrangler": "^4.38.0"
},
"packageManager": "yarn@4.9.2"
"name": "@devcycle/mcp-worker",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "wrangler dev --env dev",
"deploy:prod": "wrangler deploy --env prod",
"deploy:dev": "wrangler deploy --env dev",
"build": "tsc",
"type-check": "tsc --noEmit",
"cf-typegen": "wrangler types",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@cloudflare/workers-oauth-provider": "^0.0.10",
"ably": "^1.2.48",
"agents": "^0.1.4",
"hono": "^4.9.8",
"jose": "^6.1.0",
"oauth4webapi": "^3.8.1"
},
"devDependencies": {
"@types/node": "^24.5.2",
"vitest": "^3.2.4",
"wrangler": "^4.38.0"
},
"packageManager": "yarn@4.9.2"
}
7 changes: 2 additions & 5 deletions mcp-worker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
"outDir": "./dist",
"rootDir": "../",
"noEmit": true,
"types": [
"vitest/globals",
"node"
],
"types": ["vitest/globals", "node"],
"lib": ["ES2022"],
"module": "ESNext",
"target": "ES2022",
Expand All @@ -33,4 +30,4 @@
"../src/**/__snapshots__/**",
"src/**/*.test.ts"
]
}
}
50 changes: 33 additions & 17 deletions mcp-worker/worker-configuration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,43 @@
// Generated by Wrangler by running `wrangler types` (hash: 03094dcd0f8a91995e2ac7310c959ef5)
// Runtime types generated with workerd@1.20250803.0 2025-06-28 nodejs_compat
declare namespace Cloudflare {
interface Env {
OAUTH_KV: KVNamespace;
NODE_ENV: "production" | "development";
API_BASE_URL: "https://api.devcycle.com";
AUTH0_DOMAIN: "auth.devcycle.com";
AUTH0_AUDIENCE: "https://api.devcycle.com/";
AUTH0_SCOPE: "openid profile email offline_access";
ENABLE_OUTPUT_SCHEMAS: "false";
AUTH0_CLIENT_ID: string;
AUTH0_CLIENT_SECRET: string;
ABLY_API_KEY: string;
MCP_OBJECT: DurableObjectNamespace<import("./src/index").DevCycleMCP>;
AI: Ai;
}
interface Env {
OAUTH_KV: KVNamespace
NODE_ENV: 'production' | 'development'
API_BASE_URL: 'https://api.devcycle.com'
AUTH0_DOMAIN: 'auth.devcycle.com'
AUTH0_AUDIENCE: 'https://api.devcycle.com/'
AUTH0_SCOPE: 'openid profile email offline_access'
ENABLE_OUTPUT_SCHEMAS: 'false'
AUTH0_CLIENT_ID: string
AUTH0_CLIENT_SECRET: string
ABLY_API_KEY: string
MCP_OBJECT: DurableObjectNamespace<import('./src/index').DevCycleMCP>
AI: Ai
}
}
interface Env extends Cloudflare.Env {}
type StringifyValues<EnvType extends Record<string, unknown>> = {
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
};
[Binding in keyof EnvType]: EnvType[Binding] extends string
? EnvType[Binding]
: string
}
declare namespace NodeJS {
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "NODE_ENV" | "API_BASE_URL" | "AUTH0_DOMAIN" | "AUTH0_AUDIENCE" | "AUTH0_SCOPE" | "ENABLE_OUTPUT_SCHEMAS" | "AUTH0_CLIENT_ID" | "AUTH0_CLIENT_SECRET" | "ABLY_API_KEY">> {}
interface ProcessEnv
extends StringifyValues<
Pick<
Cloudflare.Env,
| 'NODE_ENV'
| 'API_BASE_URL'
| 'AUTH0_DOMAIN'
| 'AUTH0_AUDIENCE'
| 'AUTH0_SCOPE'
| 'ENABLE_OUTPUT_SCHEMAS'
| 'AUTH0_CLIENT_ID'
| 'AUTH0_CLIENT_SECRET'
| 'ABLY_API_KEY'
>
> {}
}

// Begin runtime types
Expand Down
14 changes: 10 additions & 4 deletions scripts/fetch-install-prompts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const fs = require('fs')
const path = require('path')

// Keep a single constant for clarity and reuse
const TREE_URL = 'https://api.github.com/repos/DevCycleHQ/AI-Prompts-And-Rules/git/trees/main?recursive=1'
const TREE_URL =
'https://api.github.com/repos/DevCycleHQ/AI-Prompts-And-Rules/git/trees/main?recursive=1'

function fetchJson(url, headers = {}) {
const requestHeaders = {
Expand All @@ -26,7 +27,11 @@ function fetchJson(url, headers = {}) {
let data = ''
res.on('data', (chunk) => (data += chunk))
res.on('end', () => {
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
if (
res.statusCode &&
res.statusCode >= 200 &&
res.statusCode < 300
) {
try {
resolve(JSON.parse(data))
} catch (err) {
Expand Down Expand Up @@ -80,7 +85,9 @@ async function main() {
// Build safe slugs (relative paths within install-prompts without extension)
const slugSet = new Set()
for (const p of mdFiles) {
const raw = p.replace(/^install-prompts\//, '').replace(/\.md$/i, '')
const raw = p
.replace(/^install-prompts\//, '')
.replace(/\.md$/i, '')
// extra guards on the slug
if (!raw || raw.includes('..') || raw.startsWith('/')) continue
const cleaned = raw
Expand Down Expand Up @@ -133,4 +140,3 @@ main().catch((err) => {
console.error(err)
process.exit(1)
})