Skip to content

Commit c1197bf

Browse files
authored
feat: configure ci/cd workflows and resolve eslint warnings (#15)
1 parent a45cb84 commit c1197bf

29 files changed

Lines changed: 264 additions & 89 deletions

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
verify:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: 20
23+
cache: 'npm'
24+
25+
- name: Install dependencies
26+
run: npm ci
27+
28+
- name: Run lint
29+
run: npm run lint
30+
31+
- name: Run tests
32+
run: npm run test:ci
33+
34+
- name: Build package
35+
run: npm run build

.github/workflows/publish.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Publish to NPM
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: 20
22+
registry-url: 'https://registry.npmjs.org/'
23+
cache: 'npm'
24+
25+
- name: Install dependencies
26+
run: npm ci
27+
28+
- name: Run lint
29+
run: npm run lint
30+
31+
- name: Run tests
32+
run: npm run test:ci
33+
34+
- name: Build package
35+
run: npm run build
36+
37+
- name: Publish to NPM
38+
run: npm publish --access public
39+
env:
40+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
41+
42+
- name: Create GitHub Release
43+
uses: softprops/action-gh-release@v2
44+
with:
45+
generate_release_notes: true
46+
env:
47+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ build/
2626

2727
__tests__
2828

29-
*.tgz
29+
*.tgz
30+
31+
# Test coverage
32+
coverage/

CONTRIBUTING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ Discussions: GitHub Discussions
8282

8383
Pull Requests: Always create a PR to the main branch
8484

85+
## 🚀 CI/CD & Releases
86+
87+
We use GitHub Actions to automate testing and package publishing.
88+
89+
1. **Pull Requests**: Every PR targeting the `main` branch triggers the **CI** workflow which runs `npm run lint`, `npm run test:ci`, and `npm run build`. The PR cannot be merged if any check fails.
90+
2. **Releasing a New Version**:
91+
- Bump the version locally: `npm version patch` (or `minor` / `major`). This will update `package.json` and create a Git tag.
92+
- Push the code and the tag: `git push origin main --tags`.
93+
- The push of a tag matching `v*` triggers the **Publish to NPM** workflow, which automatically runs all tests, builds the ESM and CommonJS bundles, publishes the package to the public NPM registry, and creates a GitHub Release with autogenerated release notes.
94+
8595
🙏 Credits
8696

8797
Maintained with ❤️ by iTeebot

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ We actively support the latest major release and security patches for the previo
1616
If you discover a security vulnerability, **DO NOT** open a public GitHub issue.
1717

1818
Instead, please report it privately by emailing:
19-
**security@realteebot.dev**
19+
**security-npm-ai-hooks@iteebot.com**
2020

2121
We take all security issues seriously and will respond within 48 hours.
2222

eslint.config.mjs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import eslint from "@eslint/js";
2+
import tseslint from "typescript-eslint";
3+
4+
export default tseslint.config(
5+
eslint.configs.recommended,
6+
...tseslint.configs.recommended,
7+
{
8+
ignores: ["dist/**", "node_modules/**", "coverage/**", "jest.config.js", "tsconfig*.json"]
9+
},
10+
{
11+
files: ["**/*.ts"],
12+
rules: {
13+
"@typescript-eslint/no-explicit-any": "warn",
14+
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }]
15+
}
16+
}
17+
);

examples/demo.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async function testAllProviders() {
1818
console.log('🚀 Testing All AI Providers\n');
1919

2020
// Initialize with all available providers
21-
const providers: Array<{ provider: string; key: string; defaultModel: string }> = [];
21+
const providers: Array<{ provider: 'openai' | 'claude' | 'gemini' | 'groq' | 'openrouter' | 'deepseek' | 'xai' | 'perplexity' | 'mistral'; key: string; defaultModel: string }> = [];
2222

2323
// Check for API keys in various environment variable formats
2424
if (process.env.OPENAI_KEY || process.env.OPENAI_API_KEY || process.env.OPENAI_KEY) {
@@ -111,10 +111,9 @@ async function testAllProviders() {
111111
providers.forEach(p => console.log(` - ${p.provider}`));
112112
console.log('');
113113

114-
// Initialize with all providers
115114
initAIHooks({
116-
providers: providers as any, // Type assertion for compatibility
117-
defaultProvider: 'groq' as any // Prefer Groq if available
115+
providers, // Type assertion for compatibility
116+
defaultProvider: 'groq' // Prefer Groq if available
118117
});
119118

120119
console.log('Available providers:', getAvailableProviders());
@@ -154,7 +153,7 @@ async function testAllProviders() {
154153
try {
155154
const summarize = wrap((text: string) => text, {
156155
task: "summarize",
157-
provider: providerName as any
156+
provider: providerName
158157
});
159158

160159
const result = await summarize(testText);
@@ -181,10 +180,9 @@ async function testAllProviders() {
181180
const { provider: selectedProvider } = getProvider();
182181
console.log(`Selected default provider: ${selectedProvider}`);
183182

184-
// Test specific provider selection
185183
if (providers.length > 1) {
186184
const secondProvider = providers[1].provider;
187-
const { provider: specificProvider } = getProvider(secondProvider as any);
185+
const { provider: specificProvider } = getProvider(secondProvider);
188186
console.log(`Selected specific provider (${secondProvider}): ${specificProvider}`);
189187
}
190188

examples/express/src/routes/summarize.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { wrap } from "npm-ai-hooks";
66
// dotenv.config();
77

88
// Initialize providers with environment variables
9-
const providers: Array<{ provider: string; key: string; defaultModel?: string }> = [];
9+
const providers: Array<{ provider: 'openai' | 'groq' | 'claude' | 'gemini' | 'openrouter'; key: string; defaultModel?: string }> = [];
1010

1111
if (process.env.OPENAI_KEY) {
1212
providers.push({
@@ -50,8 +50,8 @@ if (process.env.OPENROUTER_KEY) {
5050
// Initialize with available providers
5151
if (providers.length > 0) {
5252
initAIHooks({
53-
providers: providers as any,
54-
defaultProvider: 'gemini' as any
53+
providers,
54+
defaultProvider: 'gemini'
5555
});
5656
console.log(`✅ Initialized ${providers.length} AI providers for Express server`);
5757
} else {
@@ -77,11 +77,12 @@ router.get("/", async (req: Request, res: Response) => {
7777
summary: result.output,
7878
meta: result.meta
7979
});
80-
} catch (error: any) {
81-
console.error("Summarize Error:", error);
80+
} catch (error: unknown) {
81+
const err = error as Error & { provider?: string };
82+
console.error("Summarize Error:", err);
8283
return res.status(500).json({
83-
error: error.message || "Internal Server Error",
84-
provider: error.provider || null
84+
error: err.message || "Internal Server Error",
85+
provider: err.provider || null
8586
});
8687
}
8788
});

examples/model-switch/wrong-models.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { wrap } from "../../src/wrap";
33
async function run() {
44
// Wrong OpenRouter model
55
try {
6-
const wrongOpenRouter = wrap((text: string) => text, { task: "summarize", provider: "openrouter", model: "invalid-model" as any });
6+
const wrongOpenRouter = wrap((text: string) => text, { task: "summarize", provider: "openrouter", model: "invalid-model" as never });
77
await wrongOpenRouter("Test text");
88
} catch (err: unknown) {
99
console.error("❌ OpenRouter error:", err);
1010
}
1111

1212
// Wrong Groq model
1313
try {
14-
const wrongGroq = wrap((text: string) => text, { task: "explain", provider: "groq", model: "invalid-groq-model" as any });
14+
const wrongGroq = wrap((text: string) => text, { task: "explain", provider: "groq", model: "invalid-groq-model" as never });
1515
await wrongGroq("Test text");
1616
} catch (err: unknown) {
1717
console.error("❌ Groq error:", err);

examples/multimodal/vision-example.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export {
161161
extractTextFromImage,
162162
reviewCodeScreenshot,
163163
analyzeDocument,
164-
compareImages
164+
compareImages,
165+
main
165166
};
166167

0 commit comments

Comments
 (0)