syntra 0.1.2
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 +239 -0
- package/dist/adapters/claude.d.ts +3 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +19 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/common.d.ts +14 -0
- package/dist/adapters/common.d.ts.map +1 -0
- package/dist/adapters/common.js +38 -0
- package/dist/adapters/common.js.map +1 -0
- package/dist/adapters/copilot.d.ts +5 -0
- package/dist/adapters/copilot.d.ts.map +1 -0
- package/dist/adapters/copilot.js +25 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor.d.ts +3 -0
- package/dist/adapters/cursor.d.ts.map +1 -0
- package/dist/adapters/cursor.js +26 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +27 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +154 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/done.d.ts +2 -0
- package/dist/commands/done.d.ts.map +1 -0
- package/dist/commands/done.js +20 -0
- package/dist/commands/done.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +129 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +31 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/template.d.ts +3 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +51 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/validate.d.ts +6 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +101 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/detectors/cicd.d.ts +2 -0
- package/dist/detectors/cicd.d.ts.map +1 -0
- package/dist/detectors/cicd.js +24 -0
- package/dist/detectors/cicd.js.map +1 -0
- package/dist/detectors/existingAi.d.ts +6 -0
- package/dist/detectors/existingAi.d.ts.map +1 -0
- package/dist/detectors/existingAi.js +10 -0
- package/dist/detectors/existingAi.js.map +1 -0
- package/dist/detectors/framework.d.ts +3 -0
- package/dist/detectors/framework.d.ts.map +1 -0
- package/dist/detectors/framework.js +75 -0
- package/dist/detectors/framework.js.map +1 -0
- package/dist/detectors/index.d.ts +9 -0
- package/dist/detectors/index.d.ts.map +1 -0
- package/dist/detectors/index.js +29 -0
- package/dist/detectors/index.js.map +1 -0
- package/dist/detectors/language.d.ts +3 -0
- package/dist/detectors/language.d.ts.map +1 -0
- package/dist/detectors/language.js +34 -0
- package/dist/detectors/language.js.map +1 -0
- package/dist/detectors/monorepo.d.ts +2 -0
- package/dist/detectors/monorepo.d.ts.map +1 -0
- package/dist/detectors/monorepo.js +31 -0
- package/dist/detectors/monorepo.js.map +1 -0
- package/dist/detectors/packageManager.d.ts +3 -0
- package/dist/detectors/packageManager.d.ts.map +1 -0
- package/dist/detectors/packageManager.js +42 -0
- package/dist/detectors/packageManager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/agents/bugFixer.d.ts +2 -0
- package/dist/templates/agents/bugFixer.d.ts.map +1 -0
- package/dist/templates/agents/bugFixer.js +37 -0
- package/dist/templates/agents/bugFixer.js.map +1 -0
- package/dist/templates/agents/codeGenerator.d.ts +2 -0
- package/dist/templates/agents/codeGenerator.d.ts.map +1 -0
- package/dist/templates/agents/codeGenerator.js +41 -0
- package/dist/templates/agents/codeGenerator.js.map +1 -0
- package/dist/templates/agents/codeReviewer.d.ts +2 -0
- package/dist/templates/agents/codeReviewer.d.ts.map +1 -0
- package/dist/templates/agents/codeReviewer.js +43 -0
- package/dist/templates/agents/codeReviewer.js.map +1 -0
- package/dist/templates/agents/index.d.ts +5 -0
- package/dist/templates/agents/index.d.ts.map +1 -0
- package/dist/templates/agents/index.js +5 -0
- package/dist/templates/agents/index.js.map +1 -0
- package/dist/templates/agents/taskPlanner.d.ts +2 -0
- package/dist/templates/agents/taskPlanner.d.ts.map +1 -0
- package/dist/templates/agents/taskPlanner.js +47 -0
- package/dist/templates/agents/taskPlanner.js.map +1 -0
- package/dist/templates/engine.d.ts +9 -0
- package/dist/templates/engine.d.ts.map +1 -0
- package/dist/templates/engine.js +16 -0
- package/dist/templates/engine.js.map +1 -0
- package/dist/templates/files/index.d.ts +3 -0
- package/dist/templates/files/index.d.ts.map +1 -0
- package/dist/templates/files/index.js +51 -0
- package/dist/templates/files/index.js.map +1 -0
- package/dist/templates/instructions/architecture.d.ts +2 -0
- package/dist/templates/instructions/architecture.d.ts.map +1 -0
- package/dist/templates/instructions/architecture.js +50 -0
- package/dist/templates/instructions/architecture.js.map +1 -0
- package/dist/templates/instructions/deploy.d.ts +2 -0
- package/dist/templates/instructions/deploy.d.ts.map +1 -0
- package/dist/templates/instructions/deploy.js +53 -0
- package/dist/templates/instructions/deploy.js.map +1 -0
- package/dist/templates/instructions/index.d.ts +6 -0
- package/dist/templates/instructions/index.d.ts.map +1 -0
- package/dist/templates/instructions/index.js +6 -0
- package/dist/templates/instructions/index.js.map +1 -0
- package/dist/templates/instructions/security.d.ts +2 -0
- package/dist/templates/instructions/security.d.ts.map +1 -0
- package/dist/templates/instructions/security.js +43 -0
- package/dist/templates/instructions/security.js.map +1 -0
- package/dist/templates/instructions/style.d.ts +2 -0
- package/dist/templates/instructions/style.d.ts.map +1 -0
- package/dist/templates/instructions/style.js +45 -0
- package/dist/templates/instructions/style.js.map +1 -0
- package/dist/templates/instructions/testing.d.ts +2 -0
- package/dist/templates/instructions/testing.d.ts.map +1 -0
- package/dist/templates/instructions/testing.js +61 -0
- package/dist/templates/instructions/testing.js.map +1 -0
- package/dist/templates/registry.d.ts +13 -0
- package/dist/templates/registry.d.ts.map +1 -0
- package/dist/templates/registry.js +89 -0
- package/dist/templates/registry.js.map +1 -0
- package/dist/utils/fs.d.ts +16 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +88 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +68 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompt.d.ts +9 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +48 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/types.d.ts +68 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/validators/agents.d.ts +3 -0
- package/dist/validators/agents.d.ts.map +1 -0
- package/dist/validators/agents.js +40 -0
- package/dist/validators/agents.js.map +1 -0
- package/dist/validators/config.d.ts +12 -0
- package/dist/validators/config.d.ts.map +1 -0
- package/dist/validators/config.js +114 -0
- package/dist/validators/config.js.map +1 -0
- package/dist/validators/instructions.d.ts +10 -0
- package/dist/validators/instructions.d.ts.map +1 -0
- package/dist/validators/instructions.js +34 -0
- package/dist/validators/instructions.js.map +1 -0
- package/dist/validators/syncStatus.d.ts +9 -0
- package/dist/validators/syncStatus.d.ts.map +1 -0
- package/dist/validators/syncStatus.js +92 -0
- package/dist/validators/syncStatus.js.map +1 -0
- package/dist/validators/tasks.d.ts +3 -0
- package/dist/validators/tasks.d.ts.map +1 -0
- package/dist/validators/tasks.js +72 -0
- package/dist/validators/tasks.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Cortex CLI
|
|
2
|
+
|
|
3
|
+
`syntra` is a CLI that scaffolds, manages, validates, and syncs an AI-assisted development framework across tools like GitHub Copilot, Claude Code, and Cursor.
|
|
4
|
+
|
|
5
|
+
Core principle: **`ai/` is the source of truth**. Adapter folders (`.github/`, `.claude/`, `.cursor/`) are generated artifacts.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
### Run with npx
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx syntra init
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Global install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -g syntra
|
|
21
|
+
syntra --help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Local development usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm run build
|
|
28
|
+
node dist/index.js --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Canonical Structure
|
|
34
|
+
|
|
35
|
+
After `syntra init`, the framework is structured like this:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
project-root/
|
|
39
|
+
├── ai/
|
|
40
|
+
│ ├── config.yml
|
|
41
|
+
│ ├── instructions/
|
|
42
|
+
│ │ ├── architecture.instructions.md
|
|
43
|
+
│ │ ├── style.instructions.md
|
|
44
|
+
│ │ └── ...
|
|
45
|
+
│ ├── agents/
|
|
46
|
+
│ │ ├── code-generator.agent.md
|
|
47
|
+
│ │ ├── code-reviewer.agent.md
|
|
48
|
+
│ │ └── ...
|
|
49
|
+
│ ├── skills/
|
|
50
|
+
│ │ └── *.skill.md
|
|
51
|
+
│ └── tasks/
|
|
52
|
+
│ ├── active/
|
|
53
|
+
│ └── done/
|
|
54
|
+
│
|
|
55
|
+
├── .github/
|
|
56
|
+
├── .claude/
|
|
57
|
+
└── .cursor/
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You edit files in `ai/`, then run `syntra sync` to regenerate adapters.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Commands
|
|
65
|
+
|
|
66
|
+
## `syntra init`
|
|
67
|
+
|
|
68
|
+
Interactive setup:
|
|
69
|
+
|
|
70
|
+
- Scans project language/framework/package manager/CI
|
|
71
|
+
- Prompts for instruction templates and agents
|
|
72
|
+
- Prompts for adapter targets
|
|
73
|
+
- Creates `ai/` structure and config
|
|
74
|
+
- Runs initial adapter sync
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
syntra init
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## `syntra add <type> [name]`
|
|
83
|
+
|
|
84
|
+
Adds framework files from templates.
|
|
85
|
+
|
|
86
|
+
Supported types:
|
|
87
|
+
|
|
88
|
+
- `instruction`
|
|
89
|
+
- `agent`
|
|
90
|
+
- `task` (interactive)
|
|
91
|
+
- `skill`
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
syntra add instruction microfrontends
|
|
97
|
+
syntra add agent bug-fixer
|
|
98
|
+
syntra add task
|
|
99
|
+
syntra add skill api-pagination
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
If `sync.autoSync: true` in `ai/config.yml`, add operations trigger silent adapter sync.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## `syntra done <taskId>`
|
|
107
|
+
|
|
108
|
+
Moves a task from active to done:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
syntra done TASK-001
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## `syntra sync`
|
|
117
|
+
|
|
118
|
+
Generates tool-specific adapter files from canonical `ai/` files.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
syntra sync
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Target-specific sync:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
syntra sync --copilot
|
|
128
|
+
syntra sync --claude
|
|
129
|
+
syntra sync --cursor
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
What gets generated:
|
|
133
|
+
|
|
134
|
+
- Copilot: `.github/copilot-instructions.md` and `.github/agents/*.md`
|
|
135
|
+
- Claude: `.claude/CLAUDE.md`
|
|
136
|
+
- Cursor: `.cursor/rules/*.mdc`
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## `syntra validate`
|
|
141
|
+
|
|
142
|
+
Validates framework correctness and sync state.
|
|
143
|
+
|
|
144
|
+
Checks include:
|
|
145
|
+
|
|
146
|
+
- `ai/config.yml` schema basics
|
|
147
|
+
- instruction naming/format
|
|
148
|
+
- agent references to instructions
|
|
149
|
+
- task structure and references
|
|
150
|
+
- sync freshness/manual edit risk signals
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
syntra validate
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Exit behavior:
|
|
157
|
+
|
|
158
|
+
- exits with non-zero when errors are found
|
|
159
|
+
- warnings do not fail the process
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## `syntra template`
|
|
164
|
+
|
|
165
|
+
Save and list reusable templates.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
syntra template save my-team-template
|
|
169
|
+
syntra template list
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Saved templates are stored in:
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
~/.ai-fw/templates/
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Configuration
|
|
181
|
+
|
|
182
|
+
Main config file: `ai/config.yml`.
|
|
183
|
+
|
|
184
|
+
Typical sections:
|
|
185
|
+
|
|
186
|
+
- `project`: language/framework/package manager profile
|
|
187
|
+
- `adapters`: enabled adapters and instruction mode
|
|
188
|
+
- `sync`: auto-sync and manual edit warnings
|
|
189
|
+
- `tasks`: ID prefix and folders
|
|
190
|
+
- `language`: generation language
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Typical Workflow
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# 1) Initialize
|
|
198
|
+
syntra init
|
|
199
|
+
|
|
200
|
+
# 2) Customize instructions
|
|
201
|
+
$EDITOR ai/instructions/architecture.instructions.md
|
|
202
|
+
|
|
203
|
+
# 3) Add a task
|
|
204
|
+
syntra add task
|
|
205
|
+
|
|
206
|
+
# 4) Sync adapters
|
|
207
|
+
syntra sync
|
|
208
|
+
|
|
209
|
+
# 5) Execute task with your coding agent
|
|
210
|
+
# e.g. /TASK-001
|
|
211
|
+
|
|
212
|
+
# 6) Mark done
|
|
213
|
+
syntra done TASK-001
|
|
214
|
+
|
|
215
|
+
# 7) Validate setup
|
|
216
|
+
syntra validate
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Testing
|
|
222
|
+
|
|
223
|
+
Regression tests are included for core command behavior.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm test
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Status and Roadmap
|
|
232
|
+
|
|
233
|
+
Implemented:
|
|
234
|
+
|
|
235
|
+
- Phase 1 (init/add/done + templates + config)
|
|
236
|
+
- Phase 2 (adapter sync)
|
|
237
|
+
- Phase 3 core (validate + template save/list)
|
|
238
|
+
|
|
239
|
+
Planned next enhancements include additional template workflows and richer validation/polish.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAoBjE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fsUtils } from '../utils/fs.js';
|
|
3
|
+
import { loadCanonicalData, withGeneratedBanner, instructionTitle } from './common.js';
|
|
4
|
+
export function syncClaudeAdapter(rootPath) {
|
|
5
|
+
const data = loadCanonicalData(rootPath);
|
|
6
|
+
const outDir = path.join(rootPath, '.claude');
|
|
7
|
+
fsUtils.mkdir(outDir);
|
|
8
|
+
const instructionSections = data.instructions
|
|
9
|
+
.map((item) => `## ${instructionTitle(item.name)}\n\n${item.content}`)
|
|
10
|
+
.join('\n\n');
|
|
11
|
+
const agentSections = data.agents
|
|
12
|
+
.map((agent) => `### ${agent.name}\n\n${agent.content}`)
|
|
13
|
+
.join('\n\n');
|
|
14
|
+
const content = withGeneratedBanner(`# Project Context\n\nRead the following instruction files before any task:\n\n${instructionSections}\n\n## Available Agents\n\n${agentSections}\n\n## Task Format\nWhen given a task file, follow its steps sequentially. After each step:\n1. Implement the change\n2. Report what was done\n3. Wait for human review before proceeding\n`);
|
|
15
|
+
const outPath = path.join(outDir, 'CLAUDE.md');
|
|
16
|
+
fsUtils.writeFile(outPath, content);
|
|
17
|
+
return { writtenFiles: [outPath] };
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGvF,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAC9C,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtB,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;SACrE,IAAI,CAAC,MAAM,CAAC,CAAC;IAElB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM;SAC5B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;SACvD,IAAI,CAAC,MAAM,CAAC,CAAC;IAElB,MAAM,OAAO,GAAG,mBAAmB,CAAC,iFAAiF,mBAAmB,8BAA8B,aAAa,6LAA6L,CAAC,CAAC;IAElX,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/C,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEpC,OAAO,EAAE,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CanonicalData {
|
|
2
|
+
instructions: Array<{
|
|
3
|
+
name: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}>;
|
|
6
|
+
agents: Array<{
|
|
7
|
+
name: string;
|
|
8
|
+
content: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare function loadCanonicalData(rootPath: string): CanonicalData;
|
|
12
|
+
export declare function withGeneratedBanner(content: string): string;
|
|
13
|
+
export declare function instructionTitle(name: string): string;
|
|
14
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/adapters/common.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC1B,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA4BjE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fsUtils } from '../utils/fs.js';
|
|
3
|
+
export function loadCanonicalData(rootPath) {
|
|
4
|
+
const aiPath = path.join(rootPath, 'ai');
|
|
5
|
+
const instructionsDir = path.join(aiPath, 'instructions');
|
|
6
|
+
const agentsDir = path.join(aiPath, 'agents');
|
|
7
|
+
const instructions = fsUtils
|
|
8
|
+
.listFiles(instructionsDir, '.instructions.md')
|
|
9
|
+
.sort((a, b) => a.localeCompare(b))
|
|
10
|
+
.map((filePath) => {
|
|
11
|
+
const base = path.basename(filePath, '.instructions.md');
|
|
12
|
+
return {
|
|
13
|
+
name: base,
|
|
14
|
+
content: fsUtils.readFile(filePath).trim(),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
const agents = fsUtils
|
|
18
|
+
.listFiles(agentsDir, '.agent.md')
|
|
19
|
+
.sort((a, b) => a.localeCompare(b))
|
|
20
|
+
.map((filePath) => {
|
|
21
|
+
const base = path.basename(filePath, '.agent.md');
|
|
22
|
+
return {
|
|
23
|
+
name: base,
|
|
24
|
+
content: fsUtils.readFile(filePath).trim(),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
return { instructions, agents };
|
|
28
|
+
}
|
|
29
|
+
export function withGeneratedBanner(content) {
|
|
30
|
+
return `<!-- AUTO-GENERATED by syntra. Do not edit manually. Run \`syntra sync\` to update. -->\n\n${content}`;
|
|
31
|
+
}
|
|
32
|
+
export function instructionTitle(name) {
|
|
33
|
+
return name
|
|
34
|
+
.split('-')
|
|
35
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
36
|
+
.join(' ');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/adapters/common.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAOzC,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE9C,MAAM,YAAY,GAAG,OAAO;SACvB,SAAS,CAAC,eAAe,EAAE,kBAAkB,CAAC;SAC9C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QACzD,OAAO;YACH,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;SAC7C,CAAC;IACN,CAAC,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,OAAO;SACjB,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC;SACjC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAClD,OAAO;YACH,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;SAC7C,CAAC;IACN,CAAC,CAAC,CAAC;IAEP,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe;IAC/C,OAAO,8FAA8F,OAAO,EAAE,CAAC;AACnH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IACzC,OAAO,IAAI;SACN,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.d.ts","sourceRoot":"","sources":["../../src/adapters/copilot.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA0BlE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fsUtils } from '../utils/fs.js';
|
|
3
|
+
import { loadCanonicalData, withGeneratedBanner, instructionTitle } from './common.js';
|
|
4
|
+
export function syncCopilotAdapter(rootPath) {
|
|
5
|
+
const data = loadCanonicalData(rootPath);
|
|
6
|
+
const outDir = path.join(rootPath, '.github');
|
|
7
|
+
const agentsDir = path.join(outDir, 'agents');
|
|
8
|
+
fsUtils.mkdir(outDir);
|
|
9
|
+
fsUtils.mkdir(agentsDir);
|
|
10
|
+
const sections = data.instructions
|
|
11
|
+
.map((item) => `## ${instructionTitle(item.name)}\n\n${item.content}`)
|
|
12
|
+
.join('\n\n');
|
|
13
|
+
const copilotInstructions = withGeneratedBanner(`# Project Instructions\n\n${sections}\n`);
|
|
14
|
+
const instructionsPath = path.join(outDir, 'copilot-instructions.md');
|
|
15
|
+
fsUtils.writeFile(instructionsPath, copilotInstructions);
|
|
16
|
+
const writtenFiles = [instructionsPath];
|
|
17
|
+
for (const agent of data.agents) {
|
|
18
|
+
const content = withGeneratedBanner(`---\nname: ${agent.name}\ndescription: ${instructionTitle(agent.name)} agent\n---\n\n# ${instructionTitle(agent.name)}\n\n${agent.content}\n`);
|
|
19
|
+
const outPath = path.join(agentsDir, `${agent.name}.md`);
|
|
20
|
+
fsUtils.writeFile(outPath, content);
|
|
21
|
+
writtenFiles.push(outPath);
|
|
22
|
+
}
|
|
23
|
+
return { writtenFiles };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../src/adapters/copilot.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMvF,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEzB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY;SAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;SACrE,IAAI,CAAC,MAAM,CAAC,CAAC;IAElB,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,6BAA6B,QAAQ,IAAI,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACtE,OAAO,CAAC,SAAS,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;IAEzD,MAAM,YAAY,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,mBAAmB,CAAC,cAAc,KAAK,CAAC,IAAI,kBAAkB,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;QACpL,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QACzD,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMlD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAuBjE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fsUtils } from '../utils/fs.js';
|
|
3
|
+
import { loadCanonicalData, withGeneratedBanner, instructionTitle } from './common.js';
|
|
4
|
+
function toMdc(description, body) {
|
|
5
|
+
return withGeneratedBanner(`---\ndescription: ${description}\nglobs: [\"**/*\"]\n---\n\n${body}\n`);
|
|
6
|
+
}
|
|
7
|
+
export function syncCursorAdapter(rootPath) {
|
|
8
|
+
const data = loadCanonicalData(rootPath);
|
|
9
|
+
const rulesDir = path.join(rootPath, '.cursor', 'rules');
|
|
10
|
+
fsUtils.mkdir(rulesDir);
|
|
11
|
+
const writtenFiles = [];
|
|
12
|
+
for (const item of data.instructions) {
|
|
13
|
+
const outPath = path.join(rulesDir, `${item.name}.mdc`);
|
|
14
|
+
const content = toMdc(`${instructionTitle(item.name)} rules for this project`, item.content);
|
|
15
|
+
fsUtils.writeFile(outPath, content);
|
|
16
|
+
writtenFiles.push(outPath);
|
|
17
|
+
}
|
|
18
|
+
for (const agent of data.agents) {
|
|
19
|
+
const outPath = path.join(rulesDir, `${agent.name}.mdc`);
|
|
20
|
+
const content = toMdc(`${instructionTitle(agent.name)} agent rules`, agent.content);
|
|
21
|
+
fsUtils.writeFile(outPath, content);
|
|
22
|
+
writtenFiles.push(outPath);
|
|
23
|
+
}
|
|
24
|
+
return { writtenFiles };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGvF,SAAS,KAAK,CAAC,WAAmB,EAAE,IAAY;IAC5C,OAAO,mBAAmB,CAAC,qBAAqB,WAAW,+BAA+B,IAAI,IAAI,CAAC,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAC9C,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExB,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7F,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACpF,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Config } from '../utils/types.js';
|
|
2
|
+
export interface SyncOptions {
|
|
3
|
+
copilot?: boolean;
|
|
4
|
+
claude?: boolean;
|
|
5
|
+
cursor?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface SyncResult {
|
|
8
|
+
targets: string[];
|
|
9
|
+
writtenFiles: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function syncAdapters(rootPath: string, config: Config, options?: SyncOptions): SyncResult;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,MAAM,WAAW,WAAW;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CA2BpG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { syncCopilotAdapter } from './copilot.js';
|
|
2
|
+
import { syncClaudeAdapter } from './claude.js';
|
|
3
|
+
import { syncCursorAdapter } from './cursor.js';
|
|
4
|
+
export function syncAdapters(rootPath, config, options = {}) {
|
|
5
|
+
const shouldSyncCopilot = options.copilot ?? config.adapters.copilot.enabled;
|
|
6
|
+
const shouldSyncClaude = options.claude ?? config.adapters.claude.enabled;
|
|
7
|
+
const shouldSyncCursor = options.cursor ?? config.adapters.cursor.enabled;
|
|
8
|
+
const targets = [];
|
|
9
|
+
const writtenFiles = [];
|
|
10
|
+
if (shouldSyncCopilot) {
|
|
11
|
+
const result = syncCopilotAdapter(rootPath);
|
|
12
|
+
targets.push('copilot');
|
|
13
|
+
writtenFiles.push(...result.writtenFiles);
|
|
14
|
+
}
|
|
15
|
+
if (shouldSyncClaude) {
|
|
16
|
+
const result = syncClaudeAdapter(rootPath);
|
|
17
|
+
targets.push('claude');
|
|
18
|
+
writtenFiles.push(...result.writtenFiles);
|
|
19
|
+
}
|
|
20
|
+
if (shouldSyncCursor) {
|
|
21
|
+
const result = syncCursorAdapter(rootPath);
|
|
22
|
+
targets.push('cursor');
|
|
23
|
+
writtenFiles.push(...result.writtenFiles);
|
|
24
|
+
}
|
|
25
|
+
return { targets, writtenFiles };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAahD,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,MAAc,EAAE,UAAuB,EAAE;IACpF,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;IAC7E,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IAC1E,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IAE1E,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,IAAI,iBAAiB,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAQA,wBAAsB,UAAU,CAC5B,IAAI,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,EAChD,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,GAAE,MAAsB,GACjC,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { fsUtils } from '../utils/fs.js';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { prompt } from '../utils/prompt.js';
|
|
4
|
+
import { renderTemplate, listTemplates } from '../templates/registry.js';
|
|
5
|
+
import { loadConfig } from '../validators/config.js';
|
|
6
|
+
import { syncCommand } from './sync.js';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
export async function addCommand(type, name, rootPath = process.cwd()) {
|
|
9
|
+
const config = loadConfig(rootPath);
|
|
10
|
+
if (!config) {
|
|
11
|
+
logger.error('No syntra configuration found. Run `syntra init` first.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const aiPath = path.join(rootPath, 'ai');
|
|
15
|
+
if (type === 'instruction') {
|
|
16
|
+
await addInstruction(name, aiPath, config);
|
|
17
|
+
}
|
|
18
|
+
else if (type === 'agent') {
|
|
19
|
+
await addAgent(name, aiPath, config);
|
|
20
|
+
}
|
|
21
|
+
else if (type === 'task') {
|
|
22
|
+
await addTask(aiPath, config);
|
|
23
|
+
}
|
|
24
|
+
else if (type === 'skill') {
|
|
25
|
+
await addSkill(name, aiPath, config);
|
|
26
|
+
}
|
|
27
|
+
if (config.sync.autoSync) {
|
|
28
|
+
syncCommand(rootPath, { silent: true });
|
|
29
|
+
logger.info('Auto-sync completed.');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function addInstruction(name, aiPath, config) {
|
|
33
|
+
logger.section('Add Instruction');
|
|
34
|
+
if (!name) {
|
|
35
|
+
const templates = listTemplates('instruction');
|
|
36
|
+
const templateNames = templates.map((t) => t.name);
|
|
37
|
+
name = (await prompt({
|
|
38
|
+
message: 'Select instruction template:',
|
|
39
|
+
choices: templateNames,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
const templateData = {
|
|
43
|
+
projectProfile: {
|
|
44
|
+
language: config.project.language,
|
|
45
|
+
framework: config.project.framework,
|
|
46
|
+
packageManager: config.project.packageManager,
|
|
47
|
+
monorepo: config.project.monorepo,
|
|
48
|
+
cicd: [],
|
|
49
|
+
existingAi: { copilot: false, claude: false, cursor: false },
|
|
50
|
+
},
|
|
51
|
+
projectName: config.project.name,
|
|
52
|
+
};
|
|
53
|
+
const content = renderTemplate(name, templateData);
|
|
54
|
+
const filePath = path.join(aiPath, 'instructions', `${name}.instructions.md`);
|
|
55
|
+
fsUtils.writeFile(filePath, content);
|
|
56
|
+
logger.success(`Created: ai/instructions/${name}.instructions.md`);
|
|
57
|
+
}
|
|
58
|
+
async function addAgent(name, aiPath, config) {
|
|
59
|
+
logger.section('Add Agent');
|
|
60
|
+
if (!name) {
|
|
61
|
+
const templates = listTemplates('agent');
|
|
62
|
+
const templateNames = templates.map((t) => t.name);
|
|
63
|
+
name = (await prompt({
|
|
64
|
+
message: 'Select agent template:',
|
|
65
|
+
choices: templateNames,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
const templateData = {
|
|
69
|
+
projectProfile: {
|
|
70
|
+
language: config.project.language,
|
|
71
|
+
framework: config.project.framework,
|
|
72
|
+
packageManager: config.project.packageManager,
|
|
73
|
+
monorepo: config.project.monorepo,
|
|
74
|
+
cicd: [],
|
|
75
|
+
existingAi: { copilot: false, claude: false, cursor: false },
|
|
76
|
+
},
|
|
77
|
+
projectName: config.project.name,
|
|
78
|
+
};
|
|
79
|
+
const content = renderTemplate(name, templateData);
|
|
80
|
+
const filePath = path.join(aiPath, 'agents', `${name}.agent.md`);
|
|
81
|
+
fsUtils.writeFile(filePath, content);
|
|
82
|
+
logger.success(`Created: ai/agents/${name}.agent.md`);
|
|
83
|
+
}
|
|
84
|
+
async function addTask(aiPath, config) {
|
|
85
|
+
logger.section('Add Task');
|
|
86
|
+
const taskId = (await prompt({
|
|
87
|
+
message: 'Task ID (e.g., TASK-001):',
|
|
88
|
+
validate: (val) => {
|
|
89
|
+
return val.length > 0 ? true : 'Task ID is required';
|
|
90
|
+
},
|
|
91
|
+
}));
|
|
92
|
+
const description = (await prompt({
|
|
93
|
+
message: 'Short description:',
|
|
94
|
+
}));
|
|
95
|
+
const instructionTemplates = listTemplates('instruction');
|
|
96
|
+
const instructionNames = instructionTemplates.map((t) => t.name);
|
|
97
|
+
const instructions = (await prompt({
|
|
98
|
+
message: 'Which instructions apply?',
|
|
99
|
+
choices: instructionNames,
|
|
100
|
+
checkbox: true,
|
|
101
|
+
}));
|
|
102
|
+
const agentTemplates = listTemplates('agent');
|
|
103
|
+
const agentNames = agentTemplates.map((t) => t.name);
|
|
104
|
+
const agent = (await prompt({
|
|
105
|
+
message: 'Which agent runs this?',
|
|
106
|
+
choices: agentNames,
|
|
107
|
+
}));
|
|
108
|
+
const templateData = {
|
|
109
|
+
taskId,
|
|
110
|
+
description,
|
|
111
|
+
instructions,
|
|
112
|
+
agent,
|
|
113
|
+
steps: ['Step 1', 'Step 2', 'Step 3'],
|
|
114
|
+
acceptanceCriteria: ['Criterion 1', 'Criterion 2'],
|
|
115
|
+
projectProfile: {
|
|
116
|
+
language: config.project.language,
|
|
117
|
+
framework: config.project.framework,
|
|
118
|
+
packageManager: config.project.packageManager,
|
|
119
|
+
monorepo: config.project.monorepo,
|
|
120
|
+
cicd: [],
|
|
121
|
+
existingAi: { copilot: false, claude: false, cursor: false },
|
|
122
|
+
},
|
|
123
|
+
projectName: config.project.name,
|
|
124
|
+
};
|
|
125
|
+
const content = renderTemplate('task', templateData);
|
|
126
|
+
const filePath = path.join(aiPath, 'tasks', 'active', `${taskId}.task.md`);
|
|
127
|
+
fsUtils.writeFile(filePath, content);
|
|
128
|
+
logger.success(`Created: ai/tasks/active/${taskId}.task.md`);
|
|
129
|
+
}
|
|
130
|
+
async function addSkill(name, aiPath, config) {
|
|
131
|
+
logger.section('Add Skill');
|
|
132
|
+
if (!name) {
|
|
133
|
+
name = (await prompt({
|
|
134
|
+
message: 'Skill name (e.g., api-pagination):',
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
const templateData = {
|
|
138
|
+
projectProfile: {
|
|
139
|
+
language: config.project.language,
|
|
140
|
+
framework: config.project.framework,
|
|
141
|
+
packageManager: config.project.packageManager,
|
|
142
|
+
monorepo: config.project.monorepo,
|
|
143
|
+
cicd: [],
|
|
144
|
+
existingAi: { copilot: false, claude: false, cursor: false },
|
|
145
|
+
},
|
|
146
|
+
projectName: config.project.name,
|
|
147
|
+
skillName: name,
|
|
148
|
+
};
|
|
149
|
+
const content = renderTemplate('skill', templateData);
|
|
150
|
+
const filePath = path.join(aiPath, 'skills', `${name}.skill.md`);
|
|
151
|
+
fsUtils.writeFile(filePath, content);
|
|
152
|
+
logger.success(`Created: ai/skills/${name}.skill.md`);
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"done.d.ts","sourceRoot":"","sources":["../../src/commands/done.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAsB,GAAG,IAAI,CAgBlF"}
|