stellar-agent 0.1.0

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 (59) hide show
  1. package/README.md +162 -0
  2. package/package.json +37 -0
  3. package/src/core-skills/module-help.csv +5 -0
  4. package/src/core-skills/module.yaml +33 -0
  5. package/src/core-skills/stellar-brainstorming/SKILL.md +6 -0
  6. package/src/core-skills/stellar-brainstorming/steps/step-01-session-setup.md +67 -0
  7. package/src/core-skills/stellar-brainstorming/steps/step-02a-user-selected.md +20 -0
  8. package/src/core-skills/stellar-brainstorming/steps/step-02b-ai-recommended.md +29 -0
  9. package/src/core-skills/stellar-brainstorming/steps/step-03-technique-execution.md +69 -0
  10. package/src/core-skills/stellar-brainstorming/steps/step-04-idea-organization.md +64 -0
  11. package/src/core-skills/stellar-brainstorming/workflow.md +50 -0
  12. package/src/core-skills/stellar-help/SKILL.md +71 -0
  13. package/src/core-skills/stellar-party-mode/SKILL.md +109 -0
  14. package/src/scripts/resolve_config.py +170 -0
  15. package/src/scripts/resolve_customization.py +209 -0
  16. package/src/stellar-skills/1-analysis/stellar-agent-analyst/SKILL.md +71 -0
  17. package/src/stellar-skills/1-analysis/stellar-agent-analyst/customize.toml +41 -0
  18. package/src/stellar-skills/1-analysis/stellar-analytics/SKILL.md +239 -0
  19. package/src/stellar-skills/1-analysis/stellar-domain-research/SKILL.md +82 -0
  20. package/src/stellar-skills/1-analysis/stellar-market-research/SKILL.md +90 -0
  21. package/src/stellar-skills/2-planning/stellar-agent-pm/SKILL.md +57 -0
  22. package/src/stellar-skills/2-planning/stellar-agent-pm/customize.toml +36 -0
  23. package/src/stellar-skills/2-planning/stellar-epics-stories/SKILL.md +106 -0
  24. package/src/stellar-skills/2-planning/stellar-prd/SKILL.md +115 -0
  25. package/src/stellar-skills/2-planning/stellar-project-brief/SKILL.md +83 -0
  26. package/src/stellar-skills/3-architecture/stellar-agent-architect/SKILL.md +53 -0
  27. package/src/stellar-skills/3-architecture/stellar-agent-architect/customize.toml +31 -0
  28. package/src/stellar-skills/3-architecture/stellar-architecture-doc/SKILL.md +162 -0
  29. package/src/stellar-skills/4-implementation/stellar-agent-developer/SKILL.md +54 -0
  30. package/src/stellar-skills/4-implementation/stellar-agent-developer/customize.toml +56 -0
  31. package/src/stellar-skills/4-implementation/stellar-agent-devops/SKILL.md +54 -0
  32. package/src/stellar-skills/4-implementation/stellar-agent-devops/customize.toml +36 -0
  33. package/src/stellar-skills/4-implementation/stellar-agent-frontend/SKILL.md +54 -0
  34. package/src/stellar-skills/4-implementation/stellar-agent-frontend/customize.toml +52 -0
  35. package/src/stellar-skills/4-implementation/stellar-agent-qa/SKILL.md +54 -0
  36. package/src/stellar-skills/4-implementation/stellar-agent-qa/customize.toml +31 -0
  37. package/src/stellar-skills/4-implementation/stellar-create-asset/SKILL.md +145 -0
  38. package/src/stellar-skills/4-implementation/stellar-create-transaction/SKILL.md +134 -0
  39. package/src/stellar-skills/4-implementation/stellar-deploy-contract/SKILL.md +124 -0
  40. package/src/stellar-skills/4-implementation/stellar-freighter-integration/SKILL.md +193 -0
  41. package/src/stellar-skills/4-implementation/stellar-horizon-integration/SKILL.md +198 -0
  42. package/src/stellar-skills/4-implementation/stellar-init-contract/SKILL.md +102 -0
  43. package/src/stellar-skills/4-implementation/stellar-liquidity-pool/SKILL.md +156 -0
  44. package/src/stellar-skills/4-implementation/stellar-nextjs-setup/SKILL.md +198 -0
  45. package/src/stellar-skills/4-implementation/stellar-nextjs-soroban/SKILL.md +228 -0
  46. package/src/stellar-skills/4-implementation/stellar-nextjs-wallet/SKILL.md +276 -0
  47. package/src/stellar-skills/4-implementation/stellar-sep10-auth/SKILL.md +252 -0
  48. package/src/stellar-skills/4-implementation/stellar-setup-environment/SKILL.md +163 -0
  49. package/src/stellar-skills/4-implementation/stellar-setup-trustline/SKILL.md +107 -0
  50. package/src/stellar-skills/4-implementation/stellar-test-contract/SKILL.md +146 -0
  51. package/src/stellar-skills/4-implementation/stellar-write-contract/SKILL.md +140 -0
  52. package/src/stellar-skills/module-help.csv +24 -0
  53. package/src/stellar-skills/module.yaml +103 -0
  54. package/tools/installer/cli-utils.js +39 -0
  55. package/tools/installer/commands/init.js +335 -0
  56. package/tools/installer/fs-native.js +116 -0
  57. package/tools/installer/prompts.js +852 -0
  58. package/tools/installer/stellar-cli.js +80 -0
  59. package/tools/installer/yaml-format.js +245 -0
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const path = require('node:path');
5
+ const { execFileSync } = require('node:child_process');
6
+ const semver = require('semver');
7
+ const prompts = require('./prompts');
8
+
9
+ if (process.stdin?.setMaxListeners) {
10
+ const currentLimit = process.stdin.getMaxListeners();
11
+ process.stdin.setMaxListeners(Math.max(currentLimit, 50));
12
+ }
13
+
14
+ const packageJson = require('../../package.json');
15
+ const packageName = 'stellar-agent';
16
+ checkForUpdate().catch(() => {});
17
+
18
+ async function checkForUpdate() {
19
+ try {
20
+ const tag = semver.prerelease(packageJson.version) ? 'next' : 'latest';
21
+ const result = execFileSync('npm', ['view', `${packageName}@${tag}`, 'version'], {
22
+ encoding: 'utf8',
23
+ stdio: 'pipe',
24
+ timeout: 5000,
25
+ }).trim();
26
+
27
+ if (result && semver.gt(result, packageJson.version)) {
28
+ const color = await prompts.getColor();
29
+ const updateMsg = [
30
+ `You are using version ${packageJson.version} but ${result} is available.`,
31
+ '',
32
+ 'To update, exit and first run:',
33
+ ` npm cache clean --force && npx stellar-agent@${tag} init`,
34
+ ].join('\n');
35
+ await prompts.box(updateMsg, 'Update Available', {
36
+ rounded: true,
37
+ formatBorder: color.yellow,
38
+ });
39
+ }
40
+ } catch {
41
+ // Silently fail - network issues or npm not available
42
+ }
43
+ }
44
+
45
+ if (process.stdin.isTTY) {
46
+ try {
47
+ process.stdin.resume();
48
+ process.stdin.setEncoding('utf8');
49
+ if (process.platform === 'win32') {
50
+ process.stdin.on('error', () => {});
51
+ }
52
+ } catch {
53
+ // Silently ignore
54
+ }
55
+ }
56
+
57
+ const commandsPath = path.join(__dirname, 'commands');
58
+ const ALLOWED_COMMANDS = ['init'];
59
+
60
+ const commands = {};
61
+ for (const name of ALLOWED_COMMANDS) {
62
+ const command = require(path.join(commandsPath, `${name}.js`));
63
+ commands[command.command] = command;
64
+ }
65
+
66
+ program.version(packageJson.version).description('Stellar Agent CLI - AI agent team for Stellar blockchain');
67
+
68
+ for (const [name, cmd] of Object.entries(commands)) {
69
+ const command = program.command(name).description(cmd.description);
70
+ for (const option of cmd.options || []) {
71
+ command.option(...option);
72
+ }
73
+ command.action(cmd.action);
74
+ }
75
+
76
+ program.parse(process.argv);
77
+
78
+ if (process.argv.slice(2).length === 0) {
79
+ program.outputHelp();
80
+ }
@@ -0,0 +1,245 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const yaml = require('yaml');
4
+ const { execFileSync } = require('node:child_process');
5
+
6
+ // Dynamic import for ES module
7
+ let chalk;
8
+
9
+ // Initialize ES modules
10
+ async function initializeModules() {
11
+ if (!chalk) {
12
+ chalk = (await import('chalk')).default;
13
+ }
14
+ }
15
+
16
+ /**
17
+ * YAML Formatter and Linter for BMad-Method
18
+ * Formats and validates YAML files and YAML embedded in Markdown
19
+ */
20
+
21
+ async function formatYamlContent(content, filename) {
22
+ await initializeModules();
23
+ try {
24
+ // First try to fix common YAML issues
25
+ let fixedContent = content
26
+ // Fix "commands :" -> "commands:"
27
+ .replaceAll(/^(\s*)(\w+)\s+:/gm, '$1$2:')
28
+ // Fix inconsistent list indentation
29
+ .replaceAll(/^(\s*)-\s{3,}/gm, '$1- ');
30
+
31
+ // Skip auto-fixing for .roomodes files - they have special nested structure
32
+ if (!filename.includes('.roomodes')) {
33
+ fixedContent = fixedContent
34
+ // Fix unquoted list items that contain special characters or multiple parts
35
+ .replaceAll(/^(\s*)-\s+(.*)$/gm, (match, indent, content) => {
36
+ // Skip if already quoted
37
+ if (content.startsWith('"') && content.endsWith('"')) {
38
+ return match;
39
+ }
40
+ // If the content contains special YAML characters or looks complex, quote it
41
+ // BUT skip if it looks like a proper YAML key-value pair (like "key: value")
42
+ if (
43
+ (content.includes(':') || content.includes('-') || content.includes('{') || content.includes('}')) &&
44
+ !/^\w+:\s/.test(content)
45
+ ) {
46
+ // Remove any existing quotes first, escape internal quotes, then add proper quotes
47
+ const cleanContent = content.replaceAll(/^["']|["']$/g, '').replaceAll('"', String.raw`\"`);
48
+ return `${indent}- "${cleanContent}"`;
49
+ }
50
+ return match;
51
+ });
52
+ }
53
+
54
+ // Debug: show what we're trying to parse
55
+ if (fixedContent !== content) {
56
+ console.log(chalk.blue(`🔧 Applied YAML fixes to ${filename}`));
57
+ }
58
+
59
+ // Parse and re-dump YAML to format it
60
+ const parsed = yaml.parse(fixedContent);
61
+ const formatted = yaml.stringify(parsed, {
62
+ indent: 2,
63
+ lineWidth: 0, // Disable line wrapping
64
+ sortKeys: false, // Preserve key order
65
+ });
66
+ // Ensure POSIX-compliant final newline
67
+ return formatted.endsWith('\n') ? formatted : formatted + '\n';
68
+ } catch (error) {
69
+ console.error(chalk.red(`❌ YAML syntax error in ${filename}:`), error.message);
70
+ console.error(chalk.yellow(`💡 Try manually fixing the YAML structure first`));
71
+ return null;
72
+ }
73
+ }
74
+
75
+ async function processMarkdownFile(filePath) {
76
+ await initializeModules();
77
+ const content = fs.readFileSync(filePath, 'utf8');
78
+ let modified = false;
79
+ let newContent = content;
80
+
81
+ // Fix untyped code blocks by adding 'text' type
82
+ // Match ``` at start of line followed by newline, but only if it's an opening fence
83
+ newContent = newContent.replaceAll(/^```\n([\s\S]*?)\n```$/gm, '```text\n$1\n```');
84
+ if (newContent !== content) {
85
+ modified = true;
86
+ console.log(chalk.blue(`🔧 Added 'text' type to untyped code blocks in ${filePath}`));
87
+ }
88
+
89
+ // Find YAML code blocks
90
+ const yamlBlockRegex = /```ya?ml\n([\s\S]*?)\n```/g;
91
+ let match;
92
+ const replacements = [];
93
+
94
+ while ((match = yamlBlockRegex.exec(newContent)) !== null) {
95
+ const [fullMatch, yamlContent] = match;
96
+ const formatted = await formatYamlContent(yamlContent, filePath);
97
+ if (formatted !== null) {
98
+ const trimmedFormatted = formatted.replace(/\n$/, '');
99
+
100
+ if (trimmedFormatted !== yamlContent) {
101
+ modified = true;
102
+ console.log(chalk.green(`✓ Formatted YAML in ${filePath}`));
103
+ }
104
+
105
+ replacements.push({
106
+ start: match.index,
107
+ end: match.index + fullMatch.length,
108
+ replacement: `\`\`\`yaml\n${trimmedFormatted}\n\`\`\``,
109
+ });
110
+ }
111
+ }
112
+
113
+ // Apply replacements in reverse order to maintain indices
114
+ for (let index = replacements.length - 1; index >= 0; index--) {
115
+ const { start, end, replacement } = replacements[index];
116
+ newContent = newContent.slice(0, start) + replacement + newContent.slice(end);
117
+ }
118
+
119
+ if (modified) {
120
+ fs.writeFileSync(filePath, newContent);
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+
126
+ async function processYamlFile(filePath) {
127
+ await initializeModules();
128
+ const content = fs.readFileSync(filePath, 'utf8');
129
+ const formatted = await formatYamlContent(content, filePath);
130
+
131
+ if (formatted === null) {
132
+ return false; // Syntax error
133
+ }
134
+
135
+ if (formatted !== content) {
136
+ fs.writeFileSync(filePath, formatted);
137
+ return true;
138
+ }
139
+ return false;
140
+ }
141
+
142
+ async function lintYamlFile(filePath) {
143
+ await initializeModules();
144
+ try {
145
+ // Use yaml-lint for additional validation — execFileSync avoids shell injection
146
+ execFileSync('npx', ['yaml-lint', filePath], { stdio: 'pipe' });
147
+ return true;
148
+ } catch (error) {
149
+ console.error(chalk.red(`❌ YAML lint error in ${filePath}:`));
150
+ console.error(error.stdout?.toString() || error.message);
151
+ return false;
152
+ }
153
+ }
154
+
155
+ async function main() {
156
+ await initializeModules();
157
+ const arguments_ = process.argv.slice(2);
158
+ const glob = require('glob');
159
+
160
+ if (arguments_.length === 0) {
161
+ console.error('Usage: node yaml-format.js <file1> [file2] ...');
162
+ process.exit(1);
163
+ }
164
+
165
+ let hasErrors = false;
166
+ let hasChanges = false;
167
+ let filesProcessed = [];
168
+
169
+ // Expand glob patterns and collect all files
170
+ const allFiles = [];
171
+ for (const argument of arguments_) {
172
+ if (argument.includes('*')) {
173
+ // It's a glob pattern
174
+ const matches = glob.sync(argument);
175
+ allFiles.push(...matches);
176
+ } else {
177
+ // It's a direct file path
178
+ allFiles.push(argument);
179
+ }
180
+ }
181
+
182
+ for (const filePath of allFiles) {
183
+ if (!fs.existsSync(filePath)) {
184
+ // Skip silently for glob patterns that don't match anything
185
+ if (!arguments_.some((argument) => argument.includes('*') && filePath === argument)) {
186
+ console.error(chalk.red(`❌ File not found: ${filePath}`));
187
+ hasErrors = true;
188
+ }
189
+ continue;
190
+ }
191
+
192
+ const extension = path.extname(filePath).toLowerCase();
193
+ const basename = path.basename(filePath).toLowerCase();
194
+
195
+ try {
196
+ let changed = false;
197
+ if (extension === '.md') {
198
+ changed = await processMarkdownFile(filePath);
199
+ } else if (
200
+ extension === '.yaml' ||
201
+ extension === '.yml' ||
202
+ basename.includes('roomodes') ||
203
+ basename.includes('.yaml') ||
204
+ basename.includes('.yml')
205
+ ) {
206
+ // Handle YAML files and special cases like .roomodes
207
+ changed = await processYamlFile(filePath);
208
+
209
+ // Also run linting
210
+ const lintPassed = await lintYamlFile(filePath);
211
+ if (!lintPassed) hasErrors = true;
212
+ } else {
213
+ // Skip silently for unsupported files
214
+ continue;
215
+ }
216
+
217
+ if (changed) {
218
+ hasChanges = true;
219
+ filesProcessed.push(filePath);
220
+ }
221
+ } catch (error) {
222
+ console.error(chalk.red(`❌ Error processing ${filePath}:`), error.message);
223
+ hasErrors = true;
224
+ }
225
+ }
226
+
227
+ if (hasChanges) {
228
+ console.log(chalk.green(`\n✨ YAML formatting completed! Modified ${filesProcessed.length} files:`));
229
+ for (const file of filesProcessed) console.log(chalk.blue(` 📝 ${file}`));
230
+ }
231
+
232
+ if (hasErrors) {
233
+ console.error(chalk.red('\n💥 Some files had errors. Please fix them before committing.'));
234
+ process.exit(1);
235
+ }
236
+ }
237
+
238
+ if (require.main === module) {
239
+ main().catch((error) => {
240
+ console.error('Error:', error);
241
+ process.exit(1);
242
+ });
243
+ }
244
+
245
+ module.exports = { formatYamlContent, processMarkdownFile, processYamlFile };