@aiderdesk/aiderdesk 0.61.0-dev → 0.61.1
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/out/renderer/assets/__vite-browser-external-2447137e-DYxpcVy9.js +4 -0
- package/out/renderer/assets/{_baseUniq-Z8t1Ab1g.js → _baseUniq-BPF2Herp.js} +21 -197
- package/out/renderer/assets/{arc-CwESpVYE.js → arc-DfPLteHF.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-2XIMDMQ5-C490EQr5.js → architectureDiagram-Q4EWVU46-Bw0u-sSH.js} +34 -20
- package/out/renderer/assets/{blockDiagram-WCTKOSBZ-DbHssxrQ.js → blockDiagram-DXYQGD6D-CkfB9if8.js} +21 -8
- package/out/renderer/assets/{c4Diagram-IC4MRINW-BxE3GUKu.js → c4Diagram-AHTNJAMY-DweK9Liz.js} +31 -35
- package/out/renderer/assets/{channel-C9hJq_Xr.js → channel-C5wwrRof.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-ChcKNpL6.js → chunk-4BX2VUAB-0KM14cFd.js} +1 -1
- package/out/renderer/assets/{chunk-WL4C6EOR-vhby2fZi.js → chunk-4TB4RGXK-CmVtCVL4.js} +121 -82
- package/out/renderer/assets/{chunk-55IACEB6-oLT9lXTt.js → chunk-55IACEB6-BzVYZvBM.js} +1 -1
- package/out/renderer/assets/{chunk-KX2RTZJC-D32tV7H-.js → chunk-EDXVE4YY-BryQl5Kv.js} +1 -1
- package/out/renderer/assets/{chunk-FMBD7UC4-B5k8rETe.js → chunk-FMBD7UC4-CRiLea_e.js} +1 -1
- package/out/renderer/assets/{chunk-NQ4KR5QH-Bmqo2FpL.js → chunk-OYMX7WX6-Cpi4N3NO.js} +32 -15
- package/out/renderer/assets/{chunk-QZHKN3VN-8BpGifjS.js → chunk-QZHKN3VN-BT8kABWC.js} +1 -1
- package/out/renderer/assets/{chunk-JSJVCQXG-DtjSx6Cj.js → chunk-YZCP3GAM-OLZV_Sef.js} +1 -1
- package/out/renderer/assets/{classDiagram-VBA2DB6C-BxRSSb9e.js → classDiagram-6PBFFD2Q-VdE6G90i.js} +6 -6
- package/out/renderer/assets/{classDiagram-v2-RAHNMMFH-BxRSSb9e.js → classDiagram-v2-HSJHXN6E-VdE6G90i.js} +6 -6
- package/out/renderer/assets/{clone-D9a-uIZa.js → clone-DwQZ86nS.js} +1 -1
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-CUqqQ-6R.js → cose-bilkent-S5V4N54A-BEcAKM9H.js} +1 -1
- package/out/renderer/assets/{dagre-KLK3FWXG-ORIwMMhq.js → dagre-KV5264BT-BcFQYL1M.js} +6 -6
- package/out/renderer/assets/diagram-5BDNPKRD-GrUNdC1u.js +171 -0
- package/out/renderer/assets/{diagram-E7M64L7V-bS9HcoDQ.js → diagram-G4DWMVQ6-CG4S-ov5.js} +15 -13
- package/out/renderer/assets/{diagram-IFDJBPK2-BRlTIR0J.js → diagram-MMDJMWI5-9ogY3MRC.js} +5 -6
- package/out/renderer/assets/{diagram-P4PSJMXO-jsjGwH-p.js → diagram-TYMM5635-Ck7mI1bS.js} +5 -6
- package/out/renderer/assets/{erDiagram-INFDFZHY-DGlgjHOQ.js → erDiagram-SMLLAGMA-Dvf_c-7M.js} +81 -35
- package/out/renderer/assets/{flowDiagram-PKNHOUZH-CzLC87bM.js → flowDiagram-DWJPFMVM-CPDjOXYp.js} +27 -45
- package/out/renderer/assets/{ganttDiagram-A5KZAMGK-BbDv36wT.js → ganttDiagram-T4ZO3ILL-B4dJrK-3.js} +17 -8
- package/out/renderer/assets/{gitGraphDiagram-K3NZZRJ6-CBQnBjEi.js → gitGraphDiagram-UUTBAWPF-De2eCfMN.js} +244 -67
- package/out/renderer/assets/{graph-Dl5N6maZ.js → graph-BFn23kR_.js} +175 -3
- package/out/renderer/assets/{index-MDHavDF9.js → index-BL-57WPa.js} +15877 -20787
- package/out/renderer/assets/{index-CDCy_DhA.css → index-BkntVzTm.css} +114 -301
- package/out/renderer/assets/{infoDiagram-LFFYTUFH-GtEDBEmz.js → infoDiagram-42DDH7IO-BIt9B6mQ.js} +5 -6
- package/out/renderer/assets/{ishikawaDiagram-PHBUUO56-Uj90gr3I.js → ishikawaDiagram-UXIWVN3A-CXZs0KGV.js} +3 -3
- package/out/renderer/assets/{journeyDiagram-4ABVD52K-DekFuOwS.js → journeyDiagram-VCZTEJTY-B-EXuj5b.js} +14 -13
- package/out/renderer/assets/{kanban-definition-K7BYSVSG-Hfz2L6NS.js → kanban-definition-6JOO6SKY-ByvN0qaD.js} +5 -2
- package/out/renderer/assets/{layout-B9K2VT39.js → layout-BpybWUv6.js} +117 -4
- package/out/renderer/assets/min-DB8ixvoT.js +41 -0
- package/out/renderer/assets/{mindmap-definition-YRQLILUH-DDcS7_GH.js → mindmap-definition-QFDTVHPH-Do-I-At8.js} +69 -13
- package/out/renderer/assets/{pieDiagram-SKSYHLDU-DwjEcJ0Q.js → pieDiagram-DEJITSTG-Cnpf6Gt6.js} +20 -13
- package/out/renderer/assets/{quadrantDiagram-337W2JSQ-CpGqN7vo.js → quadrantDiagram-34T5L4WZ-VcOb1qLd.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-Z7DCOOCP-qDRUf1ip.js → requirementDiagram-MS252O5E-VJs9Hpaw.js} +42 -11
- package/out/renderer/assets/{sankeyDiagram-WA2Y5GQK-DRKS8C1H.js → sankeyDiagram-XADWPNL6-BoXxgLvi.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-2WXFIKYE-DhVN2ug2.js → sequenceDiagram-FGHM5R23-b69hQjSp.js} +446 -220
- package/out/renderer/assets/{stateDiagram-RAJIS63D-BpP4eSqu.js → stateDiagram-FHFEXIEX-BK7E-REm.js} +10 -9
- package/out/renderer/assets/{stateDiagram-v2-FVOUBMTO-B_qQJqra.js → stateDiagram-v2-QKLJ7IA2-Cd2wfCQu.js} +4 -4
- package/out/renderer/assets/{timeline-definition-YZTLITO2-UoWXE_76.js → timeline-definition-GMOUNBTQ-Bl-MTfK5.js} +445 -71
- package/out/renderer/assets/{vennDiagram-LZ73GAT5-Dp1FZ609.js → vennDiagram-DHZGUBPP-DNmr1k2L.js} +1 -1
- package/out/renderer/assets/{treemap-KZPCXAKY-W2a2L6ff.js → wardley-RL74JXVD-DTbxPMj9.js} +1474 -977
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-BWw08wtD.js +901 -0
- package/out/renderer/assets/{xychartDiagram-JWTSCODW-CTzYHTbD.js → xychartDiagram-5P7HB3ND-EEYPnLDT.js} +20 -4
- package/out/renderer/index.html +3 -3
- package/out/renderer/progress.html +212 -62
- package/out/resources/mcp-server/aider-desk-mcp-server.js +642 -402
- package/out/resources/skills/extension-creator/SKILL.md +320 -0
- package/out/resources/skills/extension-creator/assets/templates/Component.jsx.template +76 -0
- package/out/resources/skills/extension-creator/assets/templates/ConfigComponent.jsx.template +38 -0
- package/out/resources/skills/extension-creator/assets/templates/folder-extension/config.ts.template +29 -0
- package/out/resources/skills/extension-creator/assets/templates/folder-extension/index.ts.template +42 -0
- package/out/resources/skills/extension-creator/assets/templates/folder-extension/package.json +12 -0
- package/out/resources/skills/extension-creator/assets/templates/folder-extension/tsconfig.json +23 -0
- package/out/resources/skills/extension-creator/assets/templates/folder-extension-with-config/index.ts.template +80 -0
- package/out/resources/skills/extension-creator/assets/templates/single-file.ts.template +30 -0
- package/out/resources/skills/extension-creator/assets/templates/ui-component-external.ts.template +91 -0
- package/out/resources/skills/extension-creator/assets/templates/ui-component.ts.template +79 -0
- package/out/resources/skills/extension-creator/references/command-definition.md +170 -0
- package/out/resources/skills/extension-creator/references/config-components.md +427 -0
- package/out/resources/skills/extension-creator/references/event-types.md +156 -0
- package/out/resources/skills/extension-creator/references/examples-gallery.md +583 -0
- package/out/resources/skills/extension-creator/references/extension-interface.md +240 -0
- package/out/resources/skills/extension-creator/references/extension-types.md +186 -0
- package/out/resources/skills/extension-creator/references/in-repo-flow.md +132 -0
- package/out/resources/skills/extension-creator/references/install-targets.md +96 -0
- package/out/resources/skills/extension-creator/references/project-global-flow.md +76 -0
- package/out/resources/skills/extension-creator/references/ui-components.md +663 -0
- package/out/runner.js +976 -386
- package/package.json +2 -3
- package/out/renderer/assets/_basePickBy-BWoXHZ8Z.js +0 -161
- package/out/renderer/assets/apl-fqmucPXA.js +0 -140
- package/out/renderer/assets/asciiarmor-DucZyvP0.js +0 -56
- package/out/renderer/assets/asn1-BnOEsgAm.js +0 -144
- package/out/renderer/assets/asterisk-QAlztEwS.js +0 -345
- package/out/renderer/assets/brainfuck-DZVCuF_t.js +0 -53
- package/out/renderer/assets/clike-xqXYL6ge.js +0 -805
- package/out/renderer/assets/clojure-BhXMqnxz.js +0 -849
- package/out/renderer/assets/cmake-BGaNd9E7.js +0 -71
- package/out/renderer/assets/cobol-4yqQntpt.js +0 -120
- package/out/renderer/assets/coffeescript-D2dXvhEc.js +0 -308
- package/out/renderer/assets/commonlisp-CF_VNHQR.js +0 -130
- package/out/renderer/assets/crystal-DyuLTqLs.js +0 -398
- package/out/renderer/assets/css-c-jst79C.js +0 -1783
- package/out/renderer/assets/cypher-Dlu_3r4V.js +0 -121
- package/out/renderer/assets/d-UURgV0Ux.js +0 -179
- package/out/renderer/assets/diff-B_Bi2Crb.js +0 -25
- package/out/renderer/assets/dockerfile-Bvk733Ga.js +0 -201
- package/out/renderer/assets/dtd-Dy74G54E.js +0 -114
- package/out/renderer/assets/dylan-TSb-Nfix.js +0 -314
- package/out/renderer/assets/ebnf-4fKAGW3a.js +0 -140
- package/out/renderer/assets/ecl-B59qGGVg.js +0 -178
- package/out/renderer/assets/eiffel-Dze7nlu3.js +0 -134
- package/out/renderer/assets/elm-DG7jkhNZ.js +0 -176
- package/out/renderer/assets/erlang-BO6gOnGA.js +0 -674
- package/out/renderer/assets/factor-CMxFHDqz.js +0 -65
- package/out/renderer/assets/fcl-CDDUNjTj.js +0 -141
- package/out/renderer/assets/forth-B9D2JCeE.js +0 -116
- package/out/renderer/assets/fortran-CAG2BFbe.js +0 -467
- package/out/renderer/assets/gas-d3KEcW3x.js +0 -294
- package/out/renderer/assets/gherkin-DhZlEZiy.js +0 -115
- package/out/renderer/assets/groovy-CpwJiBl7.js +0 -223
- package/out/renderer/assets/haskell-ySd-OUo8.js +0 -459
- package/out/renderer/assets/haxe-7MlzfeYV.js +0 -514
- package/out/renderer/assets/http-BqypyemW.js +0 -79
- package/out/renderer/assets/idl-4HIGJlDI.js +0 -985
- package/out/renderer/assets/index-6qedlt0q.js +0 -689
- package/out/renderer/assets/index-86jDpUJn.js +0 -385
- package/out/renderer/assets/index-BRjO8ber.js +0 -332
- package/out/renderer/assets/index-BVgw7j0d.js +0 -312
- package/out/renderer/assets/index-BhkyI1q3.js +0 -642
- package/out/renderer/assets/index-BqrmLPkg.js +0 -82
- package/out/renderer/assets/index-BuPbw4xM.js +0 -178
- package/out/renderer/assets/index-CTO-LPBg.js +0 -311
- package/out/renderer/assets/index-CTO4SzlI.js +0 -97
- package/out/renderer/assets/index-CZ9IQK_0.js +0 -2488
- package/out/renderer/assets/index-CZxsVxBZ.js +0 -1765
- package/out/renderer/assets/index-DIXV-3Xn.js +0 -406
- package/out/renderer/assets/index-DNzOtZX5.js +0 -61
- package/out/renderer/assets/index-DZtJe7oC.js +0 -1019
- package/out/renderer/assets/index-DaWjZz_g.js +0 -291
- package/out/renderer/assets/index-De056HHR.js +0 -151
- package/out/renderer/assets/index-Dk3wSDSN.js +0 -117
- package/out/renderer/assets/index-Dy4VRsnA.js +0 -1041
- package/out/renderer/assets/index-FnnayPBc.js +0 -82
- package/out/renderer/assets/index-MZb_zy6R.js +0 -704
- package/out/renderer/assets/index-chzQl8rJ.js +0 -157
- package/out/renderer/assets/index-s-Owx3Pm.js +0 -327
- package/out/renderer/assets/javascript-C_OHM9hj.js +0 -994
- package/out/renderer/assets/julia-Bs6JJhYG.js +0 -407
- package/out/renderer/assets/livescript-DmzgM3Yt.js +0 -296
- package/out/renderer/assets/lua-8cJgIlqe.js +0 -256
- package/out/renderer/assets/mathematica-DNLOL9PQ.js +0 -110
- package/out/renderer/assets/mbox-Ga7d4MMN.js +0 -117
- package/out/renderer/assets/mirc-Dma3B8rS.js +0 -107
- package/out/renderer/assets/mllike-DHn7xckP.js +0 -334
- package/out/renderer/assets/modelica-0d55jYY0.js +0 -147
- package/out/renderer/assets/mscgen-DdqZYINH.js +0 -135
- package/out/renderer/assets/mumps-Btr8VblO.js +0 -93
- package/out/renderer/assets/nginx-DTDtBDVN.js +0 -141
- package/out/renderer/assets/nsis-3zG7tgur.js +0 -62
- package/out/renderer/assets/ntriples-CvgOYMpL.js +0 -153
- package/out/renderer/assets/octave-DYBj3-tl.js +0 -200
- package/out/renderer/assets/oz-R_e8WMIi.js +0 -231
- package/out/renderer/assets/pascal-GD8iposT.js +0 -105
- package/out/renderer/assets/perl-DL9mHpoi.js +0 -1105
- package/out/renderer/assets/pig-C_4T4YIV.js +0 -101
- package/out/renderer/assets/powershell-B0suO7Vd.js +0 -328
- package/out/renderer/assets/properties-BR-vP1aU.js +0 -58
- package/out/renderer/assets/protobuf-BxgpyhoW.js +0 -77
- package/out/renderer/assets/pug-CTXt1f8z.js +0 -405
- package/out/renderer/assets/puppet-Bdao66PW.js +0 -137
- package/out/renderer/assets/python-CvWbmiX4.js +0 -427
- package/out/renderer/assets/q-CrbCVq4a.js +0 -131
- package/out/renderer/assets/r-V7nswm59.js +0 -170
- package/out/renderer/assets/rpm-C-DLY-If.js +0 -109
- package/out/renderer/assets/ruby-JDKLJNK0.js +0 -330
- package/out/renderer/assets/sas-D2UG-yhZ.js +0 -207
- package/out/renderer/assets/scheme-BKzrkGJD.js +0 -222
- package/out/renderer/assets/shell-BlsXDxCn.js +0 -222
- package/out/renderer/assets/sieve-CjwBwOY5.js +0 -135
- package/out/renderer/assets/simple-mode-DMneyfDu.js +0 -130
- package/out/renderer/assets/smalltalk-BOIGQuhN.js +0 -121
- package/out/renderer/assets/solr-CwD7U71z.js +0 -69
- package/out/renderer/assets/sparql-DYskk2vE.js +0 -249
- package/out/renderer/assets/spreadsheet-Bgtt3oLP.js +0 -87
- package/out/renderer/assets/sql-BSrOzCRI.js +0 -354
- package/out/renderer/assets/stex-B6LNC55o.js +0 -231
- package/out/renderer/assets/stylus-BkS-boTH.js +0 -565
- package/out/renderer/assets/swift-FRZi1uvB.js +0 -291
- package/out/renderer/assets/tcl-CUcaCdmq.js +0 -114
- package/out/renderer/assets/textile-BnFpjsrl.js +0 -414
- package/out/renderer/assets/tiddlywiki-CjprD-Qp.js +0 -218
- package/out/renderer/assets/tiki-DK9DOeWn.js +0 -268
- package/out/renderer/assets/toml-BOuWGMcf.js +0 -76
- package/out/renderer/assets/troff-E1bJ0PPL.js +0 -61
- package/out/renderer/assets/ttcn-cfg-Dc39-fIP.js +0 -133
- package/out/renderer/assets/ttcn-tKd4HLu4.js +0 -192
- package/out/renderer/assets/turtle-Dq7-1WAf.js +0 -124
- package/out/renderer/assets/vb-Dp90gtsv.js +0 -196
- package/out/renderer/assets/vbscript-CI6_mxxU.js +0 -479
- package/out/renderer/assets/velocity-BwIZK1TH.js +0 -149
- package/out/renderer/assets/verilog-DDCYnHN8.js +0 -430
- package/out/renderer/assets/vhdl-DCkMIyT9.js +0 -158
- package/out/renderer/assets/webidl-BTLTThCm.js +0 -204
- package/out/renderer/assets/xquery-BrBUuxMR.js +0 -525
- package/out/renderer/assets/yacas-b5lAVEIl.js +0 -130
- package/out/renderer/assets/z80-BZV19vqv.js +0 -93
- package/scripts/download-uv.mjs +0 -147
- /package/patches/{ai+5.0.161.patch → ai+5.0.167.patch} +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: extension-creator
|
|
3
|
+
description: Create AiderDesk extensions by setting up extension files, defining metadata, implementing Extension interface methods, and updating documentation. Use when building a new extension, creating extension commands, tools, or event handlers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Extension Creator
|
|
7
|
+
|
|
8
|
+
Create AiderDesk extensions that extend functionality through events, commands, tools, agents, and modes.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
Use this skill when:
|
|
13
|
+
|
|
14
|
+
- Building a new AiderDesk extension
|
|
15
|
+
- Creating extension commands, tools, or event handlers
|
|
16
|
+
- Implementing the Extension interface
|
|
17
|
+
- Setting up extension metadata and documentation
|
|
18
|
+
|
|
19
|
+
Do not use when:
|
|
20
|
+
|
|
21
|
+
- Simply activating an existing extension
|
|
22
|
+
- Making general code changes unrelated to extensions
|
|
23
|
+
- Running tests or builds
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
### Rule: Choose installation target first
|
|
28
|
+
|
|
29
|
+
**When:** Starting extension creation
|
|
30
|
+
|
|
31
|
+
**Then:** Ask the user where to install the extension
|
|
32
|
+
|
|
33
|
+
**If:** Working inside the AiderDesk project (the current project is the aider-desk repository)
|
|
34
|
+
|
|
35
|
+
**Then:** Offer three options:
|
|
36
|
+
1. **Current Project** — Install to `.aider-desk/extensions/` in the current project (project-scoped)
|
|
37
|
+
2. **Global** — Install to `~/.aider-desk/extensions/` (available in all projects)
|
|
38
|
+
3. **In-Repo** — Create inside `packages/extensions/extensions/` (ships with AiderDesk app)
|
|
39
|
+
|
|
40
|
+
**If:** Working outside the AiderDesk project
|
|
41
|
+
|
|
42
|
+
**Then:** Offer two options:
|
|
43
|
+
1. **Current Project** — Install to `.aider-desk/extensions/` in the current project (project-scoped)
|
|
44
|
+
2. **Global** — Install to `~/.aider-desk/extensions/` (available in all projects)
|
|
45
|
+
|
|
46
|
+
**Must:** Wait for user's choice before proceeding. The chosen target determines the entire workflow.
|
|
47
|
+
|
|
48
|
+
**Reference:** [references/install-targets.md](references/install-targets.md) for full details on each target.
|
|
49
|
+
|
|
50
|
+
### Rule: Follow the correct flow for the chosen target
|
|
51
|
+
|
|
52
|
+
**When:** User has chosen an installation target
|
|
53
|
+
|
|
54
|
+
**If:** Target is **Current Project** or **Global**
|
|
55
|
+
|
|
56
|
+
**Then:** Follow the [Project / Global Flow](references/project-global-flow.md):
|
|
57
|
+
1. Determine extension type (single-file or folder)
|
|
58
|
+
2. Create extension file(s) in the target directory (`.aider-desk/extensions/` or `~/.aider-desk/extensions/`)
|
|
59
|
+
3. Implement Extension interface methods
|
|
60
|
+
4. Export metadata and default class
|
|
61
|
+
5. Verify the extension loads (auto-discovered, no registry needed)
|
|
62
|
+
|
|
63
|
+
**If:** Target is **In-Repo**
|
|
64
|
+
|
|
65
|
+
**Then:** Follow the [In-Repo Flow](references/in-repo-flow.md):
|
|
66
|
+
1. Determine extension type (single-file or folder)
|
|
67
|
+
2. Create extension file(s) in `packages/extensions/extensions/`
|
|
68
|
+
3. Implement Extension interface methods
|
|
69
|
+
4. Export metadata and default class
|
|
70
|
+
5. **Register in `packages/extensions/extensions.json`**
|
|
71
|
+
6. **Document in `docs-site/docs/extensions/examples.md`**
|
|
72
|
+
7. Install npm dependencies if folder extension
|
|
73
|
+
8. Verify with type checking
|
|
74
|
+
|
|
75
|
+
### Rule: Determine extension type
|
|
76
|
+
|
|
77
|
+
**When:** Creating extension files (after target is chosen)
|
|
78
|
+
|
|
79
|
+
**Then:** Check if extension needs npm dependencies or multiple files
|
|
80
|
+
|
|
81
|
+
**If:** Extension needs dependencies or multiple files
|
|
82
|
+
|
|
83
|
+
**Then:** Create folder extension
|
|
84
|
+
|
|
85
|
+
**If:** Extension is simple with no dependencies
|
|
86
|
+
|
|
87
|
+
**Then:** Create single-file extension
|
|
88
|
+
|
|
89
|
+
### Rule: Implement Extension interface
|
|
90
|
+
|
|
91
|
+
**When:** Creating extension file
|
|
92
|
+
|
|
93
|
+
**Then:** Implement required methods from Extension interface
|
|
94
|
+
|
|
95
|
+
**Must:** Define `static metadata` property on the class with name, version, description, author, capabilities
|
|
96
|
+
|
|
97
|
+
**Must:** Export class as `default` (e.g., `export default class MyExtension implements Extension`)
|
|
98
|
+
|
|
99
|
+
**Never:** Use `@/` imports in extension files
|
|
100
|
+
|
|
101
|
+
### Rule: Add UI components when needed
|
|
102
|
+
|
|
103
|
+
**When:** Extension needs to display UI elements in task page placements
|
|
104
|
+
|
|
105
|
+
**Then:** Implement `getUIComponents()` method
|
|
106
|
+
|
|
107
|
+
**Must:** Return array of UIComponentDefinition objects with id, placement, jsx
|
|
108
|
+
|
|
109
|
+
**Must:** Define components as JSX strings or load from .jsx files
|
|
110
|
+
|
|
111
|
+
**If:** Component needs data, set `loadData: true` and implement `getUIExtensionData()`
|
|
112
|
+
|
|
113
|
+
**If:** Component triggers actions, implement `executeUIExtensionAction()`
|
|
114
|
+
|
|
115
|
+
### Rule: Add config component for extension settings
|
|
116
|
+
|
|
117
|
+
**When:** Extension needs user-configurable settings (shown in gear icon dialog)
|
|
118
|
+
|
|
119
|
+
**Then:** Implement three methods: `getConfigComponent()`, `getConfigData()`, `saveConfigData()`
|
|
120
|
+
|
|
121
|
+
**Must:** Return JSX string from `getConfigComponent()` — use external .jsx file for components > 20 lines
|
|
122
|
+
|
|
123
|
+
**Must:** Load/merge defaults in `getConfigData()`, persist merged data in `saveConfigData()`
|
|
124
|
+
|
|
125
|
+
**Must:** Store config file in extension directory via `join(__dirname, 'config.json')`
|
|
126
|
+
|
|
127
|
+
**Must:** Use `ui.*` components (`ui.Input`, `ui.Checkbox`, etc.) instead of raw HTML elements
|
|
128
|
+
|
|
129
|
+
**Should:** Avoid inner state (`useState`/`useEffect`) for simple form fields — read directly from `config` prop, call `updateConfig` on change. Only use local state for derived values or transient UI state.
|
|
130
|
+
|
|
131
|
+
**Never:** Use `'extension-settings'` placement — it was removed; use the dedicated config API instead
|
|
132
|
+
|
|
133
|
+
### Rule: Update registry and docs (In-Repo only)
|
|
134
|
+
|
|
135
|
+
**When:** Target is In-Repo and extension file is created
|
|
136
|
+
|
|
137
|
+
**Then:** Add entry to `packages/extensions/extensions.json`
|
|
138
|
+
|
|
139
|
+
**Must:** Include id, name, description, file or folder path, type, capabilities
|
|
140
|
+
|
|
141
|
+
**Must:** Set `hasDependencies: true` for folder extensions
|
|
142
|
+
|
|
143
|
+
**Then:** Add entry to `docs-site/docs/extensions/examples.md` table
|
|
144
|
+
|
|
145
|
+
**Must:** Include extension name, description, capabilities, and type
|
|
146
|
+
|
|
147
|
+
**When:** Target is Project or Global
|
|
148
|
+
|
|
149
|
+
**Then:** Do NOT modify `extensions.json` or `examples.md` — these are only for built-in extensions
|
|
150
|
+
|
|
151
|
+
### Rule: Use proper TypeScript config for folders
|
|
152
|
+
|
|
153
|
+
**When:** Creating folder extension
|
|
154
|
+
|
|
155
|
+
**Then:** Include `tsconfig.json` with `module: ES2020+`
|
|
156
|
+
|
|
157
|
+
**Must:** Include `package.json` with name, version, main, dependencies
|
|
158
|
+
|
|
159
|
+
### Rule: Store config in extension directory
|
|
160
|
+
|
|
161
|
+
**When:** Extension needs persistent config
|
|
162
|
+
|
|
163
|
+
**Then:** Store config files in extension directory
|
|
164
|
+
|
|
165
|
+
**Never:** Store config outside extension directory
|
|
166
|
+
|
|
167
|
+
## Process Overview
|
|
168
|
+
|
|
169
|
+
### For Project / Global targets:
|
|
170
|
+
|
|
171
|
+
1. Ask user: Current Project or Global?
|
|
172
|
+
2. Determine extension type (single-file or folder)
|
|
173
|
+
3. Create extension file or directory structure in target dir
|
|
174
|
+
4. Implement Extension interface methods
|
|
175
|
+
5. Export metadata and default class
|
|
176
|
+
6. Verify extension loads (auto-discovered)
|
|
177
|
+
|
|
178
|
+
**Between steps 3 and 5:**
|
|
179
|
+
- If extension needs config storage, create config.ts (or use inline getConfigData/saveConfigData)
|
|
180
|
+
- If extension has a settings UI (config component), create ConfigComponent.jsx and implement the three config methods
|
|
181
|
+
- If extension needs logging, create logger.ts
|
|
182
|
+
- If extension needs constants, create constants.ts
|
|
183
|
+
- If extension has placement-based UI components, create .jsx files for components (recommended for components > 20 lines)
|
|
184
|
+
|
|
185
|
+
### For In-Repo target:
|
|
186
|
+
|
|
187
|
+
1. Confirm user wants In-Repo (only available in aider-desk project)
|
|
188
|
+
2. Determine extension type (single-file or folder)
|
|
189
|
+
3. Create extension file or directory structure in `packages/extensions/extensions/`
|
|
190
|
+
4. Implement Extension interface methods
|
|
191
|
+
5. Export metadata and default class
|
|
192
|
+
6. **Register in `packages/extensions/extensions.json`**
|
|
193
|
+
7. **Document in `docs-site/docs/extensions/examples.md`**
|
|
194
|
+
8. Run `npm install` in `packages/extensions/` (folder extensions)
|
|
195
|
+
9. Verify with type checking
|
|
196
|
+
|
|
197
|
+
**Between steps 3 and 5:**
|
|
198
|
+
- Same optional files as Project/Global flow above
|
|
199
|
+
|
|
200
|
+
## Preconditions
|
|
201
|
+
|
|
202
|
+
Before using this skill, verify:
|
|
203
|
+
|
|
204
|
+
- Installation target has been chosen by the user
|
|
205
|
+
- Extension purpose and required capabilities are clear
|
|
206
|
+
- Extension type (single-file or folder) is determined
|
|
207
|
+
- Extension interface and types are understood
|
|
208
|
+
|
|
209
|
+
If any precondition fails:
|
|
210
|
+
|
|
211
|
+
- Review [packages/common/src/extensions.ts](https://raw.githubusercontent.com/hotovo/aider-desk/refs/heads/main/packages/common/src/extensions.ts) for types
|
|
212
|
+
- Check [references/install-targets.md](references/install-targets.md) for target options
|
|
213
|
+
- Check [references/event-types.md](references/event-types.md) for event types
|
|
214
|
+
- Check [references/command-definition.md](references/command-definition.md) for command structure
|
|
215
|
+
|
|
216
|
+
## Postconditions
|
|
217
|
+
|
|
218
|
+
After completing this skill, verify:
|
|
219
|
+
|
|
220
|
+
- Extension implements Extension interface correctly
|
|
221
|
+
- Static `metadata` property on the class includes all required fields (name, version)
|
|
222
|
+
- Default export is the extension class
|
|
223
|
+
- No `@/` imports used
|
|
224
|
+
- **If In-Repo:** extensions.json updated correctly
|
|
225
|
+
- **If In-Repo:** docs-site/docs/extensions/examples.md updated
|
|
226
|
+
- **If In-Repo:** Type checking passes
|
|
227
|
+
- Extension loads without errors
|
|
228
|
+
- Extension appears in extensions list
|
|
229
|
+
- Extension capabilities work as expected
|
|
230
|
+
|
|
231
|
+
**Success metrics:**
|
|
232
|
+
|
|
233
|
+
- Extension loads without errors
|
|
234
|
+
- Extension appears in extensions list
|
|
235
|
+
- Extension capabilities work as expected
|
|
236
|
+
|
|
237
|
+
## Common Situations
|
|
238
|
+
|
|
239
|
+
**Situation:** Extension needs to handle events
|
|
240
|
+
|
|
241
|
+
**Pattern:**
|
|
242
|
+
- When: Extension needs to modify agent behavior
|
|
243
|
+
- Then: Implement event handler methods (onAgentStarted, onToolCalled, etc.)
|
|
244
|
+
- Return: Partial event object to modify behavior
|
|
245
|
+
|
|
246
|
+
**Situation:** Extension needs to register commands
|
|
247
|
+
|
|
248
|
+
**Pattern:**
|
|
249
|
+
- When: Extension provides slash commands
|
|
250
|
+
- Then: Implement getCommands() method
|
|
251
|
+
- Return: Array of CommandDefinition objects
|
|
252
|
+
|
|
253
|
+
**Situation:** Extension needs to add UI components
|
|
254
|
+
|
|
255
|
+
**Pattern:**
|
|
256
|
+
- When: Extension needs to display information in UI
|
|
257
|
+
- Then: Implement getUIComponents() method
|
|
258
|
+
- Return: Array of UIComponentDefinition objects
|
|
259
|
+
- Use: JSX strings or external .jsx files
|
|
260
|
+
- Load data: Implement getUIExtensionData() if component needs data
|
|
261
|
+
- Handle actions: Implement executeUIExtensionAction() for user interactions
|
|
262
|
+
|
|
263
|
+
**Situation:** Extension needs to log messages
|
|
264
|
+
|
|
265
|
+
**Pattern:**
|
|
266
|
+
- If: Debug/internal logging (developer diagnostics, not shown to users)
|
|
267
|
+
- Then: Use `context.log(message, type)` — logs to backend console only
|
|
268
|
+
- If: User-visible output (showing results, status, timing info in the chat)
|
|
269
|
+
- Then: Use `context.getTaskContext()?.addLogMessage(level, message)` — displays in task's chat UI
|
|
270
|
+
- When ambiguous: If the user says "log", "show", "display", or "report" something, default to `addLogMessage` (user-visible). Use `context.log` only for internal diagnostics.
|
|
271
|
+
- Note: `context.log` is always available; `getTaskContext()` returns `null` outside a task, so always use optional chaining (`?.`)
|
|
272
|
+
|
|
273
|
+
**Situation:** Extension needs config storage
|
|
274
|
+
|
|
275
|
+
**Pattern:**
|
|
276
|
+
- Check: Extension needs persistent settings
|
|
277
|
+
- If yes: Create config.ts with loadConfig and saveConfig functions
|
|
278
|
+
- Store: Config files in extension directory
|
|
279
|
+
|
|
280
|
+
**Situation:** Extension needs a settings UI (config component)
|
|
281
|
+
|
|
282
|
+
**Pattern:**
|
|
283
|
+
- When: Extension has user-configurable options that should appear in the Settings dialog
|
|
284
|
+
- Then: Implement `getConfigComponent()`, `getConfigData()`, `saveConfigData()` methods
|
|
285
|
+
- JSX: Return a `.jsx` file content via `readFileSync(join(__dirname, './ConfigComponent.jsx'), 'utf-8')`
|
|
286
|
+
- Props: Component receives `{ config, updateConfig, ui, icons, models, providers, ... }`
|
|
287
|
+
- Flow: Dialog opens → loads data via getConfigData → renders JSX with props → user edits → Save calls saveConfigData
|
|
288
|
+
- Reference: [config-components.md](references/config-components.md) for full guide and examples
|
|
289
|
+
|
|
290
|
+
## References
|
|
291
|
+
|
|
292
|
+
### Target Selection
|
|
293
|
+
|
|
294
|
+
- [install-targets.md](references/install-targets.md) - All three installation targets, when to use each, key differences
|
|
295
|
+
|
|
296
|
+
### Flows
|
|
297
|
+
|
|
298
|
+
- [project-global-flow.md](references/project-global-flow.md) - Step-by-step for Project and Global installations
|
|
299
|
+
- [in-repo-flow.md](references/in-repo-flow.md) - Step-by-step for In-Repo (packages/extensions/) installations
|
|
300
|
+
|
|
301
|
+
### Technical Reference (all targets)
|
|
302
|
+
|
|
303
|
+
- [packages/common/src/extensions.ts](https://raw.githubusercontent.com/hotovo/aider-desk/refs/heads/main/packages/common/src/extensions.ts) - Extension types and interfaces
|
|
304
|
+
- [extension-interface.md](references/extension-interface.md) - Full Extension interface, ExtensionContext, TaskContext, Metadata
|
|
305
|
+
- [extension-types.md](references/extension-types.md) - Single-file vs folder extensions, examples, extensions.json format
|
|
306
|
+
- [event-types.md](references/event-types.md) - All event types and payloads
|
|
307
|
+
- [command-definition.md](references/command-definition.md) - Command structure
|
|
308
|
+
- [ui-components.md](references/ui-components.md) - UI component system, placements, and available components
|
|
309
|
+
- [config-components.md](references/config-components.md) - Config component API (settings UI), methods, JSX format, and patterns
|
|
310
|
+
- [examples-gallery.md](references/examples-gallery.md) - Real extension examples
|
|
311
|
+
|
|
312
|
+
## Assets
|
|
313
|
+
|
|
314
|
+
- [templates/single-file.ts.template](assets/templates/single-file.ts.template) - Single-file template
|
|
315
|
+
- [templates/folder-extension/](assets/templates/folder-extension/) - Folder template (basic)
|
|
316
|
+
- [templates/folder-extension-with-config/index.ts.template](assets/templates/folder-extension-with-config/index.ts.template) - Folder template with config component API
|
|
317
|
+
- [templates/ui-component.ts.template](assets/templates/ui-component.ts.template) - UI component inline template
|
|
318
|
+
- [templates/ui-component-external.ts.template](assets/templates/ui-component-external.ts.template) - UI component with external JSX
|
|
319
|
+
- [templates/Component.jsx.template](assets/templates/Component.jsx.template) - Placement-based JSX component template
|
|
320
|
+
- [templates/ConfigComponent.jsx.template](assets/templates/ConfigComponent.jsx.template) - Config/settings JSX component template
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Component for {{EXTENSION_NAME}}
|
|
3
|
+
*
|
|
4
|
+
* Note: React is globally available (use React.useState, React.useEffect, etc.)
|
|
5
|
+
*
|
|
6
|
+
* Available props (via 'props' or destructured):
|
|
7
|
+
* - data: Data from getUIExtensionData()
|
|
8
|
+
* - task: Current TaskData
|
|
9
|
+
* - projectDir: Project directory path
|
|
10
|
+
* - models: Available models
|
|
11
|
+
* - providers: Available providers
|
|
12
|
+
* - ui: UI components (Button, Checkbox, Input, etc.)
|
|
13
|
+
* - icons: React Icons organized by set (Fi, Hi, Cg, etc.)
|
|
14
|
+
* - executeExtensionAction: Function to call extension actions
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
(props) => {
|
|
18
|
+
const { data, task, ui, icons, executeExtensionAction } = props;
|
|
19
|
+
const { useState, useCallback } = React;
|
|
20
|
+
const { Button } = ui;
|
|
21
|
+
const { FiCheckCircle } = icons.Fi;
|
|
22
|
+
|
|
23
|
+
// Early return if no data
|
|
24
|
+
if (!data) return null;
|
|
25
|
+
|
|
26
|
+
// Local state
|
|
27
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
28
|
+
|
|
29
|
+
// Event handlers
|
|
30
|
+
const handleIncrement = useCallback(async () => {
|
|
31
|
+
const result = await executeExtensionAction('increment');
|
|
32
|
+
console.log('Increment result:', result);
|
|
33
|
+
}, [executeExtensionAction]);
|
|
34
|
+
|
|
35
|
+
const handleSetMessage = useCallback(async () => {
|
|
36
|
+
await executeExtensionAction('set-message', 'New message!');
|
|
37
|
+
}, [executeExtensionAction]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
className="flex items-center gap-2 p-2 bg-bg-secondary rounded"
|
|
42
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
43
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
44
|
+
>
|
|
45
|
+
<FiCheckCircle className="w-4 h-4 text-success" />
|
|
46
|
+
|
|
47
|
+
<div className="flex-1">
|
|
48
|
+
<div className="text-sm text-text-primary">
|
|
49
|
+
{data.message}
|
|
50
|
+
</div>
|
|
51
|
+
<div className="text-xs text-text-secondary">
|
|
52
|
+
Count: {data.count}
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
{isHovered && (
|
|
57
|
+
<div className="flex gap-1">
|
|
58
|
+
<Button
|
|
59
|
+
size="xs"
|
|
60
|
+
variant="outline"
|
|
61
|
+
onClick={handleIncrement}
|
|
62
|
+
>
|
|
63
|
+
+1
|
|
64
|
+
</Button>
|
|
65
|
+
<Button
|
|
66
|
+
size="xs"
|
|
67
|
+
variant="outline"
|
|
68
|
+
onClick={handleSetMessage}
|
|
69
|
+
>
|
|
70
|
+
Change
|
|
71
|
+
</Button>
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Component for {{EXTENSION_NAME}}
|
|
3
|
+
*
|
|
4
|
+
* Renders a settings UI in the ExtensionSettingsDialog.
|
|
5
|
+
*
|
|
6
|
+
* Available props:
|
|
7
|
+
* - config: Current config data from getConfigData()
|
|
8
|
+
* - updateConfig: Callback to mutate in-memory config (does NOT persist)
|
|
9
|
+
* - ui: UI components (Button, Checkbox, Input, Select, TextArea, etc.) — prefer these over raw HTML
|
|
10
|
+
* - icons: React Icons organized by set (Fi, Hi, Cg, etc.)
|
|
11
|
+
* - models: Available models
|
|
12
|
+
* - providers: Available providers
|
|
13
|
+
* - projectDir: Project directory path
|
|
14
|
+
* - task: Current TaskData
|
|
15
|
+
* - mode: Current mode string
|
|
16
|
+
* - api: ApplicationAPI reference
|
|
17
|
+
*
|
|
18
|
+
* Note: React is globally available (use React.useState, React.useEffect, etc.)
|
|
19
|
+
* Note: Prefer ui.* components over raw HTML elements for consistent styling
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
({ config, updateConfig, ui }) => {
|
|
23
|
+
const { Input } = ui;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="flex flex-col gap-4">
|
|
27
|
+
<Input
|
|
28
|
+
label="My Setting Label"
|
|
29
|
+
value={config?.mySetting || ''}
|
|
30
|
+
onChange={(value) => updateConfig({ ...config, mySetting: value })}
|
|
31
|
+
placeholder="Enter a value..."
|
|
32
|
+
/>
|
|
33
|
+
<p className="text-xs text-text-secondary -mt-2">
|
|
34
|
+
Description of what this setting controls and how it affects the extension behavior.
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
};
|
package/out/resources/skills/extension-creator/assets/templates/folder-extension/config.ts.template
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
export interface {EXTENSION_NAME}Config {
|
|
8
|
+
// Add config properties
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const DEFAULT_CONFIG: {EXTENSION_NAME}Config = {
|
|
12
|
+
// Add default values
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const CONFIG_FILE = path.join(__dirname, 'config.json');
|
|
16
|
+
|
|
17
|
+
export const loadConfig = async (): Promise<{EXTENSION_NAME}Config> => {
|
|
18
|
+
try {
|
|
19
|
+
const data = await fs.readFile(CONFIG_FILE, 'utf-8');
|
|
20
|
+
const config = JSON.parse(data);
|
|
21
|
+
return { ...DEFAULT_CONFIG, ...config };
|
|
22
|
+
} catch {
|
|
23
|
+
return { ...DEFAULT_CONFIG };
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const saveConfig = async (config: {EXTENSION_NAME}Config): Promise<void> => {
|
|
28
|
+
await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
29
|
+
};
|
package/out/resources/skills/extension-creator/assets/templates/folder-extension/index.ts.template
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {EXTENSION_NAME} Extension
|
|
3
|
+
*
|
|
4
|
+
* {DESCRIPTION}
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Extension, ExtensionContext, AgentStartedEvent, CommandDefinition } from '@aiderdesk/extensions';
|
|
8
|
+
|
|
9
|
+
import { loadConfig, saveConfig } from './config';
|
|
10
|
+
import type { {EXTENSION_NAME}Config } from './config';
|
|
11
|
+
|
|
12
|
+
const DEFAULT_CONFIG: {EXTENSION_NAME}Config = {
|
|
13
|
+
// Add default config values
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default class {CLASS_NAME} implements Extension {
|
|
17
|
+
static metadata = {
|
|
18
|
+
name: '{EXTENSION_NAME}',
|
|
19
|
+
version: '1.0.0',
|
|
20
|
+
description: '{DESCRIPTION}',
|
|
21
|
+
author: '{AUTHOR}',
|
|
22
|
+
capabilities: ['events', 'commands'],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
private config: {EXTENSION_NAME}Config = DEFAULT_CONFIG;
|
|
26
|
+
|
|
27
|
+
async onLoad(context: ExtensionContext): Promise<void> {
|
|
28
|
+
context.log('{EXTENSION_NAME} Extension loaded', 'info');
|
|
29
|
+
this.config = await loadConfig();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCommands(_context: ExtensionContext): CommandDefinition[] {
|
|
33
|
+
return [
|
|
34
|
+
// Add commands here
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async onAgentStarted(event: AgentStartedEvent, context: ExtensionContext): Promise<void | Partial<AgentStartedEvent>> {
|
|
39
|
+
// Handle event
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{extension-name}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "{DESCRIPTION}",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"keywords": ["aiderdesk", "extension"],
|
|
7
|
+
"author": "{AUTHOR}",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"dependencies": {
|
|
10
|
+
// Add npm dependencies here
|
|
11
|
+
}
|
|
12
|
+
}
|
package/out/resources/skills/extension-creator/assets/templates/folder-extension/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ES2020",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"declarationMap": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"outDir": "./dist",
|
|
15
|
+
"rootDir": ".",
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"noFallthroughCasesInSwitch": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["*.ts"],
|
|
22
|
+
"exclude": ["node_modules", "dist", "__tests__"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {EXTENSION_NAME} Extension
|
|
3
|
+
*
|
|
4
|
+
* {DESCRIPTION}
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
import type { Extension, ExtensionContext } from '@aiderdesk/extensions';
|
|
11
|
+
|
|
12
|
+
// Load config JSX at module level (read once, reused on every getConfigComponent call)
|
|
13
|
+
const configComponentJsx = readFileSync(join(__dirname, './ConfigComponent.jsx'), 'utf-8');
|
|
14
|
+
|
|
15
|
+
interface {EXTENSION_NAME}Config {
|
|
16
|
+
// Add your config properties here
|
|
17
|
+
mySetting: string;
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DEFAULT_CONFIG: {EXTENSION_NAME}Config = {
|
|
22
|
+
mySetting: '',
|
|
23
|
+
enabled: true,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default class {CLASS_NAME} implements Extension {
|
|
27
|
+
static metadata = {
|
|
28
|
+
name: '{EXTENSION_NAME}',
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
description: '{DESCRIPTION}',
|
|
31
|
+
author: '{AUTHOR}',
|
|
32
|
+
capabilities: ['context'],
|
|
33
|
+
// iconUrl: 'https://...',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
private configPath: string;
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
this.configPath = join(__dirname, 'config.json');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async onLoad(context: ExtensionContext): Promise<void> {
|
|
43
|
+
context.log('{EXTENSION_NAME} Extension loaded', 'info');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// --- Config Component API ---
|
|
47
|
+
|
|
48
|
+
getConfigComponent(_context: ExtensionContext): string {
|
|
49
|
+
return configComponentJsx;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getConfigData(_context: ExtensionContext): Promise<{EXTENSION_NAME}Config> {
|
|
53
|
+
try {
|
|
54
|
+
if (existsSync(this.configPath)) {
|
|
55
|
+
const data = readFileSync(this.configPath, 'utf-8');
|
|
56
|
+
const parsed = JSON.parse(data);
|
|
57
|
+
return { ...DEFAULT_CONFIG, ...parsed };
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
// Ignore errors, fall back to defaults
|
|
61
|
+
}
|
|
62
|
+
return { ...DEFAULT_CONFIG };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async saveConfigData(configData: unknown, _context: ExtensionContext): Promise<unknown> {
|
|
66
|
+
const merged: {EXTENSION_NAME}Config = {
|
|
67
|
+
...DEFAULT_CONFIG,
|
|
68
|
+
...configData as Partial<{EXTENSION_NAME}Config>,
|
|
69
|
+
};
|
|
70
|
+
writeFileSync(this.configPath, JSON.stringify(merged, null, 2), 'utf-8');
|
|
71
|
+
return merged;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// --- Event Handlers / Other Methods ---
|
|
75
|
+
|
|
76
|
+
// async onRuleFilesRetrieved(event: RuleFilesRetrievedEvent, context: ExtensionContext) {
|
|
77
|
+
// const config = await this.getConfigData(context);
|
|
78
|
+
// Use config values in your logic...
|
|
79
|
+
// }
|
|
80
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {EXTENSION_NAME} Extension
|
|
3
|
+
*
|
|
4
|
+
* {DESCRIPTION}
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Extension, ExtensionContext } from '@aiderdesk/extensions';
|
|
8
|
+
|
|
9
|
+
export default class {CLASS_NAME} implements Extension {
|
|
10
|
+
static metadata = {
|
|
11
|
+
name: '{EXTENSION_NAME}',
|
|
12
|
+
version: '1.0.0',
|
|
13
|
+
description: '{DESCRIPTION}',
|
|
14
|
+
author: '{AUTHOR}',
|
|
15
|
+
capabilities: ['{CAPABILITY}'],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
async onLoad(context: ExtensionContext): Promise<void> {
|
|
19
|
+
context.log('{EXTENSION_NAME} Extension loaded', 'info');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Add methods as needed:
|
|
23
|
+
// - getCommands()
|
|
24
|
+
// - getTools()
|
|
25
|
+
// - getAgents()
|
|
26
|
+
// - getModes()
|
|
27
|
+
// - onAgentStarted()
|
|
28
|
+
// - onToolCalled()
|
|
29
|
+
// etc.
|
|
30
|
+
}
|