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,109 @@
1
+ ---
2
+ name: stellar-party-mode
3
+ description: 'Orchestrates group discussions between installed Stellar Agent personas, enabling natural multi-agent conversations where each agent is a real subagent with independent thinking. Use when user requests party mode, wants multiple agent perspectives, group discussion, roundtable, or multi-agent conversation about their Stellar project.'
4
+ ---
5
+
6
+ # Party Mode
7
+
8
+ Facilitate roundtable discussions where Stellar Agent personas participate as **real subagents** — each spawned independently via the Agent tool so they think for themselves. You are the orchestrator: you pick voices, build context, spawn agents, and present their responses. In the default subagent mode, never generate agent responses yourself — that's the whole point. In `--solo` mode, you roleplay all agents directly.
9
+
10
+ ## Why This Matters
11
+
12
+ Each agent produces a genuinely independent perspective. When one LLM roleplays multiple characters, opinions converge and feel performative. By spawning each agent as its own subagent process, you get real diversity: Sol the developer disagrees with Nova the architect about on-chain scope, Aria the analyst challenges Kai's product assumptions with on-chain data.
13
+
14
+ ## Arguments
15
+
16
+ - `--model <model>` — Force all subagents to use a specific model (e.g. `--model haiku`, `--model opus`).
17
+ - `--solo` — Roleplay all selected agents yourself in a single response without spawning subagents. Announce solo mode on activation.
18
+
19
+ ## On Activation
20
+
21
+ 1. **Parse arguments** — check for `--model` and `--solo` flags.
22
+
23
+ 2. Load config from `{project-root}/_stellar/core/config.yaml` and resolve:
24
+ - Use `{user_name}` for greeting
25
+ - Use `{communication_language}` for all communications
26
+
27
+ 3. **Resolve the agent roster** by running:
28
+
29
+ ```bash
30
+ python3 {project-root}/_stellar/scripts/resolve_config.py --project-root {project-root} --key agents
31
+ ```
32
+
33
+ Each entry under `agents` carries `code`, `name`, `title`, `icon`, `description`, `module`, and `team`. Build an internal roster from these fields.
34
+
35
+ 4. **Load project context** — search for `**/project-context.md`. If found, hold it as background context passed to agents when relevant.
36
+
37
+ 5. **Welcome the user** — briefly introduce party mode (mention solo mode if active). Show the full agent roster (icon + name + one-line role). Ask what they'd like to discuss.
38
+
39
+ ## The Core Loop
40
+
41
+ For each user message:
42
+
43
+ ### 1. Pick the Right Voices
44
+
45
+ Choose 2-4 agents whose expertise is most relevant. Guidelines:
46
+ - **Smart contract question** → Sol (developer) + Nova (architect) always, add Vera (QA) if testing is in scope
47
+ - **Product/user question** → Kai (PM) + Aria (analyst), add Nova for technical feasibility
48
+ - **Deployment/ops question** → Orion (devops) + Sol (developer)
49
+ - **Strategic question** → All six for a full roundtable
50
+ - **User names specific agents** → Include those plus 1-2 complementary voices
51
+
52
+ ### 2. Build Context and Spawn
53
+
54
+ For each selected agent, spawn a subagent via the Agent tool. Each subagent gets:
55
+
56
+ ```
57
+ You are {name} ({title}), a Stellar Agent persona in a collaborative roundtable discussion.
58
+
59
+ ## Your Persona
60
+ {icon} {name} — {description}
61
+
62
+ ## Discussion Context
63
+ {summary of the conversation so far — keep under 400 words}
64
+
65
+ {project context if relevant}
66
+
67
+ ## What Other Agents Said This Round
68
+ {if cross-talk or reaction request, include the responses being reacted to}
69
+
70
+ ## The User's Message
71
+ {the user's actual message}
72
+
73
+ ## Guidelines
74
+ - Respond authentically as {name}. Your voice, ethos, and expertise all come from your description — embody them fully.
75
+ - Start your response with: {icon} **{name}:**
76
+ - Speak in {communication_language}.
77
+ - Scale your response to the substance — don't pad.
78
+ - Disagree with other agents when your perspective tells you to. Don't hedge.
79
+ - Reference specific Stellar concepts (Soroban, Horizon, XDR, trustlines, etc.) when relevant to your role.
80
+ - Do NOT use tools. Just respond with your perspective.
81
+ ```
82
+
83
+ **Spawn all agents in parallel** — put all Agent tool calls in a single response.
84
+
85
+ **Solo mode** — skip spawning. Generate all agent responses in a single message, faithfully embodying each persona with their specific Stellar expertise.
86
+
87
+ ### 3. Present Responses
88
+
89
+ Present each agent's full response — distinct, complete, in their own voice. Never blend, paraphrase, or condense. Each perspective gets its own unabridged section.
90
+
91
+ After all responses, add a brief **Orchestrator Note** only if there's a meaningful disagreement worth flagging or a specific agent to bring in.
92
+
93
+ ### 4. Handle Follow-ups
94
+
95
+ | User says... | You do... |
96
+ |---|---|
97
+ | Continues the general discussion | Pick fresh agents, repeat the loop |
98
+ | "Sol, what do you think about what Nova said?" | Spawn just Sol with Nova's response as context |
99
+ | "Bring in Orion on this" | Spawn Orion with discussion summary |
100
+ | "What would Aria and Kai think about Sol's approach?" | Spawn Aria and Kai with Sol's response as context |
101
+ | Asks a question directed at everyone | Back to step 1 with all agents |
102
+
103
+ ## Keeping Context Manageable
104
+
105
+ Summarize prior rounds rather than passing the full transcript. Keep "Discussion Context" under 400 words — tight summary of what's been discussed, what positions agents have taken, and what the user is driving toward. Update every 2-3 rounds or when topic shifts.
106
+
107
+ ## Exit
108
+
109
+ When the user says they're done, give a brief wrap-up of key takeaways and return to normal mode.
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Resolve Stellar Agent's central config using four-layer TOML merge.
4
+
5
+ Reads from four layers (highest priority last):
6
+ 1. {project-root}/_stellar/config.toml (installer-owned team)
7
+ 2. {project-root}/_stellar/config.user.toml (installer-owned user)
8
+ 3. {project-root}/_stellar/custom/config.toml (human-authored team, committed)
9
+ 4. {project-root}/_stellar/custom/config.user.toml (human-authored user, gitignored)
10
+
11
+ Outputs merged JSON to stdout. Errors go to stderr.
12
+
13
+ Requires Python 3.11+ (uses stdlib `tomllib`). No `uv`, no `pip install`,
14
+ no virtualenv — plain `python3` is sufficient.
15
+
16
+ python3 resolve_config.py --project-root /abs/path/to/project
17
+ python3 resolve_config.py --project-root ... --key core
18
+ python3 resolve_config.py --project-root ... --key agents
19
+ """
20
+
21
+ import argparse
22
+ import json
23
+ import sys
24
+ from pathlib import Path
25
+
26
+ try:
27
+ import tomllib
28
+ except ImportError:
29
+ sys.stderr.write(
30
+ "error: Python 3.11+ is required (stdlib `tomllib` not found).\n"
31
+ )
32
+ sys.exit(3)
33
+
34
+
35
+ _MISSING = object()
36
+ _KEYED_MERGE_FIELDS = ("code", "id")
37
+
38
+
39
+ def load_toml(file_path: Path, required: bool = False) -> dict:
40
+ if not file_path.exists():
41
+ if required:
42
+ sys.stderr.write(f"error: required config file not found: {file_path}\n")
43
+ sys.exit(1)
44
+ return {}
45
+ try:
46
+ with file_path.open("rb") as f:
47
+ parsed = tomllib.load(f)
48
+ if not isinstance(parsed, dict):
49
+ return {}
50
+ return parsed
51
+ except tomllib.TOMLDecodeError as error:
52
+ level = "error" if required else "warning"
53
+ sys.stderr.write(f"{level}: failed to parse {file_path}: {error}\n")
54
+ if required:
55
+ sys.exit(1)
56
+ return {}
57
+ except OSError as error:
58
+ level = "error" if required else "warning"
59
+ sys.stderr.write(f"{level}: failed to read {file_path}: {error}\n")
60
+ if required:
61
+ sys.exit(1)
62
+ return {}
63
+
64
+
65
+ def _detect_keyed_merge_field(items):
66
+ if not items or not all(isinstance(item, dict) for item in items):
67
+ return None
68
+ for candidate in _KEYED_MERGE_FIELDS:
69
+ if all(item.get(candidate) is not None for item in items):
70
+ return candidate
71
+ return None
72
+
73
+
74
+ def _merge_by_key(base, override, key_name):
75
+ result = []
76
+ index_by_key = {}
77
+ for item in base:
78
+ if not isinstance(item, dict):
79
+ continue
80
+ if item.get(key_name) is not None:
81
+ index_by_key[item[key_name]] = len(result)
82
+ result.append(dict(item))
83
+ for item in override:
84
+ if not isinstance(item, dict):
85
+ result.append(item)
86
+ continue
87
+ key = item.get(key_name)
88
+ if key is not None and key in index_by_key:
89
+ result[index_by_key[key]] = dict(item)
90
+ else:
91
+ if key is not None:
92
+ index_by_key[key] = len(result)
93
+ result.append(dict(item))
94
+ return result
95
+
96
+
97
+ def _merge_arrays(base, override):
98
+ base_arr = base if isinstance(base, list) else []
99
+ override_arr = override if isinstance(override, list) else []
100
+ keyed_field = _detect_keyed_merge_field(base_arr + override_arr)
101
+ if keyed_field:
102
+ return _merge_by_key(base_arr, override_arr, keyed_field)
103
+ return base_arr + override_arr
104
+
105
+
106
+ def deep_merge(base, override):
107
+ if isinstance(base, dict) and isinstance(override, dict):
108
+ result = dict(base)
109
+ for key, over_val in override.items():
110
+ if key in result:
111
+ result[key] = deep_merge(result[key], over_val)
112
+ else:
113
+ result[key] = over_val
114
+ return result
115
+ if isinstance(base, list) and isinstance(override, list):
116
+ return _merge_arrays(base, override)
117
+ return override
118
+
119
+
120
+ def extract_key(data, dotted_key: str):
121
+ parts = dotted_key.split(".")
122
+ current = data
123
+ for part in parts:
124
+ if isinstance(current, dict) and part in current:
125
+ current = current[part]
126
+ else:
127
+ return _MISSING
128
+ return current
129
+
130
+
131
+ def main():
132
+ parser = argparse.ArgumentParser(
133
+ description="Resolve Stellar Agent central config using four-layer TOML merge.",
134
+ )
135
+ parser.add_argument(
136
+ "--project-root", "-p", required=True,
137
+ help="Absolute path to the project root (contains _stellar/)",
138
+ )
139
+ parser.add_argument(
140
+ "--key", "-k", action="append", default=[],
141
+ help="Dotted field path to resolve (repeatable). Omit for full dump.",
142
+ )
143
+ args = parser.parse_args()
144
+
145
+ project_root = Path(args.project_root).resolve()
146
+ stellar_dir = project_root / "_stellar"
147
+
148
+ base_team = load_toml(stellar_dir / "config.toml", required=True)
149
+ base_user = load_toml(stellar_dir / "config.user.toml")
150
+ custom_team = load_toml(stellar_dir / "custom" / "config.toml")
151
+ custom_user = load_toml(stellar_dir / "custom" / "config.user.toml")
152
+
153
+ merged = deep_merge(base_team, base_user)
154
+ merged = deep_merge(merged, custom_team)
155
+ merged = deep_merge(merged, custom_user)
156
+
157
+ if args.key:
158
+ output = {}
159
+ for key in args.key:
160
+ value = extract_key(merged, key)
161
+ if value is not _MISSING:
162
+ output[key] = value
163
+ else:
164
+ output = merged
165
+
166
+ sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
167
+
168
+
169
+ if __name__ == "__main__":
170
+ main()
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Resolve customization for a Stellar Agent skill using three-layer TOML merge.
4
+
5
+ Reads customization from three layers (highest priority first):
6
+ 1. {project-root}/_stellar/custom/{name}.user.toml (personal, gitignored)
7
+ 2. {project-root}/_stellar/custom/{name}.toml (team/org, committed)
8
+ 3. {skill-root}/customize.toml (skill defaults)
9
+
10
+ Skill name is derived from the basename of the skill directory.
11
+
12
+ Outputs merged JSON to stdout. Errors go to stderr.
13
+
14
+ Requires Python 3.11+ (uses stdlib `tomllib`). No `uv`, no `pip install`,
15
+ no virtualenv — plain `python3` is sufficient.
16
+
17
+ python3 resolve_customization.py --skill /abs/path/to/skill-dir
18
+ python3 resolve_customization.py --skill ... --key agent
19
+ python3 resolve_customization.py --skill ... --key agent.menu
20
+
21
+ Merge rules (purely structural — no field-name special-casing):
22
+ - Scalars (string, int, bool, float): override wins
23
+ - Tables: deep merge (recursively apply these rules)
24
+ - Arrays of tables where every item shares the *same* identifier
25
+ field (every item has `code`, or every item has `id`):
26
+ merge by that key (matching keys replace, new keys append)
27
+ - All other arrays — including arrays where only some items have
28
+ `code` or `id`, or where items mix the two keys:
29
+ append (base items followed by override items)
30
+
31
+ No removal mechanism — overrides cannot delete base items.
32
+ """
33
+
34
+ import argparse
35
+ import json
36
+ import sys
37
+ from pathlib import Path
38
+
39
+ try:
40
+ import tomllib
41
+ except ImportError:
42
+ sys.stderr.write(
43
+ "error: Python 3.11+ is required (stdlib `tomllib` not found).\n"
44
+ "Install a newer Python or run the resolution manually per the\n"
45
+ "fallback instructions in the skill's SKILL.md.\n"
46
+ )
47
+ sys.exit(3)
48
+
49
+
50
+ _MISSING = object()
51
+ _KEYED_MERGE_FIELDS = ("code", "id")
52
+
53
+
54
+ def find_project_root(start: Path):
55
+ current = start.resolve()
56
+ while True:
57
+ if (current / "_stellar").exists() or (current / ".git").exists():
58
+ return current
59
+ parent = current.parent
60
+ if parent == current:
61
+ return None
62
+ current = parent
63
+
64
+
65
+ def load_toml(file_path: Path, required: bool = False) -> dict:
66
+ if not file_path.exists():
67
+ if required:
68
+ sys.stderr.write(f"error: required customization file not found: {file_path}\n")
69
+ sys.exit(1)
70
+ return {}
71
+ try:
72
+ with file_path.open("rb") as f:
73
+ parsed = tomllib.load(f)
74
+ if not isinstance(parsed, dict):
75
+ if required:
76
+ sys.stderr.write(f"error: {file_path} did not parse to a table\n")
77
+ sys.exit(1)
78
+ return {}
79
+ return parsed
80
+ except tomllib.TOMLDecodeError as error:
81
+ level = "error" if required else "warning"
82
+ sys.stderr.write(f"{level}: failed to parse {file_path}: {error}\n")
83
+ if required:
84
+ sys.exit(1)
85
+ return {}
86
+ except OSError as error:
87
+ level = "error" if required else "warning"
88
+ sys.stderr.write(f"{level}: failed to read {file_path}: {error}\n")
89
+ if required:
90
+ sys.exit(1)
91
+ return {}
92
+
93
+
94
+ def _detect_keyed_merge_field(items):
95
+ if not items or not all(isinstance(item, dict) for item in items):
96
+ return None
97
+ for candidate in _KEYED_MERGE_FIELDS:
98
+ if all(item.get(candidate) is not None for item in items):
99
+ return candidate
100
+ return None
101
+
102
+
103
+ def _merge_by_key(base, override, key_name):
104
+ result = []
105
+ index_by_key = {}
106
+
107
+ for item in base:
108
+ if not isinstance(item, dict):
109
+ continue
110
+ if item.get(key_name) is not None:
111
+ index_by_key[item[key_name]] = len(result)
112
+ result.append(dict(item))
113
+
114
+ for item in override:
115
+ if not isinstance(item, dict):
116
+ result.append(item)
117
+ continue
118
+ key = item.get(key_name)
119
+ if key is not None and key in index_by_key:
120
+ result[index_by_key[key]] = dict(item)
121
+ else:
122
+ if key is not None:
123
+ index_by_key[key] = len(result)
124
+ result.append(dict(item))
125
+
126
+ return result
127
+
128
+
129
+ def _merge_arrays(base, override):
130
+ base_arr = base if isinstance(base, list) else []
131
+ override_arr = override if isinstance(override, list) else []
132
+ keyed_field = _detect_keyed_merge_field(base_arr + override_arr)
133
+ if keyed_field:
134
+ return _merge_by_key(base_arr, override_arr, keyed_field)
135
+ return base_arr + override_arr
136
+
137
+
138
+ def deep_merge(base, override):
139
+ if isinstance(base, dict) and isinstance(override, dict):
140
+ result = dict(base)
141
+ for key, over_val in override.items():
142
+ if key in result:
143
+ result[key] = deep_merge(result[key], over_val)
144
+ else:
145
+ result[key] = over_val
146
+ return result
147
+ if isinstance(base, list) and isinstance(override, list):
148
+ return _merge_arrays(base, override)
149
+ return override
150
+
151
+
152
+ def extract_key(data, dotted_key: str):
153
+ parts = dotted_key.split(".")
154
+ current = data
155
+ for part in parts:
156
+ if isinstance(current, dict) and part in current:
157
+ current = current[part]
158
+ else:
159
+ return _MISSING
160
+ return current
161
+
162
+
163
+ def main():
164
+ parser = argparse.ArgumentParser(
165
+ description="Resolve customization for a Stellar Agent skill using three-layer TOML merge.",
166
+ add_help=True,
167
+ )
168
+ parser.add_argument(
169
+ "--skill", "-s", required=True,
170
+ help="Absolute path to the skill directory (must contain customize.toml)",
171
+ )
172
+ parser.add_argument(
173
+ "--key", "-k", action="append", default=[],
174
+ help="Dotted field path to resolve (repeatable). Omit for full dump.",
175
+ )
176
+ args = parser.parse_args()
177
+
178
+ skill_dir = Path(args.skill).resolve()
179
+ skill_name = skill_dir.name
180
+ defaults_path = skill_dir / "customize.toml"
181
+
182
+ defaults = load_toml(defaults_path, required=True)
183
+
184
+ project_root = find_project_root(skill_dir) or find_project_root(Path.cwd())
185
+
186
+ team = {}
187
+ user = {}
188
+ if project_root:
189
+ custom_dir = project_root / "_stellar" / "custom"
190
+ team = load_toml(custom_dir / f"{skill_name}.toml")
191
+ user = load_toml(custom_dir / f"{skill_name}.user.toml")
192
+
193
+ merged = deep_merge(defaults, team)
194
+ merged = deep_merge(merged, user)
195
+
196
+ if args.key:
197
+ output = {}
198
+ for key in args.key:
199
+ value = extract_key(merged, key)
200
+ if value is not _MISSING:
201
+ output[key] = value
202
+ else:
203
+ output = merged
204
+
205
+ sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
206
+
207
+
208
+ if __name__ == "__main__":
209
+ main()
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: stellar-agent-analyst
3
+ description: 'Blockchain analyst for Stellar data, tokenomics, and market research. Use when the user asks to talk to Aria or requests the blockchain analyst.'
4
+ ---
5
+
6
+ # Aria — Blockchain Analyst
7
+
8
+ ## Overview
9
+
10
+ You are Aria, the Blockchain Analyst. You ground every insight in on-chain evidence and verifiable research. You specialize in Stellar network data analytics, tokenomics design, dbt data modeling, and competitive DeFi landscape analysis.
11
+
12
+ ## Conventions
13
+
14
+ - Bare paths resolve from the skill root.
15
+ - `{skill-root}` resolves to this skill's installed directory.
16
+ - `{project-root}`-prefixed paths resolve from the project working directory.
17
+ - `{skill-name}` resolves to the skill directory's basename.
18
+
19
+ ## On Activation
20
+
21
+ ### Step 1: Resolve the Agent Block
22
+
23
+ Run: `python3 {project-root}/_stellar/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
+
25
+ **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order:
26
+ 1. `{skill-root}/customize.toml` — defaults
27
+ 2. `{project-root}/_stellar/custom/{skill-name}.toml` — team overrides
28
+ 3. `{project-root}/_stellar/custom/{skill-name}.user.toml` — personal overrides
29
+
30
+ Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, all other arrays append.
31
+
32
+ ### Step 2: Execute Prepend Steps
33
+
34
+ Execute each entry in `{agent.activation_steps_prepend}` in order.
35
+
36
+ ### Step 3: Adopt Persona
37
+
38
+ Adopt the Aria / Blockchain Analyst identity. Layer the customized persona on top: fill the additional role of `{agent.role}`, embody `{agent.identity}`, speak in the style of `{agent.communication_style}`, and follow `{agent.principles}`.
39
+
40
+ Fully embody this persona. Do not break character until the user dismisses you.
41
+
42
+ ### Step 4: Load Persistent Facts
43
+
44
+ Treat every entry in `{agent.persistent_facts}` as foundational context. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts.
45
+
46
+ ### Step 5: Load Config
47
+
48
+ Load config from `{project-root}/_stellar/stellar/config.yaml` and resolve:
49
+ - Use `{user_name}` for greeting
50
+ - Use `{communication_language}` for all communications
51
+ - Use `{document_output_language}` for output documents
52
+ - Use `{planning_artifacts}` for output location
53
+ - Use `{project_knowledge}` for additional context scanning
54
+
55
+ ### Step 6: Greet the User
56
+
57
+ Greet `{user_name}` warmly by name as Aria, speaking in `{communication_language}`. Lead with `{agent.icon}`. Remind them they can invoke `stellar-help` at any time.
58
+
59
+ Continue to prefix your messages with `{agent.icon}` throughout the session.
60
+
61
+ ### Step 7: Execute Append Steps
62
+
63
+ Execute each entry in `{agent.activation_steps_append}` in order.
64
+
65
+ ### Step 8: Dispatch or Present the Menu
66
+
67
+ If the user's initial message already names an intent that clearly maps to a menu item (e.g. "Aria, let's research the DeFi landscape"), dispatch that item directly after greeting.
68
+
69
+ Otherwise render `{agent.menu}` as a numbered table: `Code`, `Description`, `Action`. Stop and wait for input. Accept a number, menu `code`, or fuzzy description match.
70
+
71
+ From here, Aria stays active — persona, persistent facts, `{agent.icon}` prefix, and `{communication_language}` carry into every turn until the user dismisses her.
@@ -0,0 +1,41 @@
1
+ # DO NOT EDIT — overwritten on every update.
2
+ [agent]
3
+ name = "Aria"
4
+ title = "Blockchain Analyst"
5
+ icon = "📊"
6
+ activation_steps_prepend = []
7
+ activation_steps_append = []
8
+
9
+ persistent_facts = [
10
+ "file:{project-root}/**/project-context.md",
11
+ ]
12
+
13
+ role = "Conduct market research, tokenomics analysis, and dbt blockchain analytics to support data-driven Stellar dApp decisions."
14
+ identity = "Channels the rigor of a quantitative analyst and the curiosity of a blockchain explorer. Every claim traces back to verifiable on-chain data or documented research."
15
+ communication_style = "Evidence-first. States the finding, then the data that supports it. Asks clarifying questions to narrow scope before diving deep. Never speculates without flagging it as such."
16
+
17
+ principles = [
18
+ "No claim without a source.",
19
+ "On-chain data beats assumptions.",
20
+ "Tokenomics must serve users, not speculation.",
21
+ ]
22
+
23
+ [[agent.menu]]
24
+ code = "MR"
25
+ description = "Stellar market research — DeFi landscape, competitive analysis, user needs"
26
+ skill = "stellar-market-research"
27
+
28
+ [[agent.menu]]
29
+ code = "TA"
30
+ description = "Tokenomics analysis — token distribution, incentive modeling, economic design"
31
+ skill = "stellar-tokenomics-analysis"
32
+
33
+ [[agent.menu]]
34
+ code = "AN"
35
+ description = "dbt analytics — blockchain data modeling, Horizon data queries, reporting"
36
+ skill = "stellar-analytics"
37
+
38
+ [[agent.menu]]
39
+ code = "DR"
40
+ description = "Research Stellar domain — protocol specifics, regulatory landscape, use cases"
41
+ skill = "stellar-domain-research"