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/plugin/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
|
}
|
|
@@ -134,7 +181,8 @@ var DEFAULTS = {
|
|
|
134
181
|
notifications: true,
|
|
135
182
|
contextMonitor: true,
|
|
136
183
|
commentChecker: true,
|
|
137
|
-
lspTools: true
|
|
184
|
+
lspTools: true,
|
|
185
|
+
autoGitOperations: false
|
|
138
186
|
},
|
|
139
187
|
/** Default MCPs enabled */
|
|
140
188
|
mcps: {
|
|
@@ -1361,6 +1409,11 @@ var SubscriptionSchema = z.object({
|
|
|
1361
1409
|
google: z.object({
|
|
1362
1410
|
enabled: z.boolean(),
|
|
1363
1411
|
authMethod: z.enum(["antigravity", "personal", "api", "none"])
|
|
1412
|
+
}),
|
|
1413
|
+
githubCopilot: z.object({
|
|
1414
|
+
enabled: z.boolean(),
|
|
1415
|
+
plan: z.enum(["free", "pro", "pro-plus", "business", "enterprise", "none"]),
|
|
1416
|
+
enabledModels: z.array(z.string()).optional()
|
|
1364
1417
|
})
|
|
1365
1418
|
});
|
|
1366
1419
|
var BmadConfigSchema = z.object({
|
|
@@ -1375,20 +1428,47 @@ var FeaturesSchema = z.object({
|
|
|
1375
1428
|
notifications: z.boolean(),
|
|
1376
1429
|
contextMonitor: z.boolean(),
|
|
1377
1430
|
commentChecker: z.boolean(),
|
|
1378
|
-
lspTools: z.boolean()
|
|
1431
|
+
lspTools: z.boolean(),
|
|
1432
|
+
autoGitOperations: z.boolean().default(false)
|
|
1379
1433
|
});
|
|
1380
1434
|
var McpsSchema = z.object({
|
|
1381
1435
|
context7: z.boolean(),
|
|
1382
1436
|
exa: z.boolean(),
|
|
1383
1437
|
grepApp: z.boolean()
|
|
1384
1438
|
});
|
|
1439
|
+
var ThinkingLevelSchema = z.enum(["off", "low", "medium", "high"]);
|
|
1440
|
+
var AgentSettingsSchema = z.object({
|
|
1441
|
+
temperature: z.number().min(0).max(1).optional(),
|
|
1442
|
+
thinkingLevel: ThinkingLevelSchema.optional()
|
|
1443
|
+
});
|
|
1444
|
+
var CustomModelDefinitionSchema = z.object({
|
|
1445
|
+
id: z.string(),
|
|
1446
|
+
name: z.string(),
|
|
1447
|
+
provider: z.enum(["anthropic", "openai", "google", "github-copilot"]),
|
|
1448
|
+
description: z.string().optional(),
|
|
1449
|
+
capabilities: z.object({
|
|
1450
|
+
thinking: z.boolean().optional(),
|
|
1451
|
+
contextWindow: z.number().optional(),
|
|
1452
|
+
supportsTemperature: z.boolean().optional()
|
|
1453
|
+
}).optional()
|
|
1454
|
+
});
|
|
1385
1455
|
var ModelsSchema = z.object({
|
|
1386
1456
|
sisyphus: z.string().describe("Model for main orchestrator agent"),
|
|
1387
1457
|
oracle: z.string().describe("Model for debugging/reasoning agent"),
|
|
1388
1458
|
librarian: z.string().describe("Model for research/documentation agent"),
|
|
1389
1459
|
frontend: z.string().optional().describe("Model for UI/UX agent"),
|
|
1390
1460
|
documentWriter: z.string().optional().describe("Model for documentation generation agent"),
|
|
1391
|
-
multimodalLooker: z.string().optional().describe("Model for image analysis agent")
|
|
1461
|
+
multimodalLooker: z.string().optional().describe("Model for image analysis agent"),
|
|
1462
|
+
settings: z.object({
|
|
1463
|
+
sisyphus: AgentSettingsSchema.optional(),
|
|
1464
|
+
oracle: AgentSettingsSchema.optional(),
|
|
1465
|
+
librarian: AgentSettingsSchema.optional(),
|
|
1466
|
+
frontend: AgentSettingsSchema.optional(),
|
|
1467
|
+
documentWriter: AgentSettingsSchema.optional(),
|
|
1468
|
+
multimodalLooker: AgentSettingsSchema.optional(),
|
|
1469
|
+
overrides: z.record(z.string(), AgentSettingsSchema).optional()
|
|
1470
|
+
}).optional(),
|
|
1471
|
+
custom: z.array(CustomModelDefinitionSchema).optional()
|
|
1392
1472
|
});
|
|
1393
1473
|
var AthenaConfigSchema = z.object({
|
|
1394
1474
|
$schema: z.string().optional(),
|
|
@@ -1520,22 +1600,37 @@ function validatePartialConfig(config, filePath) {
|
|
|
1520
1600
|
authMethod: isValidAuthMethod(google.authMethod) ? google.authMethod : "none"
|
|
1521
1601
|
};
|
|
1522
1602
|
}
|
|
1603
|
+
if (subs.githubCopilot && typeof subs.githubCopilot === "object") {
|
|
1604
|
+
const copilot = subs.githubCopilot;
|
|
1605
|
+
result.subscriptions.githubCopilot = {
|
|
1606
|
+
enabled: typeof copilot.enabled === "boolean" ? copilot.enabled : false,
|
|
1607
|
+
plan: isValidCopilotPlan(copilot.plan) ? copilot.plan : "none",
|
|
1608
|
+
enabledModels: Array.isArray(copilot.enabledModels) ? copilot.enabledModels.filter((m) => typeof m === "string") : void 0
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1523
1611
|
}
|
|
1524
1612
|
if ("models" in configObj && typeof configObj.models === "object") {
|
|
1525
1613
|
const models = configObj.models;
|
|
1526
1614
|
result.models = {};
|
|
1527
|
-
|
|
1615
|
+
const modelKeys = [
|
|
1528
1616
|
"sisyphus",
|
|
1529
1617
|
"oracle",
|
|
1530
1618
|
"librarian",
|
|
1531
1619
|
"frontend",
|
|
1532
1620
|
"documentWriter",
|
|
1533
1621
|
"multimodalLooker"
|
|
1534
|
-
]
|
|
1622
|
+
];
|
|
1623
|
+
for (const key of modelKeys) {
|
|
1535
1624
|
if (key in models && typeof models[key] === "string") {
|
|
1536
1625
|
result.models[key] = models[key];
|
|
1537
1626
|
}
|
|
1538
1627
|
}
|
|
1628
|
+
if ("settings" in models && typeof models.settings === "object" && models.settings !== null) {
|
|
1629
|
+
result.models.settings = validateModelSettings(models.settings);
|
|
1630
|
+
}
|
|
1631
|
+
if ("custom" in models && Array.isArray(models.custom)) {
|
|
1632
|
+
result.models.custom = validateCustomModels(models.custom);
|
|
1633
|
+
}
|
|
1539
1634
|
}
|
|
1540
1635
|
if ("bmad" in configObj && typeof configObj.bmad === "object") {
|
|
1541
1636
|
const bmad = configObj.bmad;
|
|
@@ -1584,9 +1679,104 @@ function isValidTier(value) {
|
|
|
1584
1679
|
function isValidAuthMethod(value) {
|
|
1585
1680
|
return typeof value === "string" && ["antigravity", "personal", "api", "none"].includes(value);
|
|
1586
1681
|
}
|
|
1682
|
+
function isValidCopilotPlan(value) {
|
|
1683
|
+
return typeof value === "string" && ["free", "pro", "pro-plus", "business", "enterprise", "none"].includes(value);
|
|
1684
|
+
}
|
|
1587
1685
|
function isValidTrack(value) {
|
|
1588
1686
|
return typeof value === "string" && ["quick-flow", "bmad-method", "enterprise"].includes(value);
|
|
1589
1687
|
}
|
|
1688
|
+
function isValidThinkingLevel(value) {
|
|
1689
|
+
return typeof value === "string" && ["off", "low", "medium", "high"].includes(value);
|
|
1690
|
+
}
|
|
1691
|
+
function isValidProvider(value) {
|
|
1692
|
+
return typeof value === "string" && ["anthropic", "openai", "google", "github-copilot"].includes(value);
|
|
1693
|
+
}
|
|
1694
|
+
function validateAgentSettings(settings) {
|
|
1695
|
+
if (typeof settings !== "object" || settings === null) {
|
|
1696
|
+
return void 0;
|
|
1697
|
+
}
|
|
1698
|
+
const result = {};
|
|
1699
|
+
const settingsObj = settings;
|
|
1700
|
+
const agentKeys = [
|
|
1701
|
+
"sisyphus",
|
|
1702
|
+
"oracle",
|
|
1703
|
+
"librarian",
|
|
1704
|
+
"frontend",
|
|
1705
|
+
"documentWriter",
|
|
1706
|
+
"multimodalLooker"
|
|
1707
|
+
];
|
|
1708
|
+
for (const key of agentKeys) {
|
|
1709
|
+
if (key in settingsObj && typeof settingsObj[key] === "object" && settingsObj[key] !== null) {
|
|
1710
|
+
const agentSetting = settingsObj[key];
|
|
1711
|
+
const validated = {};
|
|
1712
|
+
if (typeof agentSetting.temperature === "number" && agentSetting.temperature >= 0 && agentSetting.temperature <= 2) {
|
|
1713
|
+
validated.temperature = agentSetting.temperature;
|
|
1714
|
+
}
|
|
1715
|
+
if (isValidThinkingLevel(agentSetting.thinkingLevel)) {
|
|
1716
|
+
validated.thinkingLevel = agentSetting.thinkingLevel;
|
|
1717
|
+
}
|
|
1718
|
+
if (Object.keys(validated).length > 0) {
|
|
1719
|
+
result[key] = validated;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
if ("overrides" in settingsObj && typeof settingsObj.overrides === "object" && settingsObj.overrides !== null) {
|
|
1724
|
+
const overrides = settingsObj.overrides;
|
|
1725
|
+
result.overrides = {};
|
|
1726
|
+
for (const [modelId, modelSettings] of Object.entries(overrides)) {
|
|
1727
|
+
if (typeof modelSettings === "object" && modelSettings !== null) {
|
|
1728
|
+
const ms = modelSettings;
|
|
1729
|
+
const validated = {};
|
|
1730
|
+
if (typeof ms.temperature === "number" && ms.temperature >= 0 && ms.temperature <= 2) {
|
|
1731
|
+
validated.temperature = ms.temperature;
|
|
1732
|
+
}
|
|
1733
|
+
if (isValidThinkingLevel(ms.thinkingLevel)) {
|
|
1734
|
+
validated.thinkingLevel = ms.thinkingLevel;
|
|
1735
|
+
}
|
|
1736
|
+
if (Object.keys(validated).length > 0) {
|
|
1737
|
+
result.overrides[modelId] = validated;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
1743
|
+
}
|
|
1744
|
+
function validateModelSettings(settings) {
|
|
1745
|
+
return validateAgentSettings(settings);
|
|
1746
|
+
}
|
|
1747
|
+
function validateCustomModels(models) {
|
|
1748
|
+
const validated = [];
|
|
1749
|
+
for (const model of models) {
|
|
1750
|
+
if (typeof model !== "object" || model === null) continue;
|
|
1751
|
+
const m = model;
|
|
1752
|
+
if (typeof m.id !== "string" || typeof m.name !== "string" || !isValidProvider(m.provider)) {
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
const customModel = {
|
|
1756
|
+
id: m.id,
|
|
1757
|
+
name: m.name,
|
|
1758
|
+
provider: m.provider
|
|
1759
|
+
};
|
|
1760
|
+
if (typeof m.description === "string") {
|
|
1761
|
+
customModel.description = m.description;
|
|
1762
|
+
}
|
|
1763
|
+
if (typeof m.capabilities === "object" && m.capabilities !== null) {
|
|
1764
|
+
const caps = m.capabilities;
|
|
1765
|
+
customModel.capabilities = {};
|
|
1766
|
+
if (typeof caps.thinking === "boolean") {
|
|
1767
|
+
customModel.capabilities.thinking = caps.thinking;
|
|
1768
|
+
}
|
|
1769
|
+
if (typeof caps.contextWindow === "number") {
|
|
1770
|
+
customModel.capabilities.contextWindow = caps.contextWindow;
|
|
1771
|
+
}
|
|
1772
|
+
if (typeof caps.supportsTemperature === "boolean") {
|
|
1773
|
+
customModel.capabilities.supportsTemperature = caps.supportsTemperature;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
validated.push(customModel);
|
|
1777
|
+
}
|
|
1778
|
+
return validated.length > 0 ? validated : void 0;
|
|
1779
|
+
}
|
|
1590
1780
|
function validateConfig(config) {
|
|
1591
1781
|
const result = AthenaConfigSchema.safeParse(config);
|
|
1592
1782
|
if (!result.success) {
|
|
@@ -1604,7 +1794,8 @@ function getDefaultConfig() {
|
|
|
1604
1794
|
subscriptions: {
|
|
1605
1795
|
claude: { enabled: false, tier: "none" },
|
|
1606
1796
|
openai: { enabled: false },
|
|
1607
|
-
google: { enabled: false, authMethod: "none" }
|
|
1797
|
+
google: { enabled: false, authMethod: "none" },
|
|
1798
|
+
githubCopilot: { enabled: false, plan: "none" }
|
|
1608
1799
|
},
|
|
1609
1800
|
models: {
|
|
1610
1801
|
sisyphus: "anthropic/claude-sonnet-4",
|
|
@@ -1644,6 +1835,12 @@ function mergeConfigs(...configs) {
|
|
|
1644
1835
|
...config.subscriptions.google
|
|
1645
1836
|
};
|
|
1646
1837
|
}
|
|
1838
|
+
if (config.subscriptions.githubCopilot) {
|
|
1839
|
+
result.subscriptions.githubCopilot = {
|
|
1840
|
+
...result.subscriptions.githubCopilot,
|
|
1841
|
+
...config.subscriptions.githubCopilot
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1647
1844
|
}
|
|
1648
1845
|
if (config.models) {
|
|
1649
1846
|
result.models = { ...result.models, ...config.models };
|
|
@@ -1669,7 +1866,7 @@ var OpenCodeAthena = async (ctx) => {
|
|
|
1669
1866
|
await tracker.initialize();
|
|
1670
1867
|
const tools = createTools(ctx, tracker, config);
|
|
1671
1868
|
const sessionHooks = createSessionHooks(ctx, tracker, config);
|
|
1672
|
-
const toolHooks = createToolHooks();
|
|
1869
|
+
const toolHooks = createToolHooks(tracker, config);
|
|
1673
1870
|
const compactionHook = createCompactionHook(tracker);
|
|
1674
1871
|
return {
|
|
1675
1872
|
// Custom tools for BMAD integration
|