opencode-athena 0.2.0 → 0.4.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.
- package/README.md +185 -4
- package/commands/athena-debug.md +38 -0
- package/commands/athena-dev.md +38 -0
- package/commands/athena-parallel.md +17 -0
- package/commands/athena-research.md +17 -0
- package/commands/athena-review.md +38 -0
- package/commands/athena-status.md +17 -0
- package/config/presets/copilot-only.json +38 -0
- package/config/presets/enterprise.json +11 -2
- package/config/presets/minimal.json +8 -2
- package/config/presets/solo-quick.json +8 -2
- package/config/presets/standard.json +11 -2
- package/config/schemas/athena.schema.json +94 -3
- package/dist/cli/index.js +283 -22
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +434 -4
- package/dist/index.js +208 -11
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +208 -11
- package/dist/plugin/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -71,19 +71,66 @@ function handleSessionError(event, tracker) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// src/plugin/hooks/tool-hooks.ts
|
|
74
|
-
|
|
74
|
+
var GIT_WRITE_COMMANDS = [
|
|
75
|
+
"git commit",
|
|
76
|
+
"git push",
|
|
77
|
+
"git checkout -b",
|
|
78
|
+
"git branch ",
|
|
79
|
+
"git switch -c",
|
|
80
|
+
"git switch --create",
|
|
81
|
+
"git merge",
|
|
82
|
+
"git rebase",
|
|
83
|
+
"git cherry-pick",
|
|
84
|
+
"git stash",
|
|
85
|
+
"git tag",
|
|
86
|
+
"git reset",
|
|
87
|
+
"gh pr create",
|
|
88
|
+
"gh pr edit",
|
|
89
|
+
"gh pr merge",
|
|
90
|
+
"gh pr close",
|
|
91
|
+
"gh pr review",
|
|
92
|
+
"gh issue create",
|
|
93
|
+
"gh issue edit",
|
|
94
|
+
"gh issue close",
|
|
95
|
+
"gh release create",
|
|
96
|
+
"gh release edit",
|
|
97
|
+
"gh release delete"
|
|
98
|
+
];
|
|
99
|
+
function getBashCommand(metadata) {
|
|
100
|
+
if (!metadata || typeof metadata !== "object") {
|
|
101
|
+
return "";
|
|
102
|
+
}
|
|
103
|
+
const cmd = metadata.command;
|
|
104
|
+
return typeof cmd === "string" ? cmd : "";
|
|
105
|
+
}
|
|
106
|
+
function containsGitWriteCommand(command) {
|
|
107
|
+
const normalized = command.trim().toLowerCase();
|
|
108
|
+
const segments = normalized.split(/[;&|]+/).map((s) => s.trim());
|
|
109
|
+
return segments.some(
|
|
110
|
+
(segment) => GIT_WRITE_COMMANDS.some((gitCmd) => segment.startsWith(gitCmd.toLowerCase()))
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
function createToolHooks(_tracker, config) {
|
|
75
114
|
return {
|
|
76
115
|
/**
|
|
77
116
|
* Called before a tool executes
|
|
78
|
-
* Can modify args or throw to block execution
|
|
79
117
|
*/
|
|
80
118
|
before: async (_input, _output) => {
|
|
119
|
+
return;
|
|
81
120
|
},
|
|
82
121
|
/**
|
|
83
122
|
* Called after a tool executes
|
|
84
|
-
* Can modify output or append messages
|
|
85
123
|
*/
|
|
86
|
-
after: async (
|
|
124
|
+
after: async (input, output) => {
|
|
125
|
+
if (config.features.autoGitOperations) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (input.tool === "bash") {
|
|
129
|
+
const command = getBashCommand(output.metadata);
|
|
130
|
+
if (containsGitWriteCommand(command)) {
|
|
131
|
+
output.output += "\n\n\u26A0\uFE0F ATHENA GIT OPERATIONS POLICY REMINDER:\nGit operations should only be performed when explicitly requested by the user.\nIf this command was run automatically (not requested by the user), please:\n1. Ask the user before proceeding with further git operations\n2. Use athena_update_status() to track story progress instead of git commits\n\nTo enable automatic git operations, set features.autoGitOperations=true in athena.json";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
87
134
|
}
|
|
88
135
|
};
|
|
89
136
|
}
|
|
@@ -152,7 +199,8 @@ var DEFAULTS = {
|
|
|
152
199
|
notifications: true,
|
|
153
200
|
contextMonitor: true,
|
|
154
201
|
commentChecker: true,
|
|
155
|
-
lspTools: true
|
|
202
|
+
lspTools: true,
|
|
203
|
+
autoGitOperations: false
|
|
156
204
|
},
|
|
157
205
|
/** Default MCPs enabled */
|
|
158
206
|
mcps: {
|
|
@@ -1379,6 +1427,11 @@ var SubscriptionSchema = z.object({
|
|
|
1379
1427
|
google: z.object({
|
|
1380
1428
|
enabled: z.boolean(),
|
|
1381
1429
|
authMethod: z.enum(["antigravity", "personal", "api", "none"])
|
|
1430
|
+
}),
|
|
1431
|
+
githubCopilot: z.object({
|
|
1432
|
+
enabled: z.boolean(),
|
|
1433
|
+
plan: z.enum(["free", "pro", "pro-plus", "business", "enterprise", "none"]),
|
|
1434
|
+
enabledModels: z.array(z.string()).optional()
|
|
1382
1435
|
})
|
|
1383
1436
|
});
|
|
1384
1437
|
var BmadConfigSchema = z.object({
|
|
@@ -1393,20 +1446,47 @@ var FeaturesSchema = z.object({
|
|
|
1393
1446
|
notifications: z.boolean(),
|
|
1394
1447
|
contextMonitor: z.boolean(),
|
|
1395
1448
|
commentChecker: z.boolean(),
|
|
1396
|
-
lspTools: z.boolean()
|
|
1449
|
+
lspTools: z.boolean(),
|
|
1450
|
+
autoGitOperations: z.boolean().default(false)
|
|
1397
1451
|
});
|
|
1398
1452
|
var McpsSchema = z.object({
|
|
1399
1453
|
context7: z.boolean(),
|
|
1400
1454
|
exa: z.boolean(),
|
|
1401
1455
|
grepApp: z.boolean()
|
|
1402
1456
|
});
|
|
1457
|
+
var ThinkingLevelSchema = z.enum(["off", "low", "medium", "high"]);
|
|
1458
|
+
var AgentSettingsSchema = z.object({
|
|
1459
|
+
temperature: z.number().min(0).max(1).optional(),
|
|
1460
|
+
thinkingLevel: ThinkingLevelSchema.optional()
|
|
1461
|
+
});
|
|
1462
|
+
var CustomModelDefinitionSchema = z.object({
|
|
1463
|
+
id: z.string(),
|
|
1464
|
+
name: z.string(),
|
|
1465
|
+
provider: z.enum(["anthropic", "openai", "google", "github-copilot"]),
|
|
1466
|
+
description: z.string().optional(),
|
|
1467
|
+
capabilities: z.object({
|
|
1468
|
+
thinking: z.boolean().optional(),
|
|
1469
|
+
contextWindow: z.number().optional(),
|
|
1470
|
+
supportsTemperature: z.boolean().optional()
|
|
1471
|
+
}).optional()
|
|
1472
|
+
});
|
|
1403
1473
|
var ModelsSchema = z.object({
|
|
1404
1474
|
sisyphus: z.string().describe("Model for main orchestrator agent"),
|
|
1405
1475
|
oracle: z.string().describe("Model for debugging/reasoning agent"),
|
|
1406
1476
|
librarian: z.string().describe("Model for research/documentation agent"),
|
|
1407
1477
|
frontend: z.string().optional().describe("Model for UI/UX agent"),
|
|
1408
1478
|
documentWriter: z.string().optional().describe("Model for documentation generation agent"),
|
|
1409
|
-
multimodalLooker: z.string().optional().describe("Model for image analysis agent")
|
|
1479
|
+
multimodalLooker: z.string().optional().describe("Model for image analysis agent"),
|
|
1480
|
+
settings: z.object({
|
|
1481
|
+
sisyphus: AgentSettingsSchema.optional(),
|
|
1482
|
+
oracle: AgentSettingsSchema.optional(),
|
|
1483
|
+
librarian: AgentSettingsSchema.optional(),
|
|
1484
|
+
frontend: AgentSettingsSchema.optional(),
|
|
1485
|
+
documentWriter: AgentSettingsSchema.optional(),
|
|
1486
|
+
multimodalLooker: AgentSettingsSchema.optional(),
|
|
1487
|
+
overrides: z.record(z.string(), AgentSettingsSchema).optional()
|
|
1488
|
+
}).optional(),
|
|
1489
|
+
custom: z.array(CustomModelDefinitionSchema).optional()
|
|
1410
1490
|
});
|
|
1411
1491
|
var AthenaConfigSchema = z.object({
|
|
1412
1492
|
$schema: z.string().optional(),
|
|
@@ -1538,22 +1618,37 @@ function validatePartialConfig(config, filePath) {
|
|
|
1538
1618
|
authMethod: isValidAuthMethod(google.authMethod) ? google.authMethod : "none"
|
|
1539
1619
|
};
|
|
1540
1620
|
}
|
|
1621
|
+
if (subs.githubCopilot && typeof subs.githubCopilot === "object") {
|
|
1622
|
+
const copilot = subs.githubCopilot;
|
|
1623
|
+
result.subscriptions.githubCopilot = {
|
|
1624
|
+
enabled: typeof copilot.enabled === "boolean" ? copilot.enabled : false,
|
|
1625
|
+
plan: isValidCopilotPlan(copilot.plan) ? copilot.plan : "none",
|
|
1626
|
+
enabledModels: Array.isArray(copilot.enabledModels) ? copilot.enabledModels.filter((m) => typeof m === "string") : void 0
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1541
1629
|
}
|
|
1542
1630
|
if ("models" in configObj && typeof configObj.models === "object") {
|
|
1543
1631
|
const models = configObj.models;
|
|
1544
1632
|
result.models = {};
|
|
1545
|
-
|
|
1633
|
+
const modelKeys = [
|
|
1546
1634
|
"sisyphus",
|
|
1547
1635
|
"oracle",
|
|
1548
1636
|
"librarian",
|
|
1549
1637
|
"frontend",
|
|
1550
1638
|
"documentWriter",
|
|
1551
1639
|
"multimodalLooker"
|
|
1552
|
-
]
|
|
1640
|
+
];
|
|
1641
|
+
for (const key of modelKeys) {
|
|
1553
1642
|
if (key in models && typeof models[key] === "string") {
|
|
1554
1643
|
result.models[key] = models[key];
|
|
1555
1644
|
}
|
|
1556
1645
|
}
|
|
1646
|
+
if ("settings" in models && typeof models.settings === "object" && models.settings !== null) {
|
|
1647
|
+
result.models.settings = validateModelSettings(models.settings);
|
|
1648
|
+
}
|
|
1649
|
+
if ("custom" in models && Array.isArray(models.custom)) {
|
|
1650
|
+
result.models.custom = validateCustomModels(models.custom);
|
|
1651
|
+
}
|
|
1557
1652
|
}
|
|
1558
1653
|
if ("bmad" in configObj && typeof configObj.bmad === "object") {
|
|
1559
1654
|
const bmad = configObj.bmad;
|
|
@@ -1602,9 +1697,104 @@ function isValidTier(value) {
|
|
|
1602
1697
|
function isValidAuthMethod(value) {
|
|
1603
1698
|
return typeof value === "string" && ["antigravity", "personal", "api", "none"].includes(value);
|
|
1604
1699
|
}
|
|
1700
|
+
function isValidCopilotPlan(value) {
|
|
1701
|
+
return typeof value === "string" && ["free", "pro", "pro-plus", "business", "enterprise", "none"].includes(value);
|
|
1702
|
+
}
|
|
1605
1703
|
function isValidTrack(value) {
|
|
1606
1704
|
return typeof value === "string" && ["quick-flow", "bmad-method", "enterprise"].includes(value);
|
|
1607
1705
|
}
|
|
1706
|
+
function isValidThinkingLevel(value) {
|
|
1707
|
+
return typeof value === "string" && ["off", "low", "medium", "high"].includes(value);
|
|
1708
|
+
}
|
|
1709
|
+
function isValidProvider(value) {
|
|
1710
|
+
return typeof value === "string" && ["anthropic", "openai", "google", "github-copilot"].includes(value);
|
|
1711
|
+
}
|
|
1712
|
+
function validateAgentSettings(settings) {
|
|
1713
|
+
if (typeof settings !== "object" || settings === null) {
|
|
1714
|
+
return void 0;
|
|
1715
|
+
}
|
|
1716
|
+
const result = {};
|
|
1717
|
+
const settingsObj = settings;
|
|
1718
|
+
const agentKeys = [
|
|
1719
|
+
"sisyphus",
|
|
1720
|
+
"oracle",
|
|
1721
|
+
"librarian",
|
|
1722
|
+
"frontend",
|
|
1723
|
+
"documentWriter",
|
|
1724
|
+
"multimodalLooker"
|
|
1725
|
+
];
|
|
1726
|
+
for (const key of agentKeys) {
|
|
1727
|
+
if (key in settingsObj && typeof settingsObj[key] === "object" && settingsObj[key] !== null) {
|
|
1728
|
+
const agentSetting = settingsObj[key];
|
|
1729
|
+
const validated = {};
|
|
1730
|
+
if (typeof agentSetting.temperature === "number" && agentSetting.temperature >= 0 && agentSetting.temperature <= 2) {
|
|
1731
|
+
validated.temperature = agentSetting.temperature;
|
|
1732
|
+
}
|
|
1733
|
+
if (isValidThinkingLevel(agentSetting.thinkingLevel)) {
|
|
1734
|
+
validated.thinkingLevel = agentSetting.thinkingLevel;
|
|
1735
|
+
}
|
|
1736
|
+
if (Object.keys(validated).length > 0) {
|
|
1737
|
+
result[key] = validated;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
if ("overrides" in settingsObj && typeof settingsObj.overrides === "object" && settingsObj.overrides !== null) {
|
|
1742
|
+
const overrides = settingsObj.overrides;
|
|
1743
|
+
result.overrides = {};
|
|
1744
|
+
for (const [modelId, modelSettings] of Object.entries(overrides)) {
|
|
1745
|
+
if (typeof modelSettings === "object" && modelSettings !== null) {
|
|
1746
|
+
const ms = modelSettings;
|
|
1747
|
+
const validated = {};
|
|
1748
|
+
if (typeof ms.temperature === "number" && ms.temperature >= 0 && ms.temperature <= 2) {
|
|
1749
|
+
validated.temperature = ms.temperature;
|
|
1750
|
+
}
|
|
1751
|
+
if (isValidThinkingLevel(ms.thinkingLevel)) {
|
|
1752
|
+
validated.thinkingLevel = ms.thinkingLevel;
|
|
1753
|
+
}
|
|
1754
|
+
if (Object.keys(validated).length > 0) {
|
|
1755
|
+
result.overrides[modelId] = validated;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
1761
|
+
}
|
|
1762
|
+
function validateModelSettings(settings) {
|
|
1763
|
+
return validateAgentSettings(settings);
|
|
1764
|
+
}
|
|
1765
|
+
function validateCustomModels(models) {
|
|
1766
|
+
const validated = [];
|
|
1767
|
+
for (const model of models) {
|
|
1768
|
+
if (typeof model !== "object" || model === null) continue;
|
|
1769
|
+
const m = model;
|
|
1770
|
+
if (typeof m.id !== "string" || typeof m.name !== "string" || !isValidProvider(m.provider)) {
|
|
1771
|
+
continue;
|
|
1772
|
+
}
|
|
1773
|
+
const customModel = {
|
|
1774
|
+
id: m.id,
|
|
1775
|
+
name: m.name,
|
|
1776
|
+
provider: m.provider
|
|
1777
|
+
};
|
|
1778
|
+
if (typeof m.description === "string") {
|
|
1779
|
+
customModel.description = m.description;
|
|
1780
|
+
}
|
|
1781
|
+
if (typeof m.capabilities === "object" && m.capabilities !== null) {
|
|
1782
|
+
const caps = m.capabilities;
|
|
1783
|
+
customModel.capabilities = {};
|
|
1784
|
+
if (typeof caps.thinking === "boolean") {
|
|
1785
|
+
customModel.capabilities.thinking = caps.thinking;
|
|
1786
|
+
}
|
|
1787
|
+
if (typeof caps.contextWindow === "number") {
|
|
1788
|
+
customModel.capabilities.contextWindow = caps.contextWindow;
|
|
1789
|
+
}
|
|
1790
|
+
if (typeof caps.supportsTemperature === "boolean") {
|
|
1791
|
+
customModel.capabilities.supportsTemperature = caps.supportsTemperature;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
validated.push(customModel);
|
|
1795
|
+
}
|
|
1796
|
+
return validated.length > 0 ? validated : void 0;
|
|
1797
|
+
}
|
|
1608
1798
|
function validateConfig(config) {
|
|
1609
1799
|
const result = AthenaConfigSchema.safeParse(config);
|
|
1610
1800
|
if (!result.success) {
|
|
@@ -1622,7 +1812,8 @@ function getDefaultConfig() {
|
|
|
1622
1812
|
subscriptions: {
|
|
1623
1813
|
claude: { enabled: false, tier: "none" },
|
|
1624
1814
|
openai: { enabled: false },
|
|
1625
|
-
google: { enabled: false, authMethod: "none" }
|
|
1815
|
+
google: { enabled: false, authMethod: "none" },
|
|
1816
|
+
githubCopilot: { enabled: false, plan: "none" }
|
|
1626
1817
|
},
|
|
1627
1818
|
models: {
|
|
1628
1819
|
sisyphus: "anthropic/claude-sonnet-4",
|
|
@@ -1662,6 +1853,12 @@ function mergeConfigs(...configs) {
|
|
|
1662
1853
|
...config.subscriptions.google
|
|
1663
1854
|
};
|
|
1664
1855
|
}
|
|
1856
|
+
if (config.subscriptions.githubCopilot) {
|
|
1857
|
+
result.subscriptions.githubCopilot = {
|
|
1858
|
+
...result.subscriptions.githubCopilot,
|
|
1859
|
+
...config.subscriptions.githubCopilot
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1665
1862
|
}
|
|
1666
1863
|
if (config.models) {
|
|
1667
1864
|
result.models = { ...result.models, ...config.models };
|
|
@@ -1687,7 +1884,7 @@ var OpenCodeAthena = async (ctx) => {
|
|
|
1687
1884
|
await tracker.initialize();
|
|
1688
1885
|
const tools = createTools(ctx, tracker, config);
|
|
1689
1886
|
const sessionHooks = createSessionHooks(ctx, tracker, config);
|
|
1690
|
-
const toolHooks = createToolHooks();
|
|
1887
|
+
const toolHooks = createToolHooks(tracker, config);
|
|
1691
1888
|
const compactionHook = createCompactionHook(tracker);
|
|
1692
1889
|
return {
|
|
1693
1890
|
// Custom tools for BMAD integration
|