@mastra/dane 0.0.2-alpha.9 → 0.0.2-alpha.93
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.
- package/LICENSE +44 -0
- package/README.md +25 -4
- package/data/crawl/conventional-commit.json +25 -0
- package/dist/commands/changelog.d.ts +2 -0
- package/dist/commands/changelog.d.ts.map +1 -0
- package/dist/commands/changelog.js +15 -0
- package/dist/commands/commit-message.d.ts +2 -0
- package/dist/commands/commit-message.d.ts.map +1 -0
- package/dist/commands/commit-message.js +32 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +40 -0
- package/dist/commands/issue-labeler.d.ts.map +1 -1
- package/dist/commands/issue-labeler.js +19 -2
- package/dist/commands/link-checker.d.ts +4 -0
- package/dist/commands/link-checker.d.ts.map +1 -0
- package/dist/commands/link-checker.js +16 -0
- package/dist/commands/message.d.ts.map +1 -1
- package/dist/commands/message.js +3 -1
- package/dist/commands/new-contributor-message.d.ts +2 -0
- package/dist/commands/new-contributor-message.d.ts.map +1 -0
- package/dist/commands/new-contributor-message.js +43 -0
- package/dist/commands/publish-packages.d.ts +2 -0
- package/dist/commands/publish-packages.d.ts.map +1 -0
- package/dist/commands/publish-packages.js +11 -0
- package/dist/commands/telephone-game.d.ts +2 -0
- package/dist/commands/telephone-game.d.ts.map +1 -0
- package/dist/commands/telephone-game.js +32 -0
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +75 -0
- package/dist/index.js +30 -4
- package/dist/mastra/agents/index.d.ts +33 -2
- package/dist/mastra/agents/index.d.ts.map +1 -1
- package/dist/mastra/agents/index.js +62 -25
- package/dist/mastra/agents/model.d.ts +7 -0
- package/dist/mastra/agents/model.d.ts.map +1 -0
- package/dist/mastra/agents/model.js +7 -0
- package/dist/mastra/agents/new-contributor.d.ts +3 -0
- package/dist/mastra/agents/new-contributor.d.ts.map +1 -0
- package/dist/mastra/agents/new-contributor.js +12 -0
- package/dist/mastra/agents/package-publisher.d.ts +65 -0
- package/dist/mastra/agents/package-publisher.d.ts.map +1 -0
- package/dist/mastra/agents/package-publisher.js +172 -0
- package/dist/mastra/index.d.ts +134 -3
- package/dist/mastra/index.d.ts.map +1 -1
- package/dist/mastra/index.js +20 -3
- package/dist/mastra/integrations/index.d.ts +2 -0
- package/dist/mastra/integrations/index.d.ts.map +1 -1
- package/dist/mastra/integrations/index.js +19 -2
- package/dist/mastra/tools/crawl.d.ts +3 -0
- package/dist/mastra/tools/crawl.d.ts.map +1 -1
- package/dist/mastra/tools/crawl.js +4 -2
- package/dist/mastra/tools/execa.d.ts.map +1 -1
- package/dist/mastra/tools/execa.js +5 -1
- package/dist/mastra/tools/image.d.ts +27 -0
- package/dist/mastra/tools/image.d.ts.map +1 -0
- package/dist/mastra/tools/image.js +37 -0
- package/dist/mastra/tools/mcp.d.ts +3 -0
- package/dist/mastra/tools/mcp.d.ts.map +1 -0
- package/dist/mastra/tools/mcp.js +12 -0
- package/dist/mastra/tools/pdf.d.ts.map +1 -1
- package/dist/mastra/tools/pdf.js +2 -2
- package/dist/mastra/tools/pnpm.d.ts +60 -0
- package/dist/mastra/tools/pnpm.d.ts.map +1 -0
- package/dist/mastra/tools/pnpm.js +127 -0
- package/dist/mastra/workflows/changelog.d.ts +10 -0
- package/dist/mastra/workflows/changelog.d.ts.map +1 -0
- package/dist/mastra/workflows/changelog.js +149 -0
- package/dist/mastra/workflows/chat.d.ts.map +1 -1
- package/dist/mastra/workflows/chat.js +6 -11
- package/dist/mastra/workflows/commit-message.d.ts +10 -0
- package/dist/mastra/workflows/commit-message.d.ts.map +1 -0
- package/dist/mastra/workflows/commit-message.js +138 -0
- package/dist/mastra/workflows/first-contributor.d.ts +16 -0
- package/dist/mastra/workflows/first-contributor.d.ts.map +1 -0
- package/dist/mastra/workflows/first-contributor.js +122 -0
- package/dist/mastra/workflows/index.d.ts +1 -0
- package/dist/mastra/workflows/index.d.ts.map +1 -1
- package/dist/mastra/workflows/index.js +1 -0
- package/dist/mastra/workflows/issue-labeler.js +1 -1
- package/dist/mastra/workflows/link-checker.d.ts +13 -0
- package/dist/mastra/workflows/link-checker.d.ts.map +1 -0
- package/dist/mastra/workflows/link-checker.js +102 -0
- package/dist/mastra/workflows/publish-packages.d.ts +3 -0
- package/dist/mastra/workflows/publish-packages.d.ts.map +1 -0
- package/dist/mastra/workflows/publish-packages.js +260 -0
- package/dist/mastra/workflows/telephone-game.d.ts +3 -0
- package/dist/mastra/workflows/telephone-game.d.ts.map +1 -0
- package/dist/mastra/workflows/telephone-game.js +95 -0
- package/package.json +12 -9
- package/test-files/716a95a5c57a56d32a32b1c9592d6df0.png +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Step, Workflow } from '@mastra/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { slack } from '../tools/mcp.js';
|
|
7
|
+
export const changelogWorkflow = new Workflow({
|
|
8
|
+
name: 'changelog',
|
|
9
|
+
triggerSchema: z.object({
|
|
10
|
+
channelId: z.string(),
|
|
11
|
+
}),
|
|
12
|
+
});
|
|
13
|
+
const stepA1 = new Step({
|
|
14
|
+
id: 'stepA1',
|
|
15
|
+
description: 'Get a git diff',
|
|
16
|
+
outputSchema: z.object({
|
|
17
|
+
message: z.string(),
|
|
18
|
+
}),
|
|
19
|
+
execute: async () => {
|
|
20
|
+
console.log('SUH');
|
|
21
|
+
// For today
|
|
22
|
+
try {
|
|
23
|
+
await slack.connect();
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.error(e);
|
|
27
|
+
}
|
|
28
|
+
const today = new Date().toISOString().split('T')[0];
|
|
29
|
+
console.log(today);
|
|
30
|
+
// For 7 days ago
|
|
31
|
+
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
32
|
+
console.log(weekAgo);
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
console.log(cwd);
|
|
35
|
+
const args = [
|
|
36
|
+
'--no-pager',
|
|
37
|
+
'diff',
|
|
38
|
+
'--unified=1', // Reduced context to 1 line
|
|
39
|
+
'--no-prefix',
|
|
40
|
+
'--color=never',
|
|
41
|
+
'--shortstat', // Get size first to check
|
|
42
|
+
`main@{${weekAgo}}`,
|
|
43
|
+
`main@{${today}}`,
|
|
44
|
+
'--',
|
|
45
|
+
'packages/**',
|
|
46
|
+
// 'docs/**'
|
|
47
|
+
];
|
|
48
|
+
console.log(args);
|
|
49
|
+
const p = execa('git', args, {
|
|
50
|
+
cwd,
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
const diff = await p;
|
|
54
|
+
return {
|
|
55
|
+
message: diff.stdout,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.error(e);
|
|
60
|
+
return {
|
|
61
|
+
message: 'Error, do not compute',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const stepA2 = new Step({
|
|
67
|
+
id: 'stepA2',
|
|
68
|
+
description: 'Make changelog',
|
|
69
|
+
outputSchema: z.object({
|
|
70
|
+
message: z.string(),
|
|
71
|
+
}),
|
|
72
|
+
execute: async ({ context, mastra }) => {
|
|
73
|
+
if (context.machineContext?.stepResults.stepA1?.status !== 'success') {
|
|
74
|
+
throw new Error('Message not found');
|
|
75
|
+
}
|
|
76
|
+
const agent = mastra?.agents?.daneChangeLog;
|
|
77
|
+
if (!agent) {
|
|
78
|
+
throw new Error('LLM not found');
|
|
79
|
+
}
|
|
80
|
+
const today = new Date().toISOString().split('T')[0];
|
|
81
|
+
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
82
|
+
const tools = await slack.tools();
|
|
83
|
+
if (existsSync(`changelog-${today}`)) {
|
|
84
|
+
const existing = readFileSync(`changelog-${today}`, 'utf-8');
|
|
85
|
+
await agent.generate(`
|
|
86
|
+
Send this ${existing} to this slack channel: "${context.machineContext.triggerData.channelId}" with the tool slack_post_message.
|
|
87
|
+
Format it in markdown so it displays nicely in slack.
|
|
88
|
+
`, {
|
|
89
|
+
toolsets: {
|
|
90
|
+
slack: tools,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
message: existing,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const channelId = context.machineContext.triggerData.channelId;
|
|
98
|
+
const prompt = `
|
|
99
|
+
Time: ${weekAgo} - ${today}
|
|
100
|
+
|
|
101
|
+
Git diff to generate from: ${context.machineContext.stepResults.stepA1.payload.message}
|
|
102
|
+
# Task
|
|
103
|
+
1. create a structured narrative changelog that highlights key updates and improvements.
|
|
104
|
+
2. Include what packages were changed
|
|
105
|
+
|
|
106
|
+
## Structure
|
|
107
|
+
|
|
108
|
+
1. Opening
|
|
109
|
+
- Brief welcome/context (1-2 sentences)
|
|
110
|
+
- Time period covered
|
|
111
|
+
|
|
112
|
+
2. Major Updates (3-4 key highlights)
|
|
113
|
+
- Lead with the most impactful changes
|
|
114
|
+
- Include brief technical context where needed
|
|
115
|
+
- Reference relevant PR numbers
|
|
116
|
+
- Link to examples/docs where applicable
|
|
117
|
+
|
|
118
|
+
3. Technical Improvements
|
|
119
|
+
- Group related changes
|
|
120
|
+
- Focus on developer impact
|
|
121
|
+
- Include code snippets if helpful
|
|
122
|
+
|
|
123
|
+
4. Documentation & Examples
|
|
124
|
+
- New guides/tutorials
|
|
125
|
+
- Updated examples
|
|
126
|
+
- API documentation changes
|
|
127
|
+
|
|
128
|
+
5. Bug Fixes & Infrastructure
|
|
129
|
+
- Notable bug fixes
|
|
130
|
+
- Build/deployment improvements
|
|
131
|
+
- Performance optimizations
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
Finally send this to this slack channel: "${channelId}" with the tool slack_post_message
|
|
135
|
+
`;
|
|
136
|
+
console.log(chalk.green(`Generating...`));
|
|
137
|
+
const result = await agent.generate(prompt, {
|
|
138
|
+
toolsets: {
|
|
139
|
+
slack: tools,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
console.log(chalk.green(result.text));
|
|
143
|
+
writeFileSync(`changelog-${today}`, result.text);
|
|
144
|
+
return {
|
|
145
|
+
message: result.text,
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
changelogWorkflow.step(stepA1).then(stepA2).commit();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/chat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,eAAe;;;;;;;;;GAM1B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { input } from '@inquirer/prompts';
|
|
1
2
|
import { Step, Workflow } from '@mastra/core';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
|
-
import inquirer from 'inquirer';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { dane } from '../agents/index.js';
|
|
6
6
|
export const messageWorkflow = new Workflow({
|
|
@@ -16,14 +16,10 @@ const messageStep = new Step({
|
|
|
16
16
|
message: z.string(),
|
|
17
17
|
}),
|
|
18
18
|
execute: async () => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
message: '\n You:',
|
|
24
|
-
validate: input => input.trim().length > 0 || 'Message cannot be empty',
|
|
25
|
-
},
|
|
26
|
-
]);
|
|
19
|
+
const content = await input({
|
|
20
|
+
message: '\n You:',
|
|
21
|
+
validate: input => input.trim().length > 0 || 'Message cannot be empty',
|
|
22
|
+
});
|
|
27
23
|
return { message: content };
|
|
28
24
|
},
|
|
29
25
|
});
|
|
@@ -51,8 +47,7 @@ const messageOutputStep = new Step({
|
|
|
51
47
|
if (!messages || messages.length === 0) {
|
|
52
48
|
messages = [];
|
|
53
49
|
}
|
|
54
|
-
const res = await mastra?.agents?.['dane']?.
|
|
55
|
-
stream: true,
|
|
50
|
+
const res = await mastra?.agents?.['dane']?.stream(message, {
|
|
56
51
|
maxSteps: 5,
|
|
57
52
|
resourceid,
|
|
58
53
|
threadId,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Workflow } from '@mastra/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const commitMessageGenerator: Workflow<any, z.ZodObject<{
|
|
4
|
+
repoPath: z.ZodString;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
repoPath: string;
|
|
7
|
+
}, {
|
|
8
|
+
repoPath: string;
|
|
9
|
+
}>>;
|
|
10
|
+
//# sourceMappingURL=commit-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-message.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/commit-message.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,sBAAsB;;;;;;GAKjC,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import { Step, Workflow } from '@mastra/core';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { fsTool } from '../tools/fs.js';
|
|
7
|
+
export const commitMessageGenerator = new Workflow({
|
|
8
|
+
name: 'commit-message',
|
|
9
|
+
triggerSchema: z.object({
|
|
10
|
+
repoPath: z.string(),
|
|
11
|
+
}),
|
|
12
|
+
});
|
|
13
|
+
const getDiff = new Step({
|
|
14
|
+
id: 'getDiff',
|
|
15
|
+
outputSchema: z.object({
|
|
16
|
+
diff: z.string(),
|
|
17
|
+
}),
|
|
18
|
+
execute: async ({ context }) => {
|
|
19
|
+
const repoPath = context?.machineContext?.getStepPayload('trigger')?.repoPath;
|
|
20
|
+
// Get the git diff of staged changes
|
|
21
|
+
const diff = execSync('git diff --staged', {
|
|
22
|
+
cwd: repoPath,
|
|
23
|
+
encoding: 'utf-8',
|
|
24
|
+
});
|
|
25
|
+
return { diff };
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const readConventionalCommitSpec = new Step({
|
|
29
|
+
id: 'readConventionalCommitSpec',
|
|
30
|
+
outputSchema: z.object({
|
|
31
|
+
fileData: z.any(),
|
|
32
|
+
}),
|
|
33
|
+
execute: async ({ suspend }) => {
|
|
34
|
+
const fileData = await fsTool.execute({
|
|
35
|
+
context: { action: 'read', file: 'data/crawl/conventional-commit.json', data: '' },
|
|
36
|
+
suspend,
|
|
37
|
+
});
|
|
38
|
+
return { fileData };
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const generateMessage = new Step({
|
|
42
|
+
id: 'generateMessage',
|
|
43
|
+
outputSchema: z.object({
|
|
44
|
+
commitMessage: z.string(),
|
|
45
|
+
generated: z.boolean(),
|
|
46
|
+
guidelines: z.array(z.string()),
|
|
47
|
+
}),
|
|
48
|
+
execute: async ({ context, mastra }) => {
|
|
49
|
+
const diffData = context?.machineContext?.getStepPayload('getDiff');
|
|
50
|
+
const fileData = context?.machineContext?.getStepPayload('readConventionalCommitSpec');
|
|
51
|
+
if (!diffData) {
|
|
52
|
+
return { commitMessage: '', generated: false, guidelines: [] };
|
|
53
|
+
}
|
|
54
|
+
const daneCommitGenerator = mastra?.agents?.daneCommitMessage;
|
|
55
|
+
const res = await daneCommitGenerator?.generate(`
|
|
56
|
+
Given this git diff:
|
|
57
|
+
${diffData.diff}
|
|
58
|
+
|
|
59
|
+
IF THE DIFF IS EMPTY, RETURN "No staged changes found", AND SET GENERATED TO FALSE,
|
|
60
|
+
OTHERWISE, SET GENERATED TO TRUE
|
|
61
|
+
|
|
62
|
+
${fileData && fileData.fileData?.message
|
|
63
|
+
? `USE THE FOLLOWING GUIDELINES: ${fileData.fileData?.message}`
|
|
64
|
+
: `USE THE FOLLOWING GUIDELINES:
|
|
65
|
+
- Start with a verb in the present tense
|
|
66
|
+
- Be specific but concise
|
|
67
|
+
- Focus on the "what" and "why" of the changes
|
|
68
|
+
IF THERE ARE MULTIPLE LOGICAL CHANGES, USE THE DESCRIPTION TO EXPLAIN THE CHANGES IN BULLET POINTS.
|
|
69
|
+
|
|
70
|
+
- Keep the first line under 50 characters
|
|
71
|
+
- If needed, add more detailed description after a blank line`}
|
|
72
|
+
|
|
73
|
+
RETURN THE GUIDELINES YOU ARE USING AS AN ARRAY OF STRINGS ON THE GUIDELINES KEY, AND THE COMMIT MESSAGE ON THE COMMIT MESSAGE KEY
|
|
74
|
+
`, {
|
|
75
|
+
output: z.object({
|
|
76
|
+
commitMessage: z.string(),
|
|
77
|
+
generated: z.boolean(),
|
|
78
|
+
guidelines: z.array(z.string()),
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
if (!res?.object?.generated) {
|
|
82
|
+
throw new Error(res?.object?.commitMessage);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
commitMessage: res?.object?.commitMessage,
|
|
86
|
+
generated: res?.object?.generated,
|
|
87
|
+
guidelines: res?.object?.guidelines,
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
const confirmationStep = new Step({
|
|
92
|
+
id: 'confirmation',
|
|
93
|
+
outputSchema: z.object({
|
|
94
|
+
confirm: z.boolean(),
|
|
95
|
+
}),
|
|
96
|
+
execute: async ({ context }) => {
|
|
97
|
+
const parentStep = context?.machineContext?.stepResults?.generateMessage;
|
|
98
|
+
if (!parentStep || parentStep.status !== 'success') {
|
|
99
|
+
return { confirm: false };
|
|
100
|
+
}
|
|
101
|
+
if (!parentStep.payload.generated) {
|
|
102
|
+
return { confirm: false };
|
|
103
|
+
}
|
|
104
|
+
const commitMessage = parentStep.payload.commitMessage;
|
|
105
|
+
const confirmationMessage = await confirm({
|
|
106
|
+
message: `\n Would you like to use this commit message? \n\n ${chalk.yellow(commitMessage)}\n\n`,
|
|
107
|
+
});
|
|
108
|
+
return { confirm: confirmationMessage };
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
const commitStep = new Step({
|
|
112
|
+
id: 'commit',
|
|
113
|
+
outputSchema: z.object({
|
|
114
|
+
commit: z.boolean(),
|
|
115
|
+
}),
|
|
116
|
+
execute: async ({ context }) => {
|
|
117
|
+
const parentStep = context?.machineContext?.stepResults?.confirmation;
|
|
118
|
+
if (!parentStep || parentStep.status !== 'success' || !parentStep.payload.confirm) {
|
|
119
|
+
throw new Error('Commit message generation cancelled');
|
|
120
|
+
}
|
|
121
|
+
if (context?.machineContext?.stepResults?.generateMessage?.status !== 'success') {
|
|
122
|
+
throw new Error('Failed to generate commit message');
|
|
123
|
+
}
|
|
124
|
+
const commitMessage = context?.machineContext?.stepResults?.generateMessage?.payload?.commitMessage;
|
|
125
|
+
execSync(`git commit -m "${commitMessage}"`, {
|
|
126
|
+
cwd: context?.machineContext?.triggerData?.repoPath,
|
|
127
|
+
encoding: 'utf-8',
|
|
128
|
+
});
|
|
129
|
+
return { commit: true };
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
commitMessageGenerator
|
|
133
|
+
.step(getDiff)
|
|
134
|
+
.then(readConventionalCommitSpec)
|
|
135
|
+
.then(generateMessage)
|
|
136
|
+
.then(confirmationStep)
|
|
137
|
+
.then(commitStep)
|
|
138
|
+
.commit();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Workflow } from '@mastra/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const githubFirstContributorMessage: Workflow<any, z.ZodObject<{
|
|
4
|
+
repo: z.ZodString;
|
|
5
|
+
owner: z.ZodString;
|
|
6
|
+
pr_number: z.ZodNumber;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
repo: string;
|
|
9
|
+
owner: string;
|
|
10
|
+
pr_number: number;
|
|
11
|
+
}, {
|
|
12
|
+
repo: string;
|
|
13
|
+
owner: string;
|
|
14
|
+
pr_number: number;
|
|
15
|
+
}>>;
|
|
16
|
+
//# sourceMappingURL=first-contributor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"first-contributor.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/first-contributor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;GAOxC,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Step, Workflow } from '@mastra/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { github } from '../integrations/index.js';
|
|
4
|
+
export const githubFirstContributorMessage = new Workflow({
|
|
5
|
+
name: 'github-first-contributor-message',
|
|
6
|
+
triggerSchema: z.object({
|
|
7
|
+
repo: z.string(),
|
|
8
|
+
owner: z.string(),
|
|
9
|
+
pr_number: z.number(),
|
|
10
|
+
}),
|
|
11
|
+
});
|
|
12
|
+
const getPullRequest = new Step({
|
|
13
|
+
id: 'getPullRequest',
|
|
14
|
+
outputSchema: z.object({
|
|
15
|
+
title: z.string(),
|
|
16
|
+
body: z.string(),
|
|
17
|
+
diff: z.string(),
|
|
18
|
+
}),
|
|
19
|
+
execute: async ({ context }) => {
|
|
20
|
+
const client = await github.getApiClient();
|
|
21
|
+
const pullRequest = await client.pullsGet({
|
|
22
|
+
path: {
|
|
23
|
+
owner: context?.machineContext?.triggerData?.owner,
|
|
24
|
+
repo: context?.machineContext?.triggerData?.repo,
|
|
25
|
+
pull_number: context?.machineContext?.triggerData?.pr_number,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
if (!pullRequest?.data) {
|
|
29
|
+
throw new Error('Pull request not found');
|
|
30
|
+
}
|
|
31
|
+
const response = await fetch(pullRequest.data.diff_url);
|
|
32
|
+
const diff = await response.text();
|
|
33
|
+
return {
|
|
34
|
+
title: pullRequest.data.title,
|
|
35
|
+
body: pullRequest.data.body || '',
|
|
36
|
+
diff,
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
const generateMessage = new Step({
|
|
41
|
+
id: 'message-generator',
|
|
42
|
+
outputSchema: z.object({
|
|
43
|
+
message: z.array(z.string()),
|
|
44
|
+
}),
|
|
45
|
+
execute: async ({ context, mastra }) => {
|
|
46
|
+
const parentStep = context?.machineContext?.stepResults?.getPullRequest;
|
|
47
|
+
if (!parentStep || parentStep.status !== 'success') {
|
|
48
|
+
return { message: [] };
|
|
49
|
+
}
|
|
50
|
+
const mastraDocsRes = await fetch('https://mastra.ai/llms.txt');
|
|
51
|
+
const mastraDocs = await mastraDocsRes.text();
|
|
52
|
+
const daneNewContributor = mastra?.agents?.daneNewContributor;
|
|
53
|
+
const res = await daneNewContributor?.generate(`
|
|
54
|
+
Hey Dane, given:
|
|
55
|
+
START TITLE
|
|
56
|
+
${parentStep?.payload?.title}
|
|
57
|
+
END TITLE
|
|
58
|
+
|
|
59
|
+
START BODY
|
|
60
|
+
${parentStep?.payload?.body}
|
|
61
|
+
END BODY
|
|
62
|
+
START DIFF
|
|
63
|
+
${parentStep?.payload?.diff}
|
|
64
|
+
END DIFF
|
|
65
|
+
|
|
66
|
+
I'll give you some more context about Mastra:
|
|
67
|
+
MASTRA DOCS
|
|
68
|
+
${mastraDocs}
|
|
69
|
+
END MASTRA DOCS
|
|
70
|
+
|
|
71
|
+
Write message to the contributor to thank them for their first contribution? And check if the following guidelines are followed, do not mention these checklist if they are actually checked:
|
|
72
|
+
- Check if the body matches the diff and is not empty
|
|
73
|
+
- Check if tests are added or updated
|
|
74
|
+
- check if the code looks similar to what's already written
|
|
75
|
+
- Ask if they have tested the changes on any of the examples
|
|
76
|
+
|
|
77
|
+
VERY IMPORTANT:
|
|
78
|
+
You should not summarize nor you should give advice on the code itself, only follow the guidelines.
|
|
79
|
+
|
|
80
|
+
The message should bes strucutred like:
|
|
81
|
+
an intro message to thank the user for their contribution
|
|
82
|
+
the checklist
|
|
83
|
+
and an outro that just says thank you again and that we will review it shortly. If there is no checklist we should skip thank you.
|
|
84
|
+
`, {
|
|
85
|
+
output: z.object({
|
|
86
|
+
intro: z.string(),
|
|
87
|
+
checklist: z.string().array(),
|
|
88
|
+
outro: z.string(),
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
if (!res) {
|
|
92
|
+
throw new Error(`We couldn't generate a message`);
|
|
93
|
+
}
|
|
94
|
+
return res.object;
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
const createMessage = new Step({
|
|
98
|
+
id: 'create-message',
|
|
99
|
+
execute: async ({ context }) => {
|
|
100
|
+
const parentStep = context?.machineContext?.stepResults?.['message-generator'];
|
|
101
|
+
if (!parentStep || parentStep.status !== 'success') {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const client = await github.getApiClient();
|
|
105
|
+
const res = await client.issuesCreateComment({
|
|
106
|
+
path: {
|
|
107
|
+
owner: context?.machineContext?.triggerData?.owner,
|
|
108
|
+
repo: context?.machineContext?.triggerData?.repo,
|
|
109
|
+
issue_number: context?.machineContext?.triggerData?.pr_number,
|
|
110
|
+
},
|
|
111
|
+
body: {
|
|
112
|
+
body: `${parentStep.payload.intro}
|
|
113
|
+
|
|
114
|
+
${parentStep.payload.checklist.map((s) => `- [ ] ${s}`).join('\n')}
|
|
115
|
+
|
|
116
|
+
${parentStep.payload.outro}`,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
console.log(res);
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
githubFirstContributorMessage.step(getPullRequest).then(generateMessage).then(createMessage).commit();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Workflow } from '@mastra/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const linkCheckerWorkflow: Workflow<any, z.ZodObject<{
|
|
4
|
+
channelId: z.ZodString;
|
|
5
|
+
targetUrl: z.ZodString;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
channelId: string;
|
|
8
|
+
targetUrl: string;
|
|
9
|
+
}, {
|
|
10
|
+
channelId: string;
|
|
11
|
+
targetUrl: string;
|
|
12
|
+
}>>;
|
|
13
|
+
//# sourceMappingURL=link-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-checker.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/link-checker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,mBAAmB;;;;;;;;;GAM9B,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Step, Workflow } from '@mastra/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import child_process from 'node:child_process';
|
|
4
|
+
import util from 'node:util';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { slack } from '../tools/mcp.js';
|
|
7
|
+
const exec = util.promisify(child_process.exec);
|
|
8
|
+
export const linkCheckerWorkflow = new Workflow({
|
|
9
|
+
name: 'link-checker',
|
|
10
|
+
triggerSchema: z.object({
|
|
11
|
+
channelId: z.string(),
|
|
12
|
+
targetUrl: z.string(),
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
const linkSchema = z.object({
|
|
16
|
+
url: z.string(),
|
|
17
|
+
status: z.number(),
|
|
18
|
+
state: z.enum(['OK', 'BROKEN']),
|
|
19
|
+
parent: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
const getBrokenLinks = new Step({
|
|
22
|
+
id: 'get-broken-links',
|
|
23
|
+
description: 'Get broken links',
|
|
24
|
+
inputSchema: z.object({
|
|
25
|
+
targetUrl: z.string(),
|
|
26
|
+
}),
|
|
27
|
+
outputSchema: z.object({
|
|
28
|
+
brokenLinks: z.array(linkSchema),
|
|
29
|
+
}),
|
|
30
|
+
execute: async ({ context }) => {
|
|
31
|
+
const targetUrl = context.targetUrl;
|
|
32
|
+
const res = await exec(`npx linkinator ${targetUrl} --format json`, {
|
|
33
|
+
encoding: 'utf-8',
|
|
34
|
+
});
|
|
35
|
+
if (res.stderr) {
|
|
36
|
+
throw new Error(res.stderr);
|
|
37
|
+
}
|
|
38
|
+
const data = JSON.parse(res.stdout);
|
|
39
|
+
const parsedData = linkSchema.array().parse(data.links);
|
|
40
|
+
return {
|
|
41
|
+
brokenLinks: parsedData.filter(link => link.state === 'BROKEN'),
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
const reportBrokenLinks = new Step({
|
|
46
|
+
id: 'report-broken-links',
|
|
47
|
+
description: 'Report broken links',
|
|
48
|
+
outputSchema: z.object({
|
|
49
|
+
message: z.string(),
|
|
50
|
+
}),
|
|
51
|
+
execute: async ({ context, mastra }) => {
|
|
52
|
+
const brokenLinks = context.machineContext?.getStepPayload('get-broken-links');
|
|
53
|
+
if (!brokenLinks) {
|
|
54
|
+
return {
|
|
55
|
+
message: 'No broken links found',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (brokenLinks.brokenLinks.length === 0) {
|
|
59
|
+
return {
|
|
60
|
+
message: 'No broken links found',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
await slack.connect();
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
console.error(e);
|
|
68
|
+
}
|
|
69
|
+
const triggerPayload = context.machineContext?.getStepPayload('trigger');
|
|
70
|
+
if (!triggerPayload) {
|
|
71
|
+
return {
|
|
72
|
+
message: 'Trigger payload not found',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const agent = mastra?.agents?.daneLinkChecker;
|
|
76
|
+
if (!agent) {
|
|
77
|
+
return {
|
|
78
|
+
message: 'Agent not found',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const tools = await slack.tools();
|
|
82
|
+
console.log(`🤖Generating...`);
|
|
83
|
+
const res = await agent.generate(`
|
|
84
|
+
Send this ${JSON.stringify(brokenLinks, null, 2)} to this slack channel: "${triggerPayload.channelId}" with the tool slack_post_message.
|
|
85
|
+
Format it in markdown so it displays nicely in slack.
|
|
86
|
+
`, {
|
|
87
|
+
toolsets: { slack: tools },
|
|
88
|
+
});
|
|
89
|
+
console.log(chalk.green(res.text));
|
|
90
|
+
return {
|
|
91
|
+
message: res.text,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
linkCheckerWorkflow
|
|
96
|
+
.step(getBrokenLinks, {
|
|
97
|
+
variables: {
|
|
98
|
+
targetUrl: { step: 'trigger', path: 'targetUrl' },
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
.then(reportBrokenLinks)
|
|
102
|
+
.commit();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-packages.d.ts","sourceRoot":"","sources":["../../../src/mastra/workflows/publish-packages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQ9C,eAAO,MAAM,gBAAgB,oBAE3B,CAAC"}
|