matimo-examples 0.1.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.env.example +49 -0
  2. package/LICENSE +21 -0
  3. package/README.md +525 -0
  4. package/agents/decorator-pattern-agent.ts +368 -0
  5. package/agents/factory-pattern-agent.ts +253 -0
  6. package/agents/langchain-agent.ts +146 -0
  7. package/edit/edit-decorator.ts +178 -0
  8. package/edit/edit-factory.ts +138 -0
  9. package/edit/edit-langchain.ts +292 -0
  10. package/execute/execute-decorator.ts +49 -0
  11. package/execute/execute-factory.ts +46 -0
  12. package/execute/execute-langchain.ts +232 -0
  13. package/github/github-decorator.ts +326 -0
  14. package/github/github-factory.ts +355 -0
  15. package/github/github-langchain.ts +206 -0
  16. package/github/github-with-approval.ts +228 -0
  17. package/gmail/README.md +345 -0
  18. package/gmail/gmail-decorator.ts +216 -0
  19. package/gmail/gmail-factory.ts +231 -0
  20. package/gmail/gmail-langchain.ts +201 -0
  21. package/hubspot/README.md +316 -0
  22. package/hubspot/hubspot-decorator.ts +180 -0
  23. package/hubspot/hubspot-factory.ts +188 -0
  24. package/hubspot/hubspot-langchain.ts +222 -0
  25. package/logger-example.ts +40 -0
  26. package/mailchimp/README.md +321 -0
  27. package/mailchimp/mailchimp-decorator.ts +277 -0
  28. package/mailchimp/mailchimp-factory.ts +187 -0
  29. package/mailchimp/mailchimp-langchain.ts +155 -0
  30. package/notion/README.md +293 -0
  31. package/notion/notion-decorator.ts +275 -0
  32. package/notion/notion-factory.ts +256 -0
  33. package/notion/notion-langchain.ts +237 -0
  34. package/package.json +79 -0
  35. package/postgres/README.md +188 -0
  36. package/postgres/postgres-decorator.ts +198 -0
  37. package/postgres/postgres-factory.ts +180 -0
  38. package/postgres/postgres-langchain.ts +213 -0
  39. package/postgres/postgres-with-approval.ts +344 -0
  40. package/read/read-decorator.ts +154 -0
  41. package/read/read-factory.ts +121 -0
  42. package/read/read-langchain.ts +273 -0
  43. package/search/search-decorator.ts +206 -0
  44. package/search/search-factory.ts +146 -0
  45. package/search/search-langchain.ts +255 -0
  46. package/slack/README.md +339 -0
  47. package/slack/slack-decorator.ts +245 -0
  48. package/slack/slack-factory.ts +226 -0
  49. package/slack/slack-langchain.ts +242 -0
  50. package/tsconfig.json +20 -0
  51. package/twilio/README.md +309 -0
  52. package/twilio/twilio-decorator.ts +288 -0
  53. package/twilio/twilio-factory.ts +238 -0
  54. package/twilio/twilio-langchain.ts +218 -0
  55. package/web/web-decorator.ts +52 -0
  56. package/web/web-factory.ts +70 -0
  57. package/web/web-langchain.ts +163 -0
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ============================================================================
4
+ * GITHUB TOOLS - DECORATOR PATTERN EXAMPLE
5
+ * ============================================================================
6
+ *
7
+ * PATTERN: Decorator Pattern with @tool
8
+ * ─────────────────────────────────────────────────────────────────────────
9
+ * Uses TypeScript @tool decorators to wrap GitHub tool calls in a class.
10
+ *
11
+ * Use this pattern when:
12
+ * ✅ Building class-based applications
13
+ * ✅ Encapsulating tool logic in services
14
+ * ✅ Adding custom methods that combine multiple tools
15
+ * ✅ Need reusable tool wrappers
16
+ * ✅ Object-oriented design preferred
17
+ *
18
+ * SETUP:
19
+ * ─────────────────────────────────────────────────────────────────────────
20
+ * 1. Create .env file:
21
+ * GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
22
+ *
23
+ * 2. Get a GitHub Personal Access Token:
24
+ * https://github.com/settings/tokens
25
+ *
26
+ * USAGE:
27
+ * ─────────────────────────────────────────────────────────────────────────
28
+ * export GITHUB_TOKEN=your_token_here
29
+ * npm run github:decorator
30
+ *
31
+ * ============================================================================
32
+ */
33
+
34
+ import 'dotenv/config';
35
+ import path from 'path';
36
+ import { fileURLToPath } from 'url';
37
+ import { MatimoInstance, tool, setGlobalMatimoInstance } from 'matimo';
38
+
39
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
40
+
41
+ /**
42
+ * Decorator Pattern Agent - Uses @tool decorators for GitHub operations
43
+ */
44
+ class GitHubDecoratorPatternAgent {
45
+ public matimo: MatimoInstance;
46
+
47
+ constructor(matimo: MatimoInstance) {
48
+ this.matimo = matimo;
49
+ }
50
+
51
+ /**
52
+ * GitHub search repositories tool - manually execute with required parameters
53
+ */
54
+ async searchRepositories(query: string): Promise<unknown> {
55
+ const result = await this.matimo.execute('github-search-repositories', {
56
+ query,
57
+ });
58
+ return result;
59
+ }
60
+
61
+ /**
62
+ * GitHub list-repositories tool - automatically executes via @tool decorator
63
+ */
64
+ @tool('github-list-repositories')
65
+ async listRepositories(owner: string): Promise<unknown> {
66
+ // Decorator automatically calls: matimo.execute('github-list-repositories', { owner })
67
+ return undefined;
68
+ }
69
+
70
+ /**
71
+ * GitHub get-repository tool - automatically executes via @tool decorator
72
+ */
73
+ @tool('github-get-repository')
74
+ async getRepository(owner: string, repo: string): Promise<unknown> {
75
+ // Decorator automatically calls: matimo.execute('github-get-repository', { owner, repo })
76
+ return undefined;
77
+ }
78
+
79
+ /**
80
+ * GitHub list-pull-requests tool - automatically executes via @tool decorator
81
+ */
82
+ @tool('github-list-pull-requests')
83
+ async listPullRequests(owner: string, repo: string, state?: string): Promise<unknown> {
84
+ // Decorator automatically calls: matimo.execute('github-list-pull-requests', { owner, repo, state })
85
+ return undefined;
86
+ }
87
+
88
+ /**
89
+ * GitHub list-issues tool - automatically executes via @tool decorator
90
+ */
91
+ @tool('github-list-issues')
92
+ async listIssues(owner: string, repo: string, state?: string): Promise<unknown> {
93
+ // Decorator automatically calls: matimo.execute('github-list-issues', { owner, repo, state })
94
+ return undefined;
95
+ }
96
+
97
+ /**
98
+ * GitHub list-commits tool - automatically executes via @tool decorator
99
+ */
100
+ @tool('github-list-commits')
101
+ async listCommits(owner: string, repo: string): Promise<unknown> {
102
+ // Decorator automatically calls: matimo.execute('github-list-commits', { owner, repo })
103
+ return undefined;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Run decorator pattern examples
109
+ */
110
+ async function runDecoratorPatternExamples() {
111
+ const gitHubToken = process.env.GITHUB_TOKEN || 'ghp-default-fake-token';
112
+
113
+ console.info('╔════════════════════════════════════════════════════════╗');
114
+ console.info('║ GitHub Tools - Decorator Pattern ║');
115
+ console.info('║ (Uses @tool decorators for automatic execution) ║');
116
+ console.info('╚════════════════════════════════════════════════════════╝\n');
117
+
118
+ if (gitHubToken === 'ghp-default-fake-token') {
119
+ console.info('🔐 Warning: GITHUB_TOKEN not set in environment');
120
+ console.info(' Set it: export GITHUB_TOKEN="ghp_xxxx"');
121
+ console.info(' Get one from: https://github.com/settings/tokens\n');
122
+ }
123
+
124
+ console.info(`🤖 GitHub Token: ${gitHubToken.substring(0, 10)}...\n`);
125
+
126
+ try {
127
+ // Initialize Matimo with auto-discovery
128
+ console.info('🚀 Initializing Matimo...');
129
+ const matimo = await MatimoInstance.init({ autoDiscover: true });
130
+ setGlobalMatimoInstance(matimo);
131
+
132
+ const matimoTools = matimo.listTools();
133
+ const githubTools = matimoTools.filter((t) => t.name.startsWith('github'));
134
+ console.info(
135
+ `📦 Loaded ${matimoTools.length} total tools, ${githubTools.length} GitHub tools\n`
136
+ );
137
+
138
+ // Create agent
139
+ const agent = new GitHubDecoratorPatternAgent(matimo);
140
+
141
+ console.info('🧪 Testing GitHub Tools with Decorator Pattern');
142
+ console.info('═'.repeat(60) + '\n');
143
+
144
+ // Example 1: Search repositories
145
+ console.info('🔍 Example 1: Search Repositories');
146
+ console.info('─'.repeat(60));
147
+ try {
148
+ const searchResult = await agent.searchRepositories('language:rust stars:>1000');
149
+
150
+ const searchData = (searchResult as any).data || searchResult;
151
+
152
+ if (
153
+ searchData.total_count !== undefined &&
154
+ searchData.items &&
155
+ Array.isArray(searchData.items)
156
+ ) {
157
+ const totalPages = Math.ceil(searchData.total_count / searchData.items.length);
158
+ console.info(
159
+ `✅ Found ${searchData.total_count} Rust repositories (showing first ${Math.min(3, searchData.items.length)})`
160
+ );
161
+ searchData.items.slice(0, 3).forEach((repo: any, idx: number) => {
162
+ console.info(` ${idx + 1}. ${repo.full_name} (⭐ ${repo.stargazers_count})`);
163
+ });
164
+ if (searchData.items.length > 3) {
165
+ console.info(` ... and ${searchData.items.length - 3} more on this page`);
166
+ }
167
+ console.info(` 📄 Page 1 of ~${totalPages} pages`);
168
+ } else {
169
+ console.info(`❌ Failed: ${searchData.message || 'Unknown error'}`);
170
+ }
171
+ } catch (error) {
172
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
173
+ }
174
+
175
+ // Example 2: List organization repositories
176
+ console.info('\n📋 Example 2: List Organization Repositories');
177
+ console.info('─'.repeat(60));
178
+ try {
179
+ const listResult = await agent.listRepositories('rust-lang');
180
+
181
+ const listData = (listResult as any).data || listResult;
182
+
183
+ if (Array.isArray(listData)) {
184
+ console.info(`✅ Found ${listData.length} repositories in rust-lang:`);
185
+ listData.slice(0, 3).forEach((repo: any, idx: number) => {
186
+ console.info(` ${idx + 1}. ${repo.name}`);
187
+ });
188
+ if (listData.length > 3) {
189
+ console.info(` ... and ${listData.length - 3} more`);
190
+ }
191
+
192
+ // Use first repository for next examples
193
+ const firstRepo = listData[0];
194
+ console.info(`\n🎯 Using first repo: ${firstRepo.name}\n`);
195
+
196
+ // Example 3: Get repository details
197
+ console.info('🔎 Example 3: Get Repository Details');
198
+ console.info('─'.repeat(60));
199
+ try {
200
+ const repoResult = await agent.getRepository('rust-lang', firstRepo.name);
201
+
202
+ const repoData = (repoResult as any).data || repoResult;
203
+ if (repoData.id !== undefined) {
204
+ console.info(`✅ rust-lang/${firstRepo.name}`);
205
+ console.info(` Stars: ⭐ ${repoData.stargazers_count}`);
206
+ console.info(` Forks: 🍴 ${repoData.forks_count}`);
207
+ console.info(` Language: ${repoData.language || 'N/A'}`);
208
+ console.info(` Open Issues: ${repoData.open_issues_count}`);
209
+ } else {
210
+ console.info(`❌ Failed: ${repoData.message || 'Unknown error'}`);
211
+ }
212
+ } catch (error) {
213
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
214
+ }
215
+
216
+ // Example 4: List pull requests (manually execute to use per_page parameter)
217
+ console.info('\n🔀 Example 4: List Pull Requests');
218
+ console.info('─'.repeat(60));
219
+ console.info('📌 Checking: cli/cli (has active PRs)\n');
220
+ try {
221
+ const prsResult = await agent.matimo.execute('github-list-pull-requests', {
222
+ owner: 'cli',
223
+ repo: 'cli',
224
+ state: 'open',
225
+ per_page: 5,
226
+ });
227
+
228
+ const prsData = (prsResult as any).data || prsResult;
229
+ const prList = Array.isArray(prsData) ? prsData : prsData?.pull_requests || [];
230
+
231
+ if (prList.length > 0) {
232
+ console.info(`✅ Found ${prList.length} open pull requests from cli/cli`);
233
+ prList.slice(0, 3).forEach((pr: any, idx: number) => {
234
+ console.info(` ${idx + 1}. #${pr.number}: ${pr.title}`);
235
+ console.info(` Created: ${new Date(pr.created_at).toLocaleDateString()}`);
236
+ });
237
+ if (prList.length > 3) {
238
+ console.info(` ... and ${prList.length - 3} more`);
239
+ }
240
+ } else {
241
+ console.info(`⚠️ No open pull requests found`);
242
+ }
243
+ } catch (error) {
244
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
245
+ }
246
+
247
+ // Example 5: List commits (manually execute to use per_page parameter)
248
+ console.info('\n📝 Example 5: List Commits');
249
+ console.info('─'.repeat(60));
250
+ console.info('📌 Checking: golang/go (has active commits)\n');
251
+ try {
252
+ const commitsResult = await agent.matimo.execute('github-list-commits', {
253
+ owner: 'golang',
254
+ repo: 'go',
255
+ per_page: 5,
256
+ });
257
+
258
+ const commitsData = (commitsResult as any).data || commitsResult;
259
+ const commitList = Array.isArray(commitsData) ? commitsData : commitsData?.commits || [];
260
+
261
+ if (commitList.length > 0) {
262
+ console.info(`✅ Found ${commitList.length} recent commits from golang/go`);
263
+ commitList.slice(0, 3).forEach((commit: any, idx: number) => {
264
+ const msg = commit.commit.message.split('\n')[0];
265
+ console.info(` ${idx + 1}. ${commit.commit.author?.name || 'Unknown'}`);
266
+ console.info(` ${msg}`);
267
+ console.info(` SHA: ${commit.sha.substring(0, 7)}`);
268
+ });
269
+ if (commitList.length > 3) {
270
+ console.info(` ... and ${commitList.length - 3} more`);
271
+ }
272
+ } else {
273
+ console.info(`⚠️ No commits found`);
274
+ }
275
+ } catch (error) {
276
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
277
+ }
278
+
279
+ // Example 6: List releases (manually execute to use per_page parameter)
280
+ console.info('\n🎉 Example 6: List Releases');
281
+ console.info('─'.repeat(60));
282
+ try {
283
+ const releasesResult = await agent.matimo.execute('github-list-releases', {
284
+ owner: 'nodejs',
285
+ repo: 'node',
286
+ per_page: 5,
287
+ });
288
+
289
+ const releasesData = (releasesResult as any).data || releasesResult;
290
+ const releaseList = Array.isArray(releasesData) ? releasesData : [];
291
+
292
+ if (releaseList.length > 0) {
293
+ console.info(`✅ Found ${releaseList.length} releases from nodejs/node`);
294
+ releaseList.slice(0, 3).forEach((release: any, idx: number) => {
295
+ console.info(` ${idx + 1}. ${release.tag_name} - ${release.name || 'Unnamed'}`);
296
+ });
297
+ if (releaseList.length > 3) {
298
+ console.info(` ... and ${releaseList.length - 3} more`);
299
+ }
300
+ } else {
301
+ console.info(`⚠️ No releases found`);
302
+ }
303
+ } catch (error) {
304
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
305
+ }
306
+ } else {
307
+ console.info(`❌ Failed to list repositories: ${listData.message || 'Unknown error'}`);
308
+ }
309
+ } catch (error) {
310
+ console.info(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
311
+ }
312
+
313
+ console.info('\n' + '═'.repeat(60));
314
+ console.info('✨ Decorator Pattern Example Complete!');
315
+ console.info('═'.repeat(60) + '\n');
316
+ } catch (error) {
317
+ console.error('❌ Fatal error:', error instanceof Error ? error.message : String(error));
318
+ process.exit(1);
319
+ }
320
+ }
321
+
322
+ // Run the example
323
+ runDecoratorPatternExamples().catch((error) => {
324
+ console.error('❌ Unhandled error:', error);
325
+ process.exit(1);
326
+ });
@@ -0,0 +1,355 @@
1
+ #!/usr/bin/env node
2
+
3
+ import 'dotenv/config';
4
+ import { MatimoInstance } from '@matimo/core';
5
+
6
+ /**
7
+ * GitHub Factory Pattern Example
8
+ * ================================
9
+ *
10
+ * Demonstrates the simplest way to use Matimo tools: direct execution via matimo.execute().
11
+ * This pattern is best for:
12
+ * - Simple scripts and CLIs
13
+ * - Direct tool invocation
14
+ * - Learning Matimo basics
15
+ *
16
+ * Setup:
17
+ * ------
18
+ * 1. Get a GitHub Personal Access Token (PAT):
19
+ * Visit: https://github.com/settings/tokens
20
+ * Create token with: repo, read:org scopes (for public repo access)
21
+ *
22
+ * 2. Set environment variable:
23
+ * export GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx"
24
+ *
25
+ * 3. Run this example:
26
+ * pnpm github:factory
27
+ *
28
+ * Available GitHub Tools:
29
+ * -----------------------
30
+ * SEARCH:
31
+ * - github-search-repositories: Find repositories by query (language, stars, etc.)
32
+ * - github-search-code: Search code across repositories
33
+ * - github-search-issues: Find issues and pull requests
34
+ * - github-search-users: Find GitHub users
35
+ *
36
+ * REPOSITORIES:
37
+ * - github-list-repositories: List repos in an org/user
38
+ * - github-get-repository: Get detailed repo info
39
+ * - github-create-repository: Create new repo (write access required)
40
+ * - github-delete-repository: Delete a repo (write access required)
41
+ *
42
+ * ISSUES:
43
+ * - github-list-issues: List issues in a repo
44
+ * - github-create-issue: Create issue (write access required)
45
+ * - github-get-issue: Get issue details
46
+ * - github-update-issue: Update issue (write access required)
47
+ *
48
+ * PULL REQUESTS:
49
+ * - github-list-pull-requests: List PRs in a repo
50
+ * - github-create-pull-request: Create PR (write access required)
51
+ * - github-merge-pull-request: Merge PR (write access required)
52
+ *
53
+ * COMMITS:
54
+ * - github-list-commits: List commits in repo
55
+ *
56
+ * COLLABORATORS:
57
+ * - github-list-collaborators: List repo collaborators
58
+ * - github-add-collaborator: Add collaborator (admin access required)
59
+ *
60
+ * RELEASES:
61
+ * - github-list-releases: List releases
62
+ * - github-create-release: Create release (write access required)
63
+ *
64
+ * CODE SCANNING:
65
+ * - github-list-code-alerts: List security alerts (Advanced Security)
66
+ * - github-update-code-alert: Update alert status (Advanced Security)
67
+ */
68
+
69
+ // Type definitions for API responses
70
+ interface SearchRepositoryResult {
71
+ total_count: number;
72
+ items: Array<{
73
+ id: number;
74
+ name: string;
75
+ full_name: string;
76
+ description: string;
77
+ url: string;
78
+ stargazers_count: number;
79
+ forks_count: number;
80
+ language: string | null;
81
+ updated_at: string;
82
+ }>;
83
+ }
84
+
85
+ interface Repository {
86
+ id: number;
87
+ name: string;
88
+ full_name: string;
89
+ description: string | null;
90
+ url: string;
91
+ stargazers_count: number;
92
+ forks_count: number;
93
+ language: string | null;
94
+ open_issues_count: number;
95
+ topics: string[];
96
+ }
97
+
98
+ interface PullRequest {
99
+ id: number;
100
+ number: number;
101
+ title: string;
102
+ body: string | null;
103
+ state: string;
104
+ created_at: string;
105
+ updated_at: string;
106
+ }
107
+
108
+ interface Commit {
109
+ sha: string;
110
+ commit: {
111
+ author: {
112
+ name: string;
113
+ email: string;
114
+ date: string;
115
+ };
116
+ message: string;
117
+ };
118
+ }
119
+
120
+ interface Release {
121
+ id: number;
122
+ tag_name: string;
123
+ name: string | null;
124
+ body: string | null;
125
+ draft: boolean;
126
+ prerelease: boolean;
127
+ created_at: string;
128
+ published_at: string | null;
129
+ }
130
+
131
+ async function main() {
132
+ console.info('\n╔════════════════════════════════════════════════════════════╗');
133
+ console.info('║ 🐙 GitHub Factory Pattern Example ║');
134
+ console.info('║ Direct tool execution using matimo.execute() ║');
135
+ console.info('╚════════════════════════════════════════════════════════════╝\n');
136
+
137
+ // Check for GitHub token
138
+ const token = process.env.GITHUB_TOKEN;
139
+ if (!token) {
140
+ console.error('\n❌ Error: GITHUB_TOKEN environment variable not set');
141
+ console.info('\n📖 Setup Instructions:');
142
+ console.info(' 1. Create a GitHub Personal Access Token:');
143
+ console.info(' https://github.com/settings/tokens');
144
+ console.info(' 2. Set the environment variable:');
145
+ console.info(' export GITHUB_TOKEN="ghp_xxxx..."');
146
+ console.info(' 3. Run this example again:');
147
+ console.info(' pnpm github:factory\n');
148
+ process.exit(1);
149
+ }
150
+
151
+ try {
152
+ // Initialize Matimo with auto-discovery
153
+ const matimo = await MatimoInstance.init({
154
+ autoDiscover: true,
155
+ });
156
+
157
+ // Get all GitHub tools (filter by prefix)
158
+ const allTools = matimo.listTools();
159
+ const githubTools = allTools.filter((t) => t.name.startsWith('github-'));
160
+ console.info(`📚 Loaded ${githubTools.length} GitHub tools from Matimo\n`);
161
+
162
+ // Example 1: Search repositories
163
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
164
+ console.info('Example 1: Search TypeScript Repositories');
165
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
166
+ console.info('📦 Searching: language:typescript fork:false stars:>100\n');
167
+ try {
168
+ const searchResults = await matimo.execute('github-search-repositories', {
169
+ query: 'language:typescript fork:false stars:>100',
170
+ });
171
+ const searchData = (searchResults as any).data || searchResults;
172
+ console.info(`✅ Found ${searchData?.total_count} TypeScript repositories\n`);
173
+ if (searchData?.items && searchData.items.length > 0) {
174
+ console.info('Top 3 Results:');
175
+ searchData.items.slice(0, 3).forEach((repo: any, idx: number) => {
176
+ console.info(` ${idx + 1}. ${repo.full_name} ⭐ ${repo.stargazers_count}`);
177
+ console.info(` ${repo.description || 'No description'}\n`);
178
+ });
179
+ }
180
+ } catch (error: any) {
181
+ console.error(`❌ Search failed: ${error.message}`);
182
+ }
183
+
184
+ // Example 2: Get repository details
185
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
186
+ console.info('Example 2: Get Repository Details');
187
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
188
+ console.info('🔎 Getting details for: kubernetes/kubernetes\n');
189
+ try {
190
+ const repo = await matimo.execute('github-get-repository', {
191
+ owner: 'kubernetes',
192
+ repo: 'kubernetes',
193
+ });
194
+ const repoData = (repo as any).data || repo;
195
+ if (repoData && repoData.full_name) {
196
+ console.info(`✅ Repository: ${repoData.full_name}`);
197
+ console.info(` Description: ${repoData.description}`);
198
+ console.info(` Stars: ⭐ ${repoData.stargazers_count?.toLocaleString()}`);
199
+ console.info(` Language: ${repoData.language || 'Mixed'}`);
200
+ console.info(` Open Issues: ${repoData.open_issues_count}`);
201
+ if (repoData.topics?.length > 0) {
202
+ console.info(` Topics: ${repoData.topics.join(', ')}`);
203
+ }
204
+ console.info();
205
+ } else {
206
+ console.error(
207
+ `❌ Get repository returned unexpected format: ${JSON.stringify(repoData).slice(0, 100)}`
208
+ );
209
+ }
210
+ } catch (error: any) {
211
+ console.error(`❌ Get repository failed: ${error.message}`);
212
+ }
213
+
214
+ // Example 3: List repositories
215
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
216
+ console.info('Example 3: List Organization Repositories');
217
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
218
+ console.info('📋 Listing top 5 Node.js repositories\n');
219
+ try {
220
+ const repos = await matimo.execute('github-list-repositories', {
221
+ owner: 'nodejs',
222
+ type: 'public',
223
+ per_page: 5,
224
+ });
225
+ const reposData = (repos as any).data || repos;
226
+ const repoList = Array.isArray(reposData) ? reposData : reposData?.repositories || [];
227
+ if (repoList.length > 0) {
228
+ console.info(`✅ Found ${repoList.length} repositories from nodejs org:\n`);
229
+ repoList.forEach((repo: any, idx: number) => {
230
+ console.info(` ${idx + 1}. ${repo.name} ⭐ ${repo.stargazers_count}`);
231
+ console.info(` Full Name: ${repo.full_name}`);
232
+ console.info(` Language: ${repo.language || 'Mixed'}`);
233
+ console.info();
234
+ });
235
+ } else {
236
+ console.info(`⚠️ No repositories found or unexpected response format`);
237
+ }
238
+ } catch (error: any) {
239
+ console.error(`❌ List repositories failed: ${error.message}`);
240
+ }
241
+
242
+ // Example 4: List pull requests
243
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
244
+ console.info('Example 4: List Open Pull Requests');
245
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
246
+ console.info('🔀 Listing PRs from: cli/cli\n');
247
+ try {
248
+ const prs = await matimo.execute('github-list-pull-requests', {
249
+ owner: 'cli',
250
+ repo: 'cli',
251
+ state: 'open',
252
+ per_page: 5,
253
+ });
254
+ const prsData = (prs as any).data || prs;
255
+ const prList = Array.isArray(prsData) ? prsData : prsData?.pull_requests || [];
256
+ if (prList.length > 0) {
257
+ console.info(`✅ Found ${prList.length} open pull requests:\n`);
258
+ prList.forEach((pr: any, idx: number) => {
259
+ console.info(` ${idx + 1}. #${pr.number}: ${pr.title}`);
260
+ console.info(
261
+ ` Status: ${pr.state} | Created: ${new Date(pr.created_at).toLocaleDateString()}`
262
+ );
263
+ console.info();
264
+ });
265
+ } else {
266
+ console.info(`⚠️ No open pull requests found or unexpected response format`);
267
+ }
268
+ } catch (error: any) {
269
+ console.error(`❌ List pull requests failed: ${error.message}`);
270
+ }
271
+
272
+ // Example 5: List commits
273
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
274
+ console.info('Example 5: List Recent Commits');
275
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
276
+ console.info('📝 Listing commits from: golang/go\n');
277
+ try {
278
+ const commits = await matimo.execute('github-list-commits', {
279
+ owner: 'golang',
280
+ repo: 'go',
281
+ per_page: 5,
282
+ });
283
+ const commitsData = (commits as any).data || commits;
284
+ const commitList = Array.isArray(commitsData) ? commitsData : commitsData?.commits || [];
285
+ if (commitList.length > 0) {
286
+ console.info(`✅ Found ${commitList.length} recent commits:\n`);
287
+ commitList.slice(0, 3).forEach((commit: any, idx: number) => {
288
+ const msg = commit.commit.message.split('\n')[0];
289
+ console.info(` ${idx + 1}. ${commit.commit.author.name}`);
290
+ console.info(` ${msg}`);
291
+ console.info(` SHA: ${commit.sha.substring(0, 7)}`);
292
+ console.info();
293
+ });
294
+ } else {
295
+ console.info(`⚠️ No commits found or unexpected response format`);
296
+ }
297
+ } catch (error: any) {
298
+ console.error(`❌ List commits failed: ${error.message}`);
299
+ }
300
+
301
+ // Example 6: List releases
302
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
303
+ console.info('Example 6: List Releases');
304
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
305
+ console.info('🎉 Listing releases from: nodejs/node\n');
306
+ try {
307
+ const releases = await matimo.execute('github-list-releases', {
308
+ owner: 'nodejs',
309
+ repo: 'node',
310
+ per_page: 5,
311
+ });
312
+ const releasesData = (releases as any).data || releases;
313
+ const releaseList = Array.isArray(releasesData) ? releasesData : releasesData?.releases || [];
314
+ if (releaseList.length > 0) {
315
+ console.info(`✅ Found ${releaseList.length} releases:\n`);
316
+ releaseList.slice(0, 3).forEach((release: any, idx: number) => {
317
+ console.info(` ${idx + 1}. ${release.tag_name} "${release.name}"`);
318
+ console.info(` Published: ${new Date(release.published_at!).toLocaleDateString()}`);
319
+ console.info();
320
+ });
321
+ } else {
322
+ console.info(`⚠️ No releases found or unexpected response format`);
323
+ }
324
+ } catch (error: any) {
325
+ console.error(`❌ List releases failed: ${error.message}`);
326
+ }
327
+
328
+ // Example 7: Search code
329
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
330
+ console.info('Example 7: Search Code');
331
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
332
+ console.info('🔍 Searching for: "async function" in React\n');
333
+ try {
334
+ const codeResults = await matimo.execute('github-search-code', {
335
+ query: 'language:typescript "async function" repo:facebook/react',
336
+ });
337
+ const codeData = (codeResults as any).data || codeResults;
338
+ console.info(`✅ Found ${codeData?.total_count} code matches in React\n`);
339
+ } catch (error: any) {
340
+ console.error(`❌ Search code failed: ${error.message}`);
341
+ }
342
+
343
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
344
+ console.info('✅ All factory pattern examples completed!');
345
+ console.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
346
+ } catch (error: any) {
347
+ console.error('\n❌ Fatal Error:', error.message);
348
+ if (error.details) {
349
+ console.error('Details:', JSON.stringify(error.details, null, 2));
350
+ }
351
+ process.exit(1);
352
+ }
353
+ }
354
+
355
+ main();