@deimoscloud/coreai 0.1.16 → 0.1.18
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/agents/_templates/master-context.md +76 -0
- package/agents/_templates/master-protocols.md +39 -0
- package/agents/android-engineer.md +3 -115
- package/agents/backend-engineer.md +3 -115
- package/agents/database-administrator.md +3 -115
- package/agents/devops-engineer.md +3 -115
- package/agents/frontend-engineer.md +3 -115
- package/agents/react-engineer.md +3 -115
- package/agents/react-native-engineer.md +3 -115
- package/agents/software-security-engineer.md +3 -115
- package/agents/sre-huawei-cloud-architect.md +3 -115
- package/agents/sre-iac-specialist.md +3 -115
- package/agents/sre-kubernetes-specialist.md +3 -115
- package/agents/sre-network-specialist.md +3 -115
- package/agents/wearos-engineer.md +3 -115
- package/dist/cli/index.js +209 -616
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +35 -30
- package/dist/index.js +173 -590
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/skills/core/check-inbox/SKILL.md +37 -0
- package/skills/core/delegate/SKILL.md +61 -0
- package/skills/core/review/SKILL.md +57 -0
package/dist/cli/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { join as join14, dirname as
|
|
4
|
+
import { join as join14, dirname as dirname8 } from "path";
|
|
5
5
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { readFileSync as readFileSync7 } from "fs";
|
|
10
|
-
import { dirname as
|
|
10
|
+
import { dirname as dirname6, join as join8 } from "path";
|
|
11
11
|
import { fileURLToPath } from "url";
|
|
12
12
|
|
|
13
13
|
// src/config/loader.ts
|
|
@@ -442,7 +442,7 @@ function resolveAgentDefinition(agent, config, options = {}) {
|
|
|
442
442
|
|
|
443
443
|
// src/agents/compiler.ts
|
|
444
444
|
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
445
|
-
import { join as join3, dirname as dirname2, extname as extname2 } from "path";
|
|
445
|
+
import { join as join3, dirname as dirname2, extname as extname2, isAbsolute } from "path";
|
|
446
446
|
import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
|
|
447
447
|
function buildAgentTools(agent, mcpServers) {
|
|
448
448
|
const tools = agent.tools ? [...agent.tools] : [...DEFAULT_AGENT_TOOLS];
|
|
@@ -456,16 +456,44 @@ function buildAgentTools(agent, mcpServers) {
|
|
|
456
456
|
}
|
|
457
457
|
return tools.join(", ");
|
|
458
458
|
}
|
|
459
|
+
function processIncludes(template, templateDir, depth = 0, maxDepth = 3) {
|
|
460
|
+
if (depth > maxDepth) {
|
|
461
|
+
throw new Error(`Include depth exceeded maximum of ${maxDepth}`);
|
|
462
|
+
}
|
|
463
|
+
const includePattern = /<!--\s*include:\s*(\S+)\s*-->/g;
|
|
464
|
+
return template.replace(includePattern, (_match, includePath) => {
|
|
465
|
+
const resolvedPath = isAbsolute(includePath) ? includePath : join3(templateDir, includePath);
|
|
466
|
+
if (!existsSync3(resolvedPath)) {
|
|
467
|
+
throw new Error(`Include file not found: ${includePath} (resolved to ${resolvedPath})`);
|
|
468
|
+
}
|
|
469
|
+
const includedContent = readFileSync3(resolvedPath, "utf-8");
|
|
470
|
+
return processIncludes(includedContent, dirname2(resolvedPath), depth + 1, maxDepth);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
459
473
|
function processAgentTemplate(templatePath, agent, config, mcpServers) {
|
|
460
474
|
const template = readFileSync3(templatePath, "utf-8");
|
|
461
|
-
const
|
|
475
|
+
const templateDir = dirname2(templatePath);
|
|
476
|
+
const expandedTemplate = processIncludes(template, templateDir);
|
|
477
|
+
const earlyMatch = expandedTemplate.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
478
|
+
if (!earlyMatch) {
|
|
479
|
+
throw new Error(`Invalid markdown format in ${templatePath}: no frontmatter found`);
|
|
480
|
+
}
|
|
481
|
+
const earlyFrontmatter = parseYaml3(earlyMatch[1]);
|
|
482
|
+
const reservedKeys = /* @__PURE__ */ new Set(["name", "description", "tools"]);
|
|
483
|
+
const extendedAgent = { ...agent };
|
|
484
|
+
for (const [key, value] of Object.entries(earlyFrontmatter)) {
|
|
485
|
+
if (!reservedKeys.has(key) && !(key in extendedAgent)) {
|
|
486
|
+
extendedAgent[key] = value;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
const context = { agent: extendedAgent };
|
|
462
490
|
if (config) {
|
|
463
491
|
context.config = config;
|
|
464
492
|
}
|
|
465
|
-
const resolved = resolveString(
|
|
493
|
+
const resolved = resolveString(expandedTemplate, context);
|
|
466
494
|
const frontmatterMatch = resolved.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
467
495
|
if (!frontmatterMatch) {
|
|
468
|
-
throw new Error(`Invalid markdown format in ${templatePath}
|
|
496
|
+
throw new Error(`Invalid markdown format after resolution in ${templatePath}`);
|
|
469
497
|
}
|
|
470
498
|
const frontmatterYaml = frontmatterMatch[1];
|
|
471
499
|
const body = frontmatterMatch[2] ?? "";
|
|
@@ -1876,469 +1904,123 @@ var CacheManager = class {
|
|
|
1876
1904
|
|
|
1877
1905
|
// src/skills/generator.ts
|
|
1878
1906
|
import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync } from "fs";
|
|
1879
|
-
import { join as join6,
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
## Quality Gates
|
|
1997
|
-
|
|
1998
|
-
Run these checks before committing:
|
|
1999
|
-
|
|
2000
|
-
1. **Lint**: \`{{LINT_CMD}}\`
|
|
2001
|
-
2. **Tests**: \`{{TEST_CMD}}\`
|
|
2002
|
-
3. **Build**: \`{{BUILD_CMD}}\`
|
|
2003
|
-
|
|
2004
|
-
## Instructions
|
|
2005
|
-
|
|
2006
|
-
1. Stage the relevant files with \`git add\`
|
|
2007
|
-
2. Run all quality gate commands
|
|
2008
|
-
3. If any gate fails:
|
|
2009
|
-
- Fix the issues
|
|
2010
|
-
- Re-run the failed gate
|
|
2011
|
-
- Continue only when all pass
|
|
2012
|
-
4. Create the commit with the provided message
|
|
2013
|
-
5. Format: Include ticket reference if applicable
|
|
2014
|
-
|
|
2015
|
-
## Commit Message Format
|
|
2016
|
-
|
|
2017
|
-
\`\`\`
|
|
2018
|
-
<type>(<scope>): <description>
|
|
2019
|
-
|
|
2020
|
-
[optional body]
|
|
2021
|
-
|
|
2022
|
-
[optional footer]
|
|
2023
|
-
\`\`\`
|
|
2024
|
-
|
|
2025
|
-
Types: feat, fix, docs, style, refactor, test, chore
|
|
2026
|
-
|
|
2027
|
-
## Fallbacks
|
|
2028
|
-
|
|
2029
|
-
If quality gate commands are not configured:
|
|
2030
|
-
- Ask the user what commands to run
|
|
2031
|
-
- Or skip gates with user confirmation
|
|
2032
|
-
`
|
|
2033
|
-
};
|
|
2034
|
-
var prCreateSkill = {
|
|
2035
|
-
name: "pr-create",
|
|
2036
|
-
description: "Create a pull request with proper format",
|
|
2037
|
-
argumentHint: "[branch-name]",
|
|
2038
|
-
category: "core",
|
|
2039
|
-
dependencies: [{ type: "git", required: true, description: "For PR creation" }],
|
|
2040
|
-
content: `---
|
|
2041
|
-
description: Create a pull request with proper format
|
|
2042
|
-
argument-hint: [branch-name]
|
|
2043
|
-
requires: [git]
|
|
2044
|
-
---
|
|
2045
|
-
|
|
2046
|
-
# Create Pull Request
|
|
2047
|
-
|
|
2048
|
-
Create a well-formatted pull request for the current branch.
|
|
2049
|
-
|
|
2050
|
-
## Instructions
|
|
2051
|
-
|
|
2052
|
-
1. Ensure all changes are committed
|
|
2053
|
-
2. Push the branch to remote
|
|
2054
|
-
3. Create PR with proper format:
|
|
2055
|
-
|
|
2056
|
-
\`\`\`markdown
|
|
2057
|
-
## Summary
|
|
2058
|
-
<Brief description of changes>
|
|
2059
|
-
|
|
2060
|
-
## Changes
|
|
2061
|
-
- <Change 1>
|
|
2062
|
-
- <Change 2>
|
|
2063
|
-
|
|
2064
|
-
## Test Plan
|
|
2065
|
-
- [ ] <Test case 1>
|
|
2066
|
-
- [ ] <Test case 2>
|
|
2067
|
-
|
|
2068
|
-
## Related Issues
|
|
2069
|
-
Closes {{JIRA_PROJECT}}-XXX
|
|
2070
|
-
\`\`\`
|
|
2071
|
-
|
|
2072
|
-
4. Request reviewers if specified
|
|
2073
|
-
|
|
2074
|
-
## Using GitHub CLI
|
|
2075
|
-
|
|
2076
|
-
\`\`\`bash
|
|
2077
|
-
gh pr create --title "<title>" --body "<body>"
|
|
2078
|
-
\`\`\`
|
|
2079
|
-
|
|
2080
|
-
## Output
|
|
2081
|
-
|
|
2082
|
-
Provide the PR URL and summary of what was created.
|
|
2083
|
-
`
|
|
2084
|
-
};
|
|
2085
|
-
var reviewSkill = {
|
|
2086
|
-
name: "review",
|
|
2087
|
-
description: "Request or perform a code review",
|
|
2088
|
-
argumentHint: "<pr-number-or-url>",
|
|
2089
|
-
category: "core",
|
|
2090
|
-
dependencies: [{ type: "git", required: true, description: "For PR review" }],
|
|
2091
|
-
content: `---
|
|
2092
|
-
description: Request or perform a code review
|
|
2093
|
-
argument-hint: <pr-number-or-url>
|
|
2094
|
-
requires: [git]
|
|
2095
|
-
---
|
|
2096
|
-
|
|
2097
|
-
# Code Review
|
|
2098
|
-
|
|
2099
|
-
Review a pull request or delegate review to a specialist.
|
|
2100
|
-
|
|
2101
|
-
## Instructions
|
|
2102
|
-
|
|
2103
|
-
### If you are reviewing:
|
|
2104
|
-
|
|
2105
|
-
1. Fetch the PR details and diff
|
|
2106
|
-
2. Review for:
|
|
2107
|
-
- Code quality and style
|
|
2108
|
-
- Logic errors or bugs
|
|
2109
|
-
- Security concerns
|
|
2110
|
-
- Test coverage
|
|
2111
|
-
- Documentation
|
|
2112
|
-
3. Provide feedback with specific line references
|
|
2113
|
-
4. Approve, request changes, or comment
|
|
2114
|
-
|
|
2115
|
-
### If delegating to a reviewer:
|
|
2116
|
-
|
|
2117
|
-
1. Identify the appropriate reviewer based on the changes
|
|
2118
|
-
2. Create a review request message in their inbox
|
|
2119
|
-
3. Include PR link and context
|
|
2120
|
-
|
|
2121
|
-
## Review Checklist
|
|
2122
|
-
|
|
2123
|
-
- [ ] Code follows project conventions
|
|
2124
|
-
- [ ] No obvious bugs or edge cases
|
|
2125
|
-
- [ ] Tests cover the changes
|
|
2126
|
-
- [ ] Documentation updated if needed
|
|
2127
|
-
- [ ] No security vulnerabilities
|
|
2128
|
-
|
|
2129
|
-
## Output
|
|
2130
|
-
|
|
2131
|
-
Provide review summary with actionable feedback.
|
|
2132
|
-
`
|
|
2133
|
-
};
|
|
2134
|
-
var sprintStatusSkill = {
|
|
2135
|
-
name: "sprint-status",
|
|
2136
|
-
description: "Get current sprint status and progress",
|
|
2137
|
-
category: "optional",
|
|
2138
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For sprint data" }],
|
|
2139
|
-
content: `---
|
|
2140
|
-
description: Get current sprint status and progress
|
|
2141
|
-
requires: [issue_tracker]
|
|
2142
|
-
---
|
|
2143
|
-
|
|
2144
|
-
# Sprint Status
|
|
2145
|
-
|
|
2146
|
-
Get the current sprint status and team progress.
|
|
2147
|
-
|
|
2148
|
-
## Instructions
|
|
2149
|
-
|
|
2150
|
-
1. Query the active sprint for project {{JIRA_PROJECT}}
|
|
2151
|
-
2. Gather metrics:
|
|
2152
|
-
- Total story points committed
|
|
2153
|
-
- Points completed
|
|
2154
|
-
- Points in progress
|
|
2155
|
-
- Points remaining
|
|
2156
|
-
3. List tickets by status
|
|
2157
|
-
4. Identify blockers or at-risk items
|
|
2158
|
-
|
|
2159
|
-
## Output Format
|
|
2160
|
-
|
|
2161
|
-
\`\`\`
|
|
2162
|
-
Sprint: <sprint-name>
|
|
2163
|
-
Progress: XX/YY points (ZZ%)
|
|
2164
|
-
|
|
2165
|
-
## Completed
|
|
2166
|
-
- [{{JIRA_PROJECT}}-123] Task name (3 pts)
|
|
2167
|
-
|
|
2168
|
-
## In Progress
|
|
2169
|
-
- [{{JIRA_PROJECT}}-124] Task name (5 pts) - @assignee
|
|
2170
|
-
|
|
2171
|
-
## To Do
|
|
2172
|
-
- [{{JIRA_PROJECT}}-125] Task name (2 pts)
|
|
2173
|
-
|
|
2174
|
-
## Blocked
|
|
2175
|
-
- [{{JIRA_PROJECT}}-126] Task name - Reason
|
|
2176
|
-
\`\`\`
|
|
2177
|
-
|
|
2178
|
-
## Fallbacks
|
|
2179
|
-
|
|
2180
|
-
If issue tracker is unavailable:
|
|
2181
|
-
- Report that sprint data cannot be fetched
|
|
2182
|
-
- Suggest checking the issue tracker directly at {{JIRA_URL}}
|
|
2183
|
-
`
|
|
2184
|
-
};
|
|
2185
|
-
var jiraCreateSkill = {
|
|
2186
|
-
name: "jira-create",
|
|
2187
|
-
description: "Create a new Jira ticket",
|
|
2188
|
-
argumentHint: "<ticket-type> <summary>",
|
|
2189
|
-
category: "optional",
|
|
2190
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For ticket creation" }],
|
|
2191
|
-
content: `---
|
|
2192
|
-
description: Create a new Jira ticket
|
|
2193
|
-
argument-hint: <ticket-type> <summary>
|
|
2194
|
-
requires: [issue_tracker]
|
|
2195
|
-
---
|
|
2196
|
-
|
|
2197
|
-
# Create Jira Ticket
|
|
2198
|
-
|
|
2199
|
-
Create a new ticket in project {{JIRA_PROJECT}}.
|
|
2200
|
-
|
|
2201
|
-
## Instructions
|
|
2202
|
-
|
|
2203
|
-
1. Parse the ticket type and summary from arguments
|
|
2204
|
-
2. Gather additional details:
|
|
2205
|
-
- Description
|
|
2206
|
-
- Priority
|
|
2207
|
-
- Labels
|
|
2208
|
-
- Components (if applicable)
|
|
2209
|
-
3. Create the ticket via the issue tracker integration
|
|
2210
|
-
4. Return the ticket key and URL
|
|
2211
|
-
|
|
2212
|
-
## Ticket Types
|
|
2213
|
-
|
|
2214
|
-
- **Story**: User-facing feature
|
|
2215
|
-
- **Bug**: Defect to fix
|
|
2216
|
-
- **Task**: Technical work
|
|
2217
|
-
- **Spike**: Research/investigation
|
|
2218
|
-
|
|
2219
|
-
## Output
|
|
2220
|
-
|
|
2221
|
-
\`\`\`
|
|
2222
|
-
Created: {{JIRA_PROJECT}}-XXX
|
|
2223
|
-
URL: {{JIRA_URL}}/browse/{{JIRA_PROJECT}}-XXX
|
|
2224
|
-
Summary: <summary>
|
|
2225
|
-
Type: <type>
|
|
2226
|
-
\`\`\`
|
|
2227
|
-
|
|
2228
|
-
## Fallbacks
|
|
2229
|
-
|
|
2230
|
-
If issue tracker is unavailable:
|
|
2231
|
-
- Provide the user with manual creation instructions
|
|
2232
|
-
- Include all details they should enter
|
|
2233
|
-
`
|
|
2234
|
-
};
|
|
2235
|
-
var jiraTransitionSkill = {
|
|
2236
|
-
name: "jira-transition",
|
|
2237
|
-
description: "Transition a Jira ticket to a new status",
|
|
2238
|
-
argumentHint: "<ticket-key> to <status>",
|
|
2239
|
-
category: "optional",
|
|
2240
|
-
dependencies: [{ type: "issue_tracker", required: true, description: "For ticket transitions" }],
|
|
2241
|
-
content: `---
|
|
2242
|
-
description: Transition a Jira ticket to a new status
|
|
2243
|
-
argument-hint: <ticket-key> to <status>
|
|
2244
|
-
requires: [issue_tracker]
|
|
2245
|
-
---
|
|
2246
|
-
|
|
2247
|
-
# Transition Jira Ticket
|
|
2248
|
-
|
|
2249
|
-
Update the status of a ticket in {{JIRA_PROJECT}}.
|
|
2250
|
-
|
|
2251
|
-
## Status Mapping
|
|
2252
|
-
|
|
2253
|
-
| Workflow Status | Jira Status |
|
|
2254
|
-
|-----------------|-------------|
|
|
2255
|
-
| BACKLOG | Backlog |
|
|
2256
|
-
| IN_PROGRESS | In Progress |
|
|
2257
|
-
| PR_CREATED | In Review |
|
|
2258
|
-
| IN_REVIEW | In Review |
|
|
2259
|
-
| APPROVED | Ready to Merge |
|
|
2260
|
-
| MERGED | Done |
|
|
2261
|
-
| DONE | Done |
|
|
2262
|
-
|
|
2263
|
-
## Instructions
|
|
2264
|
-
|
|
2265
|
-
1. Parse ticket key and target status
|
|
2266
|
-
2. Validate the transition is allowed
|
|
2267
|
-
3. Add a comment explaining the transition
|
|
2268
|
-
4. Execute the transition
|
|
2269
|
-
|
|
2270
|
-
## Transition Comment Format
|
|
2271
|
-
|
|
2272
|
-
\`\`\`
|
|
2273
|
-
Status updated to <status>.
|
|
2274
|
-
<optional context about why>
|
|
2275
|
-
\`\`\`
|
|
2276
|
-
|
|
2277
|
-
## Fallbacks
|
|
2278
|
-
|
|
2279
|
-
If issue tracker is unavailable:
|
|
2280
|
-
- Instruct user to manually transition at {{JIRA_URL}}
|
|
2281
|
-
- Provide the target status name
|
|
2282
|
-
`
|
|
2283
|
-
};
|
|
2284
|
-
var docsUpdateSkill = {
|
|
2285
|
-
name: "docs-update",
|
|
2286
|
-
description: "Update project documentation",
|
|
2287
|
-
argumentHint: "<doc-path-or-topic>",
|
|
2288
|
-
category: "optional",
|
|
2289
|
-
dependencies: [{ type: "documentation", required: false, description: "For remote docs" }],
|
|
2290
|
-
content: `---
|
|
2291
|
-
description: Update project documentation
|
|
2292
|
-
argument-hint: <doc-path-or-topic>
|
|
2293
|
-
optional: [documentation]
|
|
2294
|
-
---
|
|
2295
|
-
|
|
2296
|
-
# Update Documentation
|
|
2297
|
-
|
|
2298
|
-
Update project documentation for a specific topic or file.
|
|
2299
|
-
|
|
2300
|
-
## Instructions
|
|
2301
|
-
|
|
2302
|
-
1. Identify the documentation to update:
|
|
2303
|
-
- Local: \`{{DOCS_PATH}}/\`
|
|
2304
|
-
- Remote: {{CONFLUENCE_SPACE}} (if configured)
|
|
2305
|
-
|
|
2306
|
-
2. Make the necessary updates:
|
|
2307
|
-
- Keep formatting consistent
|
|
2308
|
-
- Update examples if code changed
|
|
2309
|
-
- Add/update version information
|
|
2310
|
-
|
|
2311
|
-
3. For remote documentation:
|
|
2312
|
-
- Use the documentation integration
|
|
2313
|
-
- Or provide content for manual update
|
|
2314
|
-
|
|
2315
|
-
## Documentation Types
|
|
2316
|
-
|
|
2317
|
-
- **README**: Project overview and setup
|
|
2318
|
-
- **API Docs**: Endpoint documentation
|
|
2319
|
-
- **Architecture**: Design decisions
|
|
2320
|
-
- **Runbooks**: Operational procedures
|
|
2321
|
-
|
|
2322
|
-
## Fallbacks
|
|
2323
|
-
|
|
2324
|
-
If documentation integration is unavailable:
|
|
2325
|
-
- Create/update local markdown files
|
|
2326
|
-
- Provide instructions for manual remote update
|
|
2327
|
-
`
|
|
2328
|
-
};
|
|
2329
|
-
var builtInSkills = [
|
|
2330
|
-
checkInboxSkill,
|
|
2331
|
-
delegateSkill,
|
|
2332
|
-
gitCommitSkill,
|
|
2333
|
-
prCreateSkill,
|
|
2334
|
-
reviewSkill,
|
|
2335
|
-
sprintStatusSkill,
|
|
2336
|
-
jiraCreateSkill,
|
|
2337
|
-
jiraTransitionSkill,
|
|
2338
|
-
docsUpdateSkill
|
|
2339
|
-
];
|
|
2340
|
-
|
|
2341
|
-
// src/skills/generator.ts
|
|
1907
|
+
import { join as join6, dirname as dirname5 } from "path";
|
|
1908
|
+
function getCoreSkillsDir() {
|
|
1909
|
+
let currentDir = dirname5(import.meta.url.replace("file://", ""));
|
|
1910
|
+
for (let i = 0; i < 5; i++) {
|
|
1911
|
+
if (existsSync5(join6(currentDir, "package.json"))) {
|
|
1912
|
+
return join6(currentDir, "skills");
|
|
1913
|
+
}
|
|
1914
|
+
currentDir = dirname5(currentDir);
|
|
1915
|
+
}
|
|
1916
|
+
return join6(dirname5(dirname5(dirname5(import.meta.url.replace("file://", "")))), "skills");
|
|
1917
|
+
}
|
|
1918
|
+
function discoverSkills(skillsDir) {
|
|
1919
|
+
const templates = [];
|
|
1920
|
+
if (!existsSync5(skillsDir)) {
|
|
1921
|
+
return templates;
|
|
1922
|
+
}
|
|
1923
|
+
const categories = readdirSync2(skillsDir);
|
|
1924
|
+
for (const category of categories) {
|
|
1925
|
+
const categoryPath = join6(skillsDir, category);
|
|
1926
|
+
const stat = statSync(categoryPath);
|
|
1927
|
+
if (!stat.isDirectory()) continue;
|
|
1928
|
+
if (category.startsWith(".") || category.startsWith("_")) continue;
|
|
1929
|
+
const skillDirs = readdirSync2(categoryPath);
|
|
1930
|
+
for (const skillName of skillDirs) {
|
|
1931
|
+
const skillDir = join6(categoryPath, skillName);
|
|
1932
|
+
const skillStat = statSync(skillDir);
|
|
1933
|
+
if (!skillStat.isDirectory()) continue;
|
|
1934
|
+
const skillFile = join6(skillDir, "SKILL.md");
|
|
1935
|
+
if (!existsSync5(skillFile)) continue;
|
|
1936
|
+
try {
|
|
1937
|
+
const content = readFileSync5(skillFile, "utf-8");
|
|
1938
|
+
const template = parseSkillFile(skillName, category, content);
|
|
1939
|
+
templates.push(template);
|
|
1940
|
+
} catch {
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
return templates;
|
|
1945
|
+
}
|
|
1946
|
+
function parseSkillFile(name, category, content) {
|
|
1947
|
+
const template = {
|
|
1948
|
+
name,
|
|
1949
|
+
description: name,
|
|
1950
|
+
category,
|
|
1951
|
+
content
|
|
1952
|
+
};
|
|
1953
|
+
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);
|
|
1954
|
+
if (!frontmatterMatch) {
|
|
1955
|
+
return template;
|
|
1956
|
+
}
|
|
1957
|
+
const frontmatter = frontmatterMatch[1];
|
|
1958
|
+
const lines = frontmatter.split(/\r?\n/);
|
|
1959
|
+
const dependencies = [];
|
|
1960
|
+
for (const line of lines) {
|
|
1961
|
+
const colonIndex = line.indexOf(":");
|
|
1962
|
+
if (colonIndex === -1) continue;
|
|
1963
|
+
const key = line.slice(0, colonIndex).trim();
|
|
1964
|
+
let value = line.slice(colonIndex + 1).trim();
|
|
1965
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1966
|
+
value = value.slice(1, -1);
|
|
1967
|
+
}
|
|
1968
|
+
switch (key) {
|
|
1969
|
+
case "name":
|
|
1970
|
+
template.name = value;
|
|
1971
|
+
break;
|
|
1972
|
+
case "description":
|
|
1973
|
+
template.description = value;
|
|
1974
|
+
break;
|
|
1975
|
+
case "argument-hint":
|
|
1976
|
+
template.argumentHint = value;
|
|
1977
|
+
break;
|
|
1978
|
+
case "requires":
|
|
1979
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
1980
|
+
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
1981
|
+
for (const item of items) {
|
|
1982
|
+
if (item) {
|
|
1983
|
+
dependencies.push({
|
|
1984
|
+
type: mapIntegrationName(item),
|
|
1985
|
+
required: true
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
break;
|
|
1991
|
+
case "optional":
|
|
1992
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
1993
|
+
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
1994
|
+
for (const item of items) {
|
|
1995
|
+
if (item) {
|
|
1996
|
+
dependencies.push({
|
|
1997
|
+
type: mapIntegrationName(item),
|
|
1998
|
+
required: false
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
break;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
if (dependencies.length > 0) {
|
|
2007
|
+
template.dependencies = dependencies;
|
|
2008
|
+
}
|
|
2009
|
+
return template;
|
|
2010
|
+
}
|
|
2011
|
+
function mapIntegrationName(name) {
|
|
2012
|
+
const lower = name.toLowerCase();
|
|
2013
|
+
if (["jira", "linear", "issue_tracker", "issues", "github-issues"].includes(lower)) {
|
|
2014
|
+
return "issue_tracker";
|
|
2015
|
+
}
|
|
2016
|
+
if (["git", "github", "gitlab", "bitbucket"].includes(lower)) {
|
|
2017
|
+
return "git";
|
|
2018
|
+
}
|
|
2019
|
+
if (["docs", "documentation", "confluence", "notion", "wiki"].includes(lower)) {
|
|
2020
|
+
return "documentation";
|
|
2021
|
+
}
|
|
2022
|
+
return "state";
|
|
2023
|
+
}
|
|
2342
2024
|
function extractVariables2(config) {
|
|
2343
2025
|
const vars = {};
|
|
2344
2026
|
if (!config) {
|
|
@@ -2448,112 +2130,12 @@ function checkDependencies(skill, config) {
|
|
|
2448
2130
|
missing
|
|
2449
2131
|
};
|
|
2450
2132
|
}
|
|
2451
|
-
function loadCustomTemplates(templatesDir) {
|
|
2452
|
-
const templates = [];
|
|
2453
|
-
if (!existsSync5(templatesDir)) {
|
|
2454
|
-
return templates;
|
|
2455
|
-
}
|
|
2456
|
-
const files = readdirSync2(templatesDir);
|
|
2457
|
-
for (const file of files) {
|
|
2458
|
-
if (!file.endsWith(".md")) continue;
|
|
2459
|
-
const filePath = join6(templatesDir, file);
|
|
2460
|
-
const stat = statSync(filePath);
|
|
2461
|
-
if (!stat.isFile()) continue;
|
|
2462
|
-
try {
|
|
2463
|
-
const content = readFileSync5(filePath, "utf-8");
|
|
2464
|
-
const template = parseSkillTemplate(file, content);
|
|
2465
|
-
templates.push(template);
|
|
2466
|
-
} catch {
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
return templates;
|
|
2470
|
-
}
|
|
2471
|
-
function parseSkillTemplate(filename, content) {
|
|
2472
|
-
const name = basename2(filename, ".md");
|
|
2473
|
-
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
2474
|
-
let description = name;
|
|
2475
|
-
let argumentHint;
|
|
2476
|
-
const dependencies = [];
|
|
2477
|
-
if (frontmatterMatch) {
|
|
2478
|
-
const frontmatter = frontmatterMatch[1] ?? "";
|
|
2479
|
-
const lines = frontmatter.split(/\r?\n/);
|
|
2480
|
-
for (const line of lines) {
|
|
2481
|
-
const colonIndex = line.indexOf(":");
|
|
2482
|
-
if (colonIndex === -1) continue;
|
|
2483
|
-
const key = line.slice(0, colonIndex).trim();
|
|
2484
|
-
let value = line.slice(colonIndex + 1).trim();
|
|
2485
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2486
|
-
value = value.slice(1, -1);
|
|
2487
|
-
}
|
|
2488
|
-
switch (key) {
|
|
2489
|
-
case "description":
|
|
2490
|
-
description = value;
|
|
2491
|
-
break;
|
|
2492
|
-
case "argument-hint":
|
|
2493
|
-
argumentHint = value;
|
|
2494
|
-
break;
|
|
2495
|
-
case "requires":
|
|
2496
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2497
|
-
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
2498
|
-
for (const item of items) {
|
|
2499
|
-
if (item) {
|
|
2500
|
-
dependencies.push({
|
|
2501
|
-
type: mapIntegrationName(item),
|
|
2502
|
-
required: true
|
|
2503
|
-
});
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
break;
|
|
2508
|
-
case "optional":
|
|
2509
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2510
|
-
const items = value.slice(1, -1).split(",").map((s) => s.trim().replace(/['"]/g, ""));
|
|
2511
|
-
for (const item of items) {
|
|
2512
|
-
if (item) {
|
|
2513
|
-
dependencies.push({
|
|
2514
|
-
type: mapIntegrationName(item),
|
|
2515
|
-
required: false
|
|
2516
|
-
});
|
|
2517
|
-
}
|
|
2518
|
-
}
|
|
2519
|
-
}
|
|
2520
|
-
break;
|
|
2521
|
-
}
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
const template = {
|
|
2525
|
-
name,
|
|
2526
|
-
description,
|
|
2527
|
-
category: "custom",
|
|
2528
|
-
content
|
|
2529
|
-
};
|
|
2530
|
-
if (argumentHint) {
|
|
2531
|
-
template.argumentHint = argumentHint;
|
|
2532
|
-
}
|
|
2533
|
-
if (dependencies.length > 0) {
|
|
2534
|
-
template.dependencies = dependencies;
|
|
2535
|
-
}
|
|
2536
|
-
return template;
|
|
2537
|
-
}
|
|
2538
|
-
function mapIntegrationName(name) {
|
|
2539
|
-
const lower = name.toLowerCase();
|
|
2540
|
-
if (["jira", "linear", "issue_tracker", "issues", "github-issues"].includes(lower)) {
|
|
2541
|
-
return "issue_tracker";
|
|
2542
|
-
}
|
|
2543
|
-
if (["git", "github", "gitlab", "bitbucket"].includes(lower)) {
|
|
2544
|
-
return "git";
|
|
2545
|
-
}
|
|
2546
|
-
if (["docs", "documentation", "confluence", "notion", "wiki"].includes(lower)) {
|
|
2547
|
-
return "documentation";
|
|
2548
|
-
}
|
|
2549
|
-
return "state";
|
|
2550
|
-
}
|
|
2551
2133
|
function generateSkills(config, options = {}) {
|
|
2552
2134
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
2553
|
-
const
|
|
2135
|
+
const coreSkillsDir = options.coreSkillsDir ?? getCoreSkillsDir();
|
|
2136
|
+
const outputDir = options.outputDir ?? join6(projectRoot, ".claude", "skills");
|
|
2554
2137
|
const includeCoreSkills = options.includeCoreSkills ?? true;
|
|
2555
|
-
const
|
|
2556
|
-
const overwrite = options.overwrite ?? false;
|
|
2138
|
+
const overwrite = options.overwrite ?? true;
|
|
2557
2139
|
const result = {
|
|
2558
2140
|
generated: [],
|
|
2559
2141
|
errors: [],
|
|
@@ -2566,21 +2148,17 @@ function generateSkills(config, options = {}) {
|
|
|
2566
2148
|
result.variables = variables;
|
|
2567
2149
|
let templates = [];
|
|
2568
2150
|
if (includeCoreSkills) {
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
if (includeOptionalSkills) {
|
|
2572
|
-
templates.push(...builtInSkills.filter((s) => s.category === "optional"));
|
|
2151
|
+
const discovered = discoverSkills(coreSkillsDir);
|
|
2152
|
+
templates.push(...discovered);
|
|
2573
2153
|
}
|
|
2574
2154
|
if (options.customTemplatesDir && existsSync5(options.customTemplatesDir)) {
|
|
2575
|
-
|
|
2155
|
+
const custom = discoverSkills(options.customTemplatesDir);
|
|
2156
|
+
templates.push(...custom);
|
|
2576
2157
|
}
|
|
2577
2158
|
if (options.skills && options.skills.length > 0) {
|
|
2578
2159
|
const skillsToInclude = options.skills;
|
|
2579
2160
|
templates = templates.filter((t) => skillsToInclude.includes(t.name));
|
|
2580
2161
|
}
|
|
2581
|
-
if (!existsSync5(outputDir)) {
|
|
2582
|
-
mkdirSync2(outputDir, { recursive: true });
|
|
2583
|
-
}
|
|
2584
2162
|
for (const template of templates) {
|
|
2585
2163
|
try {
|
|
2586
2164
|
const generated = generateSkill(template, variables, config, outputDir, overwrite);
|
|
@@ -2595,7 +2173,8 @@ function generateSkills(config, options = {}) {
|
|
|
2595
2173
|
return result;
|
|
2596
2174
|
}
|
|
2597
2175
|
function generateSkill(template, variables, config, outputDir, overwrite) {
|
|
2598
|
-
const
|
|
2176
|
+
const skillDir = join6(outputDir, template.name);
|
|
2177
|
+
const outputPath = join6(skillDir, "SKILL.md");
|
|
2599
2178
|
if (existsSync5(outputPath) && !overwrite) {
|
|
2600
2179
|
return {
|
|
2601
2180
|
name: template.name,
|
|
@@ -2618,6 +2197,9 @@ function generateSkill(template, variables, config, outputDir, overwrite) {
|
|
|
2618
2197
|
}
|
|
2619
2198
|
const content = substituteVariables(template.content, variables);
|
|
2620
2199
|
const isUpdate = existsSync5(outputPath);
|
|
2200
|
+
if (!existsSync5(skillDir)) {
|
|
2201
|
+
mkdirSync2(skillDir, { recursive: true });
|
|
2202
|
+
}
|
|
2621
2203
|
writeFileSync2(outputPath, content, "utf-8");
|
|
2622
2204
|
return {
|
|
2623
2205
|
name: template.name,
|
|
@@ -2661,7 +2243,7 @@ function formatGenerateResult(result) {
|
|
|
2661
2243
|
}
|
|
2662
2244
|
const total = created.length + updated.length;
|
|
2663
2245
|
if (total > 0) {
|
|
2664
|
-
lines.push(`Generated ${total} skill(s) to .claude/
|
|
2246
|
+
lines.push(`Generated ${total} skill(s) to .claude/skills/`);
|
|
2665
2247
|
} else if (result.generated.length === 0 && result.errors.length === 0) {
|
|
2666
2248
|
lines.push("No skills to generate.");
|
|
2667
2249
|
}
|
|
@@ -2678,7 +2260,7 @@ import {
|
|
|
2678
2260
|
renameSync,
|
|
2679
2261
|
statSync as statSync2
|
|
2680
2262
|
} from "fs";
|
|
2681
|
-
import { join as join7, basename as
|
|
2263
|
+
import { join as join7, basename as basename2 } from "path";
|
|
2682
2264
|
var DEFAULT_KNOWLEDGE_LIBRARY_PATH = "KnowledgeLibrary";
|
|
2683
2265
|
var STANDARD_FILES = {
|
|
2684
2266
|
context: "context.txt",
|
|
@@ -3091,8 +2673,8 @@ function getKnowledgeLibraryState(options = {}) {
|
|
|
3091
2673
|
|
|
3092
2674
|
// src/index.ts
|
|
3093
2675
|
function findPackageJson() {
|
|
3094
|
-
let dir =
|
|
3095
|
-
while (dir !==
|
|
2676
|
+
let dir = dirname6(fileURLToPath(import.meta.url));
|
|
2677
|
+
while (dir !== dirname6(dir)) {
|
|
3096
2678
|
const pkgPath = join8(dir, "package.json");
|
|
3097
2679
|
try {
|
|
3098
2680
|
const content = readFileSync7(pkgPath, "utf-8");
|
|
@@ -3102,7 +2684,7 @@ function findPackageJson() {
|
|
|
3102
2684
|
}
|
|
3103
2685
|
} catch {
|
|
3104
2686
|
}
|
|
3105
|
-
dir =
|
|
2687
|
+
dir = dirname6(dir);
|
|
3106
2688
|
}
|
|
3107
2689
|
return '{"version": "unknown"}';
|
|
3108
2690
|
}
|
|
@@ -3380,7 +2962,7 @@ function formatSyncResult(result) {
|
|
|
3380
2962
|
|
|
3381
2963
|
// src/cli/commands/init.ts
|
|
3382
2964
|
import { existsSync as existsSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync8 } from "fs";
|
|
3383
|
-
import { join as join11, basename as
|
|
2965
|
+
import { join as join11, basename as basename3 } from "path";
|
|
3384
2966
|
import { execSync } from "child_process";
|
|
3385
2967
|
function detectGitInfo() {
|
|
3386
2968
|
try {
|
|
@@ -3417,7 +2999,7 @@ function detectProjectName(projectRoot) {
|
|
|
3417
2999
|
} catch {
|
|
3418
3000
|
}
|
|
3419
3001
|
}
|
|
3420
|
-
return
|
|
3002
|
+
return basename3(projectRoot);
|
|
3421
3003
|
}
|
|
3422
3004
|
function generateConfigYaml(options) {
|
|
3423
3005
|
let yaml = `# CoreAI Configuration
|
|
@@ -3614,6 +3196,14 @@ function build(options = {}) {
|
|
|
3614
3196
|
warnings
|
|
3615
3197
|
};
|
|
3616
3198
|
}
|
|
3199
|
+
let skillsResult;
|
|
3200
|
+
if (!options.skipSkills) {
|
|
3201
|
+
skillsResult = generateSkills(config, {
|
|
3202
|
+
projectRoot,
|
|
3203
|
+
skills: options.skills,
|
|
3204
|
+
overwrite: true
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3617
3207
|
let knowledgeLibraryInitialized;
|
|
3618
3208
|
if (options.initKnowledgeLibrary) {
|
|
3619
3209
|
knowledgeLibraryInitialized = [];
|
|
@@ -3630,6 +3220,7 @@ function build(options = {}) {
|
|
|
3630
3220
|
return {
|
|
3631
3221
|
success: true,
|
|
3632
3222
|
result,
|
|
3223
|
+
skillsResult,
|
|
3633
3224
|
config,
|
|
3634
3225
|
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3635
3226
|
knowledgeLibraryInitialized,
|
|
@@ -3699,6 +3290,24 @@ function formatBuildResult(result) {
|
|
|
3699
3290
|
}
|
|
3700
3291
|
lines.push("");
|
|
3701
3292
|
}
|
|
3293
|
+
if (result.skillsResult) {
|
|
3294
|
+
const created = result.skillsResult.generated.filter((g) => g.action === "created");
|
|
3295
|
+
const updated = result.skillsResult.generated.filter((g) => g.action === "updated");
|
|
3296
|
+
const total = created.length + updated.length;
|
|
3297
|
+
if (total > 0) {
|
|
3298
|
+
lines.push(`Generated ${total} skill(s):`);
|
|
3299
|
+
for (const skill of [...created, ...updated]) {
|
|
3300
|
+
lines.push(` \u2713 ${skill.name} \u2192 ${skill.outputPath}`);
|
|
3301
|
+
}
|
|
3302
|
+
lines.push("");
|
|
3303
|
+
}
|
|
3304
|
+
if (result.skillsResult.errors.length > 0) {
|
|
3305
|
+
for (const error of result.skillsResult.errors) {
|
|
3306
|
+
lines.push(` \u2717 skill ${error.name}: ${error.error}`);
|
|
3307
|
+
}
|
|
3308
|
+
lines.push("");
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3702
3311
|
if (result.mcpServers && result.mcpServers.length > 0) {
|
|
3703
3312
|
lines.push(`MCP tools included: ${result.mcpServers.map((s) => `mcp__${s}`).join(", ")}`);
|
|
3704
3313
|
lines.push("");
|
|
@@ -3943,8 +3552,7 @@ function skillsGenerate(options = {}) {
|
|
|
3943
3552
|
const generateOptions = {
|
|
3944
3553
|
projectRoot,
|
|
3945
3554
|
includeCoreSkills: options.includeCoreSkills ?? true,
|
|
3946
|
-
|
|
3947
|
-
overwrite: options.overwrite ?? false
|
|
3555
|
+
overwrite: options.overwrite ?? true
|
|
3948
3556
|
};
|
|
3949
3557
|
if (options.outputDir) {
|
|
3950
3558
|
generateOptions.outputDir = options.outputDir;
|
|
@@ -4010,11 +3618,11 @@ function formatSkillsGenerateResult(result) {
|
|
|
4010
3618
|
function skillsList(options = {}) {
|
|
4011
3619
|
try {
|
|
4012
3620
|
const skills = [];
|
|
3621
|
+
const coreSkillsDir = getCoreSkillsDir();
|
|
3622
|
+
const discovered = discoverSkills(coreSkillsDir);
|
|
4013
3623
|
const includeCoreSkills = options.includeCoreSkills ?? true;
|
|
4014
|
-
const
|
|
4015
|
-
for (const skill of builtInSkills) {
|
|
3624
|
+
for (const skill of discovered) {
|
|
4016
3625
|
if (skill.category === "core" && !includeCoreSkills) continue;
|
|
4017
|
-
if (skill.category === "optional" && !includeOptionalSkills) continue;
|
|
4018
3626
|
skills.push({
|
|
4019
3627
|
name: skill.name,
|
|
4020
3628
|
description: skill.description,
|
|
@@ -4024,7 +3632,7 @@ function skillsList(options = {}) {
|
|
|
4024
3632
|
});
|
|
4025
3633
|
}
|
|
4026
3634
|
if (options.customTemplatesDir) {
|
|
4027
|
-
const customSkills =
|
|
3635
|
+
const customSkills = discoverSkills(options.customTemplatesDir);
|
|
4028
3636
|
for (const skill of customSkills) {
|
|
4029
3637
|
skills.push({
|
|
4030
3638
|
name: skill.name,
|
|
@@ -4056,7 +3664,6 @@ function formatSkillsListResult(result) {
|
|
|
4056
3664
|
const lines = [];
|
|
4057
3665
|
lines.push("Available skills:\n");
|
|
4058
3666
|
const coreSkills = result.skills.filter((s) => s.category === "core");
|
|
4059
|
-
const optionalSkills = result.skills.filter((s) => s.category === "optional");
|
|
4060
3667
|
const customSkills = result.skills.filter((s) => s.category === "custom");
|
|
4061
3668
|
if (coreSkills.length > 0) {
|
|
4062
3669
|
lines.push("Core skills:");
|
|
@@ -4069,18 +3676,6 @@ function formatSkillsListResult(result) {
|
|
|
4069
3676
|
}
|
|
4070
3677
|
lines.push("");
|
|
4071
3678
|
}
|
|
4072
|
-
if (optionalSkills.length > 0) {
|
|
4073
|
-
lines.push("Optional skills:");
|
|
4074
|
-
for (const skill of optionalSkills) {
|
|
4075
|
-
const deps = skill.dependencies?.length ? ` (requires: ${skill.dependencies.join(", ")})` : "";
|
|
4076
|
-
lines.push(` ${skill.name}${deps}`);
|
|
4077
|
-
lines.push(` ${skill.description}`);
|
|
4078
|
-
if (skill.argumentHint) {
|
|
4079
|
-
lines.push(` Argument: ${skill.argumentHint}`);
|
|
4080
|
-
}
|
|
4081
|
-
}
|
|
4082
|
-
lines.push("");
|
|
4083
|
-
}
|
|
4084
3679
|
if (customSkills.length > 0) {
|
|
4085
3680
|
lines.push("Custom skills:");
|
|
4086
3681
|
for (const skill of customSkills) {
|
|
@@ -4257,7 +3852,7 @@ function formatStatusResult(result) {
|
|
|
4257
3852
|
|
|
4258
3853
|
// src/cli/commands/agents.ts
|
|
4259
3854
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
4260
|
-
import { join as join13, dirname as
|
|
3855
|
+
import { join as join13, dirname as dirname7 } from "path";
|
|
4261
3856
|
import { parse as parseYaml4, stringify as stringifyYaml2 } from "yaml";
|
|
4262
3857
|
function readConfigFile(configPath) {
|
|
4263
3858
|
const content = readFileSync9(configPath, "utf-8");
|
|
@@ -4291,7 +3886,7 @@ function getAvailableAgents(coreAgentsDir, customAgentsDir) {
|
|
|
4291
3886
|
}
|
|
4292
3887
|
function agentsAdd(agents2, options = {}) {
|
|
4293
3888
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
4294
|
-
const coreAgentsDir = options.coreAgentsDir ?? join13(
|
|
3889
|
+
const coreAgentsDir = options.coreAgentsDir ?? join13(dirname7(dirname7(dirname7(__dirname))), "agents");
|
|
4295
3890
|
const customAgentsDir = join13(projectRoot, "coreai", "agents");
|
|
4296
3891
|
const configPath = findConfigFile(projectRoot);
|
|
4297
3892
|
if (!configPath) {
|
|
@@ -4473,7 +4068,7 @@ function formatAgentsRemoveResult(result) {
|
|
|
4473
4068
|
|
|
4474
4069
|
// src/cli/index.ts
|
|
4475
4070
|
var __filename = fileURLToPath2(import.meta.url);
|
|
4476
|
-
var __dirname2 =
|
|
4071
|
+
var __dirname2 = dirname8(__filename);
|
|
4477
4072
|
function getCoreAgentsPath() {
|
|
4478
4073
|
return join14(__dirname2, "..", "..", "agents");
|
|
4479
4074
|
}
|
|
@@ -4783,7 +4378,7 @@ program.command("status").description("Show agent states and pending messages").
|
|
|
4783
4378
|
}
|
|
4784
4379
|
});
|
|
4785
4380
|
var skillsCmd = program.command("skills").description("Manage Claude skills");
|
|
4786
|
-
skillsCmd.command("generate").description("Generate Claude skills from
|
|
4381
|
+
skillsCmd.command("generate").description("Generate Claude skills from source files").option("-o, --output <dir>", "output directory (default: .claude/skills)").option("--skills <skills>", "comma-separated list of skills to generate").option("--no-core", "exclude core skills").option("--no-overwrite", "do not overwrite existing skill files").option("--json", "output as JSON").action(
|
|
4787
4382
|
(options) => {
|
|
4788
4383
|
console.log("Generating skills...\n");
|
|
4789
4384
|
const result = skillsGenerate({
|
|
@@ -4791,8 +4386,7 @@ skillsCmd.command("generate").description("Generate Claude skills from templates
|
|
|
4791
4386
|
outputDir: options.output,
|
|
4792
4387
|
skills: options.skills?.split(",").map((s) => s.trim()),
|
|
4793
4388
|
includeCoreSkills: options.core !== false,
|
|
4794
|
-
|
|
4795
|
-
overwrite: options.overwrite
|
|
4389
|
+
overwrite: options.overwrite !== false
|
|
4796
4390
|
});
|
|
4797
4391
|
if (options.json) {
|
|
4798
4392
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4804,11 +4398,10 @@ skillsCmd.command("generate").description("Generate Claude skills from templates
|
|
|
4804
4398
|
}
|
|
4805
4399
|
}
|
|
4806
4400
|
);
|
|
4807
|
-
skillsCmd.command("list").description("List available skills").option("--no-core", "exclude core skills").option("--
|
|
4401
|
+
skillsCmd.command("list").description("List available skills").option("--no-core", "exclude core skills").option("--json", "output as JSON").action((options) => {
|
|
4808
4402
|
const result = skillsList({
|
|
4809
4403
|
projectRoot: process.cwd(),
|
|
4810
|
-
includeCoreSkills: options.core !== false
|
|
4811
|
-
includeOptionalSkills: options.optional !== false
|
|
4404
|
+
includeCoreSkills: options.core !== false
|
|
4812
4405
|
});
|
|
4813
4406
|
if (options.json) {
|
|
4814
4407
|
console.log(JSON.stringify(result, null, 2));
|