agents-inc 0.164.0 → 0.166.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/README.md +8 -9
- package/dist/{chunk-X4SSJZLY.js → chunk-25MPBIK3.js} +12 -261
- package/dist/chunk-25MPBIK3.js.map +1 -0
- package/dist/{chunk-LT5GXEB2.js → chunk-2VUYFTUB.js} +8 -7
- package/dist/chunk-2VUYFTUB.js.map +1 -0
- package/dist/chunk-4AAOOAIN.js +49 -0
- package/dist/chunk-4AAOOAIN.js.map +1 -0
- package/dist/{chunk-ARYNOWKF.js → chunk-4NDBUJHK.js} +8 -8
- package/dist/{chunk-S63LXWMC.js → chunk-6L75SQZU.js} +2 -2
- package/dist/{chunk-7REKOTKG.js → chunk-6LF4CQBY.js} +3 -3
- package/dist/{chunk-K5ITEA3I.js → chunk-7JNJ52CD.js} +34 -17
- package/dist/chunk-7JNJ52CD.js.map +1 -0
- package/dist/{chunk-XPDVAJDH.js → chunk-A4KDXNOT.js} +3519 -1568
- package/dist/chunk-A4KDXNOT.js.map +1 -0
- package/dist/{chunk-XHPWTL4I.js → chunk-DAIEQJIF.js} +3 -3
- package/dist/{chunk-UITEKY2R.js → chunk-ENGYJCTF.js} +28 -4
- package/dist/chunk-ENGYJCTF.js.map +1 -0
- package/dist/{chunk-G2JJ5BO5.js → chunk-G4JK7WVO.js} +336 -140
- package/dist/chunk-G4JK7WVO.js.map +1 -0
- package/dist/{chunk-X37UYIE3.js → chunk-G6UREQ4V.js} +436 -739
- package/dist/chunk-G6UREQ4V.js.map +1 -0
- package/dist/chunk-GE3WKJ6Q.js +375 -0
- package/dist/chunk-GE3WKJ6Q.js.map +1 -0
- package/dist/{chunk-RGYDFBCT.js → chunk-HHIYT3PI.js} +5 -5
- package/dist/{chunk-2CQNPLVF.js → chunk-HWEKHVLE.js} +63 -42
- package/dist/chunk-HWEKHVLE.js.map +1 -0
- package/dist/{chunk-XVAQG2CV.js → chunk-JOEA52NR.js} +10 -8
- package/dist/chunk-JOEA52NR.js.map +1 -0
- package/dist/{chunk-3WVH2CTK.js → chunk-JQRJQ4SS.js} +15 -8
- package/dist/chunk-JQRJQ4SS.js.map +1 -0
- package/dist/{chunk-DSL66I4N.js → chunk-LFWLEDUG.js} +6 -6
- package/dist/{chunk-B3Y3QMWI.js → chunk-MAWNVT2C.js} +4 -4
- package/dist/{chunk-Q4IRRVXK.js → chunk-MPTNC32T.js} +3 -3
- package/dist/chunk-NBXXFIIW.js +73 -0
- package/dist/chunk-NBXXFIIW.js.map +1 -0
- package/dist/{chunk-B6FSLXYN.js → chunk-PMJWD27C.js} +3 -3
- package/dist/{chunk-XATLUKXK.js → chunk-PNB3524H.js} +6 -6
- package/dist/chunk-PXWG7KFO.js +39 -0
- package/dist/chunk-PXWG7KFO.js.map +1 -0
- package/dist/{chunk-4VL3CEOS.js → chunk-QHDPLLK6.js} +3 -3
- package/dist/{chunk-AOTCIUGX.js → chunk-RAHSOJQ2.js} +2 -2
- package/dist/{chunk-PHCPUQVR.js → chunk-RZDXDMT6.js} +2 -2
- package/dist/{chunk-6MV4JOCL.js → chunk-SAYZWCH6.js} +2 -2
- package/dist/{chunk-URXIQE7I.js → chunk-SCOQ34YM.js} +2 -2
- package/dist/{chunk-NQXO4LR3.js → chunk-SXVHSOTH.js} +16 -11
- package/dist/chunk-SXVHSOTH.js.map +1 -0
- package/dist/{chunk-QZX7SYKU.js → chunk-T6UWJAB3.js} +2 -2
- package/dist/{chunk-ZVXGW2IC.js → chunk-TODCQFRB.js} +4 -6
- package/dist/chunk-TODCQFRB.js.map +1 -0
- package/dist/{chunk-YRS3QZP2.js → chunk-TTY6DPJN.js} +3 -3
- package/dist/{chunk-QGUP3QJF.js → chunk-TZ2YJJKK.js} +22 -18
- package/dist/{chunk-QGUP3QJF.js.map → chunk-TZ2YJJKK.js.map} +1 -1
- package/dist/chunk-V3I7VQ7N.js +356 -0
- package/dist/chunk-V3I7VQ7N.js.map +1 -0
- package/dist/{chunk-AVK2HEKB.js → chunk-V5WXIM2F.js} +2 -6
- package/dist/{chunk-AVK2HEKB.js.map → chunk-V5WXIM2F.js.map} +1 -1
- package/dist/{chunk-NKGYKOB7.js → chunk-VAPTVR3J.js} +7 -8
- package/dist/chunk-VAPTVR3J.js.map +1 -0
- package/dist/chunk-VRXX4D6K.js +31 -0
- package/dist/chunk-VRXX4D6K.js.map +1 -0
- package/dist/{chunk-ABAZMMG4.js → chunk-WVUDLKIO.js} +2 -2
- package/dist/{chunk-ECURHW3T.js → chunk-WWIFNPJG.js} +13 -12
- package/dist/chunk-WWIFNPJG.js.map +1 -0
- package/dist/{chunk-J27W6TXS.js → chunk-XQHZPINL.js} +8 -4
- package/dist/chunk-XQHZPINL.js.map +1 -0
- package/dist/{chunk-V5GLL2JB.js → chunk-XZEVWPX6.js} +7 -7
- package/dist/chunk-Y3VIRVVE.js +932 -0
- package/dist/chunk-Y3VIRVVE.js.map +1 -0
- package/dist/{chunk-NTF4UXGK.js → chunk-Y47EV74W.js} +73 -30
- package/dist/chunk-Y47EV74W.js.map +1 -0
- package/dist/chunk-ZR4YPKXQ.js +159 -0
- package/dist/chunk-ZR4YPKXQ.js.map +1 -0
- package/dist/chunk-ZXKBERQU.js +250 -0
- package/dist/chunk-ZXKBERQU.js.map +1 -0
- package/dist/commands/build/marketplace.js +17 -17
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +11 -9
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +105 -27
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +309 -171
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +503 -314
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +40 -23
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +44 -40
- package/dist/commands/list.js +44 -10
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +13 -10
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +12 -10
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +102 -15
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +231 -103
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +49 -20
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/prompt-confirm.js +1 -1
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/select-list.js +3 -3
- package/dist/components/common/spinner.js +6 -3
- package/dist/components/wizard/category-grid.js +5 -5
- package/dist/components/wizard/checkbox-grid.js +4 -4
- package/dist/components/wizard/domain-selection.js +9 -9
- package/dist/components/wizard/run-wizard-session.js +29 -29
- package/dist/components/wizard/scroll-affordance.js +2 -2
- package/dist/components/wizard/skill-agent-summary.js +5 -5
- package/dist/components/wizard/source-grid.js +6 -6
- package/dist/components/wizard/stack-selection.js +8 -8
- package/dist/components/wizard/step-agents.js +8 -8
- package/dist/components/wizard/step-build.js +8 -8
- package/dist/components/wizard/step-confirm.js +9 -9
- package/dist/components/wizard/step-sources.js +9 -9
- package/dist/components/wizard/step-stack.js +9 -9
- package/dist/components/wizard/summary-panel.js +8 -8
- package/dist/components/wizard/toast.js +2 -2
- package/dist/components/wizard/wizard-layout.js +12 -12
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard.js +27 -27
- package/dist/hooks/init.js +69 -43
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-3C27ENC7.js +14 -0
- package/dist/recompile-project-agents-DGNBCU3N.js +18 -0
- package/dist/{source-loader-GRBVNRAW.js → source-loader-7KZ3MD5O.js} +6 -4
- package/dist/src/agents/_templates/agent-body.liquid +55 -0
- package/dist/src/agents/_templates/agent.liquid +1 -55
- package/dist/src/agents/meta/agent-summoner/output.md +1 -1
- package/dist/src/agents/meta/agent-summoner/playbook.md +15 -7
- package/dist/stores/wizard-store.js +4 -4
- package/package.json +10 -9
- package/src/agents/_templates/agent-body.liquid +55 -0
- package/src/agents/_templates/agent.liquid +1 -55
- package/src/agents/meta/agent-summoner/output.md +1 -1
- package/src/agents/meta/agent-summoner/playbook.md +15 -7
- package/src/schemas/project-config.schema.json +1 -1
- package/src/schemas/project-source-config.schema.json +1 -1
- package/dist/chunk-2CQNPLVF.js.map +0 -1
- package/dist/chunk-3WVH2CTK.js.map +0 -1
- package/dist/chunk-7ANJQLPJ.js +0 -35
- package/dist/chunk-7ANJQLPJ.js.map +0 -1
- package/dist/chunk-ECURHW3T.js.map +0 -1
- package/dist/chunk-FLW25ORT.js +0 -130
- package/dist/chunk-FLW25ORT.js.map +0 -1
- package/dist/chunk-G2JJ5BO5.js.map +0 -1
- package/dist/chunk-J27W6TXS.js.map +0 -1
- package/dist/chunk-JCPANDNR.js +0 -35
- package/dist/chunk-JCPANDNR.js.map +0 -1
- package/dist/chunk-JIERYE6B.js +0 -480
- package/dist/chunk-JIERYE6B.js.map +0 -1
- package/dist/chunk-JU4ZGJ7A.js +0 -668
- package/dist/chunk-JU4ZGJ7A.js.map +0 -1
- package/dist/chunk-K5ITEA3I.js.map +0 -1
- package/dist/chunk-LT5GXEB2.js.map +0 -1
- package/dist/chunk-NKGYKOB7.js.map +0 -1
- package/dist/chunk-NQXO4LR3.js.map +0 -1
- package/dist/chunk-NTF4UXGK.js.map +0 -1
- package/dist/chunk-UITEKY2R.js.map +0 -1
- package/dist/chunk-X37UYIE3.js.map +0 -1
- package/dist/chunk-X4SSJZLY.js.map +0 -1
- package/dist/chunk-XPDVAJDH.js.map +0 -1
- package/dist/chunk-XVAQG2CV.js.map +0 -1
- package/dist/chunk-ZBPEFQ4G.js +0 -12
- package/dist/chunk-ZBPEFQ4G.js.map +0 -1
- package/dist/chunk-ZVXGW2IC.js.map +0 -1
- package/dist/load-agent-defs-7IM3GBEQ.js +0 -13
- package/dist/recompile-project-agents-VR4NLGOU.js +0 -17
- /package/dist/{chunk-ARYNOWKF.js.map → chunk-4NDBUJHK.js.map} +0 -0
- /package/dist/{chunk-S63LXWMC.js.map → chunk-6L75SQZU.js.map} +0 -0
- /package/dist/{chunk-7REKOTKG.js.map → chunk-6LF4CQBY.js.map} +0 -0
- /package/dist/{chunk-XHPWTL4I.js.map → chunk-DAIEQJIF.js.map} +0 -0
- /package/dist/{chunk-RGYDFBCT.js.map → chunk-HHIYT3PI.js.map} +0 -0
- /package/dist/{chunk-DSL66I4N.js.map → chunk-LFWLEDUG.js.map} +0 -0
- /package/dist/{chunk-B3Y3QMWI.js.map → chunk-MAWNVT2C.js.map} +0 -0
- /package/dist/{chunk-Q4IRRVXK.js.map → chunk-MPTNC32T.js.map} +0 -0
- /package/dist/{chunk-B6FSLXYN.js.map → chunk-PMJWD27C.js.map} +0 -0
- /package/dist/{chunk-XATLUKXK.js.map → chunk-PNB3524H.js.map} +0 -0
- /package/dist/{chunk-4VL3CEOS.js.map → chunk-QHDPLLK6.js.map} +0 -0
- /package/dist/{chunk-AOTCIUGX.js.map → chunk-RAHSOJQ2.js.map} +0 -0
- /package/dist/{chunk-PHCPUQVR.js.map → chunk-RZDXDMT6.js.map} +0 -0
- /package/dist/{chunk-6MV4JOCL.js.map → chunk-SAYZWCH6.js.map} +0 -0
- /package/dist/{chunk-URXIQE7I.js.map → chunk-SCOQ34YM.js.map} +0 -0
- /package/dist/{chunk-QZX7SYKU.js.map → chunk-T6UWJAB3.js.map} +0 -0
- /package/dist/{chunk-YRS3QZP2.js.map → chunk-TTY6DPJN.js.map} +0 -0
- /package/dist/{chunk-ABAZMMG4.js.map → chunk-WVUDLKIO.js.map} +0 -0
- /package/dist/{chunk-V5GLL2JB.js.map → chunk-XZEVWPX6.js.map} +0 -0
- /package/dist/{load-agent-defs-7IM3GBEQ.js.map → load-agent-defs-3C27ENC7.js.map} +0 -0
- /package/dist/{recompile-project-agents-VR4NLGOU.js.map → recompile-project-agents-DGNBCU3N.js.map} +0 -0
- /package/dist/{source-loader-GRBVNRAW.js.map → source-loader-7KZ3MD5O.js.map} +0 -0
package/dist/commands/edit.js
CHANGED
|
@@ -3,83 +3,105 @@ import {
|
|
|
3
3
|
publishSeedConfig,
|
|
4
4
|
seedPayloadForInstallation,
|
|
5
5
|
skillsAuthoredHere
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-Y47EV74W.js";
|
|
7
7
|
import {
|
|
8
8
|
RemovalPlanConfirm
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import
|
|
9
|
+
} from "../chunk-TODCQFRB.js";
|
|
10
|
+
import {
|
|
11
|
+
unofferablePlacementsFound
|
|
12
|
+
} from "../chunk-PXWG7KFO.js";
|
|
11
13
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
arrivalLines,
|
|
15
|
+
arrivalsByScope,
|
|
16
|
+
notInstalledGlobally,
|
|
17
|
+
openUrl,
|
|
18
|
+
readInstalledGlobal,
|
|
19
|
+
reconcileSharedConfig,
|
|
20
|
+
restoreInstalledGlobal,
|
|
21
|
+
sameAssignments,
|
|
22
|
+
skillLabel,
|
|
23
|
+
withUnplaceableAssignees
|
|
24
|
+
} from "../chunk-V3I7VQ7N.js";
|
|
14
25
|
import {
|
|
15
26
|
runWizardSession
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
27
|
+
} from "../chunk-HHIYT3PI.js";
|
|
28
|
+
import "../chunk-WWIFNPJG.js";
|
|
29
|
+
import "../chunk-RAHSOJQ2.js";
|
|
30
|
+
import "../chunk-DAIEQJIF.js";
|
|
31
|
+
import "../chunk-SCOQ34YM.js";
|
|
32
|
+
import "../chunk-4NDBUJHK.js";
|
|
33
|
+
import "../chunk-2VUYFTUB.js";
|
|
34
|
+
import "../chunk-T6UWJAB3.js";
|
|
35
|
+
import "../chunk-6L75SQZU.js";
|
|
36
|
+
import "../chunk-LFWLEDUG.js";
|
|
37
|
+
import "../chunk-TZ2YJJKK.js";
|
|
38
|
+
import "../chunk-SAYZWCH6.js";
|
|
39
|
+
import "../chunk-PNB3524H.js";
|
|
40
|
+
import "../chunk-XZEVWPX6.js";
|
|
41
|
+
import "../chunk-QHDPLLK6.js";
|
|
42
|
+
import "../chunk-MPTNC32T.js";
|
|
32
43
|
import "../chunk-TSIU7DME.js";
|
|
33
|
-
import "../chunk-
|
|
44
|
+
import "../chunk-JOEA52NR.js";
|
|
34
45
|
import {
|
|
35
|
-
|
|
36
|
-
} from "../chunk-
|
|
37
|
-
import "../chunk-
|
|
38
|
-
import "../chunk-
|
|
39
|
-
import "../chunk-
|
|
40
|
-
import "../chunk-
|
|
46
|
+
awaitUnderSpinner
|
|
47
|
+
} from "../chunk-VRXX4D6K.js";
|
|
48
|
+
import "../chunk-SXVHSOTH.js";
|
|
49
|
+
import "../chunk-XQHZPINL.js";
|
|
50
|
+
import "../chunk-JQRJQ4SS.js";
|
|
51
|
+
import "../chunk-TTY6DPJN.js";
|
|
41
52
|
import "../chunk-WTJ3AY33.js";
|
|
42
|
-
import "../chunk-
|
|
53
|
+
import "../chunk-WVUDLKIO.js";
|
|
43
54
|
import {
|
|
44
|
-
fetchSeedConfig
|
|
45
|
-
|
|
46
|
-
writeExternalSkills
|
|
47
|
-
} from "../chunk-X4SSJZLY.js";
|
|
55
|
+
fetchSeedConfig
|
|
56
|
+
} from "../chunk-25MPBIK3.js";
|
|
48
57
|
import {
|
|
49
58
|
promptConfirm
|
|
50
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-4AAOOAIN.js";
|
|
60
|
+
import "../chunk-OZXAJNLA.js";
|
|
61
|
+
import {
|
|
62
|
+
hostCompileNotices
|
|
63
|
+
} from "../chunk-ZXKBERQU.js";
|
|
51
64
|
import {
|
|
52
65
|
applyMigratedGlobalSources,
|
|
53
66
|
compileAgentsAllScopes,
|
|
67
|
+
compileProjectScope,
|
|
54
68
|
detectProject,
|
|
55
69
|
loadSource,
|
|
70
|
+
movedGlobalAgentInputs,
|
|
56
71
|
mutateGlobal,
|
|
57
|
-
|
|
72
|
+
sayCapturedWarnings,
|
|
58
73
|
writeProjectConfig
|
|
59
|
-
} from "../chunk-
|
|
74
|
+
} from "../chunk-G6UREQ4V.js";
|
|
60
75
|
import {
|
|
61
76
|
copyLocalSkills,
|
|
62
77
|
discoverInstalledSkills,
|
|
63
78
|
removeCompiledAgents,
|
|
64
79
|
uninstallPluginSkills
|
|
65
|
-
} from "../chunk-
|
|
80
|
+
} from "../chunk-HWEKHVLE.js";
|
|
66
81
|
import {
|
|
67
82
|
loadAgentDefs
|
|
68
|
-
} from "../chunk-
|
|
69
|
-
import "../chunk-
|
|
70
|
-
import "../chunk-
|
|
71
|
-
import
|
|
72
|
-
|
|
73
|
-
} from "../chunk-JFLVEFFP.js";
|
|
83
|
+
} from "../chunk-PMJWD27C.js";
|
|
84
|
+
import "../chunk-ZR4YPKXQ.js";
|
|
85
|
+
import "../chunk-GE3WKJ6Q.js";
|
|
86
|
+
import "../chunk-MAWNVT2C.js";
|
|
87
|
+
import "../chunk-JFLVEFFP.js";
|
|
74
88
|
import {
|
|
75
89
|
formatScopeTag
|
|
76
|
-
} from "../chunk-
|
|
90
|
+
} from "../chunk-7JNJ52CD.js";
|
|
91
|
+
import {
|
|
92
|
+
providerFlag,
|
|
93
|
+
providerNamedBy,
|
|
94
|
+
refuseAnAmbiguousInstallation
|
|
95
|
+
} from "../chunk-NBXXFIIW.js";
|
|
77
96
|
import {
|
|
78
97
|
BaseCommand,
|
|
79
|
-
EXIT_CODES
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
EXIT_CODES,
|
|
99
|
+
carriedSkillsThatDiffer,
|
|
100
|
+
registerExternalSkills,
|
|
101
|
+
writeExternalSkills
|
|
102
|
+
} from "../chunk-Y3VIRVVE.js";
|
|
103
|
+
import "../chunk-VAPTVR3J.js";
|
|
104
|
+
import "../chunk-RZDXDMT6.js";
|
|
83
105
|
import {
|
|
84
106
|
ERROR_MESSAGES,
|
|
85
107
|
INCOMPLETE_WORK_RECOVERY,
|
|
@@ -88,23 +110,28 @@ import {
|
|
|
88
110
|
SHARED_CONFIG_APPLY,
|
|
89
111
|
STATUS_MESSAGES,
|
|
90
112
|
agentsNotCompiled,
|
|
113
|
+
applySharedConfigHere,
|
|
91
114
|
authoredHereKept,
|
|
92
115
|
buildMarketplacePluginRef,
|
|
93
116
|
carriedSkillsWritten,
|
|
94
|
-
claudePluginInstall,
|
|
95
|
-
claudePluginUninstall,
|
|
96
117
|
deleteLocalSkill,
|
|
97
118
|
detectMigrations,
|
|
98
119
|
discoverAllPluginSkills,
|
|
99
120
|
ejectCopyFailureError,
|
|
100
121
|
executeMigration,
|
|
122
|
+
foldLocalSkillIntoGlobal,
|
|
101
123
|
getErrorMessage,
|
|
102
|
-
|
|
103
|
-
|
|
124
|
+
holdsItsOwnInstallation,
|
|
125
|
+
hostAt,
|
|
104
126
|
isHomeDirectory,
|
|
105
|
-
|
|
127
|
+
keptAsInstalledGlobally,
|
|
128
|
+
keptUnassigned,
|
|
106
129
|
localSkillsCopied,
|
|
107
130
|
migrateLocalSkillScope,
|
|
131
|
+
nothingInstalledToApplyTo,
|
|
132
|
+
plural,
|
|
133
|
+
projectCopyRemoved,
|
|
134
|
+
providerInUse,
|
|
108
135
|
recompileSummary,
|
|
109
136
|
resolveInstallPaths,
|
|
110
137
|
seedToWizardResult,
|
|
@@ -112,119 +139,38 @@ import {
|
|
|
112
139
|
sharedConfigNeedsTerminal,
|
|
113
140
|
skippedUnknownAgents,
|
|
114
141
|
skippedUnknownSkills,
|
|
115
|
-
toClaudePluginScope,
|
|
116
142
|
unplaceableKept,
|
|
117
|
-
unresolvedSkillRemovalReasons
|
|
118
|
-
|
|
143
|
+
unresolvedSkillRemovalReasons,
|
|
144
|
+
wizardNeedsTerminal
|
|
145
|
+
} from "../chunk-A4KDXNOT.js";
|
|
119
146
|
import {
|
|
120
|
-
getCategoryDomain,
|
|
121
147
|
getSkillById,
|
|
122
148
|
getSkillDisplayName,
|
|
123
149
|
matrix,
|
|
124
|
-
typedEntries,
|
|
125
150
|
typedKeys
|
|
126
|
-
} from "../chunk-
|
|
151
|
+
} from "../chunk-V5WXIM2F.js";
|
|
127
152
|
import {
|
|
128
153
|
CLI_COLORS,
|
|
129
154
|
CLI_INVOKE_COMMAND,
|
|
130
155
|
EDIT_PROJECT_SETUP_FLAG,
|
|
156
|
+
EDIT_PROJECT_SETUP_MARKETPLACE_FLAG,
|
|
131
157
|
EJECT_SOURCE,
|
|
132
158
|
activeAgentNames,
|
|
133
159
|
activeAgentScopeMap,
|
|
134
160
|
editorConfigUrl,
|
|
135
161
|
formatSourceDisplayName,
|
|
136
162
|
isActiveAt,
|
|
137
|
-
|
|
138
|
-
} from "../chunk-
|
|
163
|
+
isGlobalTombstone
|
|
164
|
+
} from "../chunk-ENGYJCTF.js";
|
|
139
165
|
import "../chunk-OI2H6M5I.js";
|
|
140
166
|
|
|
141
167
|
// src/cli/commands/edit.tsx
|
|
142
|
-
import os from "os";
|
|
143
168
|
import path from "path";
|
|
144
169
|
import chalk from "chalk";
|
|
145
170
|
import { Flags } from "@oclif/core";
|
|
146
171
|
import { difference, indexBy, partition } from "remeda";
|
|
147
|
-
|
|
148
|
-
// src/cli/lib/seed/seed-apply.ts
|
|
149
|
-
var NOTHING_KEPT = {
|
|
150
|
-
authoredSkillIds: [],
|
|
151
|
-
unplaceableSkillIds: []
|
|
152
|
-
};
|
|
153
|
-
function reconcileSharedConfig(options) {
|
|
154
|
-
const { decoded, installed } = options;
|
|
155
|
-
if (!installed) return { result: decoded, kept: NOTHING_KEPT };
|
|
156
|
-
const keptSkills = skillsToKeep(options, installed);
|
|
157
|
-
if (keptSkills.length === 0) return { result: decoded, kept: NOTHING_KEPT };
|
|
158
|
-
return {
|
|
159
|
-
result: withKeptEntries(decoded, installed, keptSkills),
|
|
160
|
-
kept: describeKept(options, keptSkills)
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
function skillsToKeep(options, installed) {
|
|
164
|
-
const named = new Set(options.decoded.skills.map((skill) => skill.id));
|
|
165
|
-
return installed.skills.filter(
|
|
166
|
-
(skill) => !skill.excluded && !named.has(skill.id) && mayNotRemove(skill, options)
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
function mayNotRemove(skill, options) {
|
|
170
|
-
return options.authoredHere.has(skill.id) || options.unplaceable.has(skill.id);
|
|
171
|
-
}
|
|
172
|
-
function describeKept(options, keptSkills) {
|
|
173
|
-
const idsKeptFor = (reason) => keptSkills.filter((skill) => reasonKept(skill, options) === reason).map((skill) => skill.id);
|
|
174
|
-
return {
|
|
175
|
-
authoredSkillIds: idsKeptFor("authored"),
|
|
176
|
-
unplaceableSkillIds: idsKeptFor("unplaceable")
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function reasonKept(skill, options) {
|
|
180
|
-
return options.authoredHere.has(skill.id) ? "authored" : "unplaceable";
|
|
181
|
-
}
|
|
182
|
-
function withKeptEntries(decoded, installed, keptSkills) {
|
|
183
|
-
return {
|
|
184
|
-
...decoded,
|
|
185
|
-
skills: [...decoded.skills, ...keptSkills],
|
|
186
|
-
selectedDomains: withKeptDomains(decoded.selectedDomains, keptSkills),
|
|
187
|
-
...decoded.assignedStack !== void 0 && {
|
|
188
|
-
assignedStack: withKeptStackRows(decoded.assignedStack, installed.stack, {
|
|
189
|
-
keptSkillIds: new Set(keptSkills.map((skill) => skill.id)),
|
|
190
|
-
survivingAgents: new Set(decoded.selectedAgents)
|
|
191
|
-
})
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
function withKeptDomains(selected, keptSkills) {
|
|
196
|
-
const keptDomains = keptSkills.flatMap((skill) => domainOfSkill(skill.id) ?? []);
|
|
197
|
-
const missing = keptDomains.filter((domain) => !selected.includes(domain));
|
|
198
|
-
if (missing.length === 0) return selected;
|
|
199
|
-
return orderDomains([...selected, ...new Set(missing)]);
|
|
200
|
-
}
|
|
201
|
-
function domainOfSkill(skillId) {
|
|
202
|
-
const category = matrix.skills[skillId]?.category;
|
|
203
|
-
return category === void 0 ? void 0 : getCategoryDomain(category);
|
|
204
|
-
}
|
|
205
|
-
function withKeptStackRows(assigned, installedStack, filter) {
|
|
206
|
-
if (!installedStack) return assigned;
|
|
207
|
-
const carried = { ...assigned };
|
|
208
|
-
for (const [agent, agentStack] of typedEntries(installedStack)) {
|
|
209
|
-
if (!filter.survivingAgents.has(agent)) continue;
|
|
210
|
-
const rows = keptRowsFor(agentStack, filter.keptSkillIds);
|
|
211
|
-
if (typedKeys(rows).length === 0) continue;
|
|
212
|
-
carried[agent] = { ...carried[agent], ...rows };
|
|
213
|
-
}
|
|
214
|
-
return carried;
|
|
215
|
-
}
|
|
216
|
-
function keptRowsFor(agentStack, keptSkillIds) {
|
|
217
|
-
const rows = {};
|
|
218
|
-
for (const [category, assignments] of typedEntries(agentStack)) {
|
|
219
|
-
const carried = assignments.filter((assignment) => keptSkillIds.has(assignment.id));
|
|
220
|
-
if (carried.length > 0) rows[category] = carried;
|
|
221
|
-
}
|
|
222
|
-
return rows;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// src/cli/commands/edit.tsx
|
|
226
172
|
import { jsx } from "react/jsx-runtime";
|
|
227
|
-
var RECOMPILE_SUBJECT = "
|
|
173
|
+
var RECOMPILE_SUBJECT = "agent";
|
|
228
174
|
function formatDualScopeTransition(displayName, to) {
|
|
229
175
|
const isAdd = to === "project";
|
|
230
176
|
const prefix = isAdd ? "+" : "-";
|
|
@@ -251,6 +197,9 @@ function formatAgentScopeChangeLine(agentName, change, dualScopeAgentTransitions
|
|
|
251
197
|
function scopeArrow(change) {
|
|
252
198
|
return ` (${formatScopeTag(change.from)} \u2192 ${formatScopeTag(change.to)})`;
|
|
253
199
|
}
|
|
200
|
+
function formatValueChangeLine(subject, change, kind) {
|
|
201
|
+
return chalk.hex(CLI_COLORS.WARNING)(` ~ ${subject}`) + chalk.hex(CLI_COLORS.NEUTRAL)(` (${kind}: ${change.from} \u2192 ${change.to})`);
|
|
202
|
+
}
|
|
254
203
|
function loadedSourceLabel(sourceResult) {
|
|
255
204
|
return sourceResult.marketplace ?? sourceResult.sourceConfig.source;
|
|
256
205
|
}
|
|
@@ -259,55 +208,73 @@ function resolveEditRoot(installation, cwd, setupRequested) {
|
|
|
259
208
|
const isGlobal = isHomeDirectory(dir);
|
|
260
209
|
return { dir, isGlobal, isProjectSetup: setupRequested && !isGlobal };
|
|
261
210
|
}
|
|
262
|
-
function
|
|
263
|
-
const
|
|
211
|
+
function sharedConfigPlan(changes, kept) {
|
|
212
|
+
const dropped = droppedProjectHalves(changes);
|
|
213
|
+
const skillLines = [
|
|
214
|
+
...changes.removedSkills.map(skillLabel),
|
|
215
|
+
...dropped.skillIds.map(droppedSkillLine)
|
|
216
|
+
];
|
|
217
|
+
const agentLines = [...changes.removedAgents, ...dropped.agentNames.map(projectCopyRemoved)];
|
|
218
|
+
const sections = removalSections(skillLines, agentLines);
|
|
264
219
|
return { heading: planHeading(sections), sections, statements: kept };
|
|
265
220
|
}
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
const sections = [
|
|
269
|
-
...removalSections(here.skills, here.agents),
|
|
270
|
-
...globalRemovalSections(global.skills, global.agents)
|
|
271
|
-
];
|
|
272
|
-
return {
|
|
273
|
-
heading: planHeading(sections),
|
|
274
|
-
sections,
|
|
275
|
-
statements: [...globalReachStatement(global, otherProjects), ...kept]
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
function splitRemovalsByScope(changes, installed) {
|
|
279
|
-
const isGlobalSkill = (id) => installed.skills.some((skill) => skill.id === id && isActiveAt(skill, "global"));
|
|
280
|
-
const isGlobalAgent = (name) => installed.agents.some((agent) => agent.name === name && isActiveAt(agent, "global"));
|
|
281
|
-
const [globalSkills, projectSkills] = partition(changes.removedSkills, isGlobalSkill);
|
|
282
|
-
const [globalAgents, projectAgents] = partition(changes.removedAgents, isGlobalAgent);
|
|
283
|
-
return {
|
|
284
|
-
here: { skills: projectSkills, agents: projectAgents },
|
|
285
|
-
global: { skills: globalSkills, agents: globalAgents }
|
|
286
|
-
};
|
|
221
|
+
function droppedSkillLine(skillId) {
|
|
222
|
+
return projectCopyRemoved(skillLabel(skillId));
|
|
287
223
|
}
|
|
288
224
|
function removalSections(skills, agents) {
|
|
289
225
|
return [
|
|
290
|
-
{ label: SHARED_CONFIG_APPLY.SKILLS_HEADING, items: skills
|
|
291
|
-
{ label: SHARED_CONFIG_APPLY.AGENTS_HEADING, items:
|
|
292
|
-
].filter((section) => section.items.length > 0);
|
|
293
|
-
}
|
|
294
|
-
function globalRemovalSections(skills, agents) {
|
|
295
|
-
return [
|
|
296
|
-
{ label: SHARED_CONFIG_APPLY.GLOBAL_SKILLS_HEADING, items: skills.map(skillLabel) },
|
|
297
|
-
{ label: SHARED_CONFIG_APPLY.GLOBAL_AGENTS_HEADING, items: [...agents] }
|
|
226
|
+
{ label: SHARED_CONFIG_APPLY.SKILLS_HEADING, items: skills },
|
|
227
|
+
{ label: SHARED_CONFIG_APPLY.AGENTS_HEADING, items: agents }
|
|
298
228
|
].filter((section) => section.items.length > 0);
|
|
299
229
|
}
|
|
300
|
-
function
|
|
301
|
-
|
|
302
|
-
|
|
230
|
+
function droppedProjectHalves(changes) {
|
|
231
|
+
const droppedSkills = changes.collapsedPairs.filter((pair) => !pair.folded);
|
|
232
|
+
const droppedAgents = [...changes.agentScopeChanges].filter(
|
|
233
|
+
([name, change]) => change.to === "global" && changes.dualScopeAgentTransitions.has(name)
|
|
234
|
+
);
|
|
235
|
+
return {
|
|
236
|
+
skillIds: droppedSkills.map(({ projectHalf }) => projectHalf.id),
|
|
237
|
+
agentNames: droppedAgents.map(([name]) => name)
|
|
238
|
+
};
|
|
303
239
|
}
|
|
304
240
|
function planHeading(sections) {
|
|
305
241
|
if (sections.length === 0) return SHARED_CONFIG_APPLY.NOTHING_REMOVED;
|
|
306
242
|
return SHARED_CONFIG_APPLY.PREVIEW_HEADING;
|
|
307
243
|
}
|
|
308
|
-
function
|
|
309
|
-
|
|
310
|
-
return
|
|
244
|
+
function compilesGlobalScope(producer, editRoot, written) {
|
|
245
|
+
if (editRoot.isGlobal || producer === "wizard") return true;
|
|
246
|
+
return movedGlobalAgentInputs(written);
|
|
247
|
+
}
|
|
248
|
+
function withReassignments(changes, result, installedStack, editRoot) {
|
|
249
|
+
const { assignedStack } = result;
|
|
250
|
+
if (assignedStack === void 0) return { ...changes, reassignedAgents: [] };
|
|
251
|
+
const ownedHere = (agent) => editRoot.isGlobal || isActiveAt(agent, "project");
|
|
252
|
+
const countedAsAdded = (agent) => changes.addedAgents.includes(agent.name);
|
|
253
|
+
const rowsMoved = (agent) => !sameAssignments(assignedStack[agent.name], installedStack?.[agent.name]);
|
|
254
|
+
const reassigned = result.agentConfigs.filter(
|
|
255
|
+
(agent) => ownedHere(agent) && !countedAsAdded(agent) && rowsMoved(agent)
|
|
256
|
+
);
|
|
257
|
+
return { ...changes, reassignedAgents: reassigned.map((agent) => agent.name) };
|
|
258
|
+
}
|
|
259
|
+
function applyArrivals(changes, result) {
|
|
260
|
+
const changedSkills = /* @__PURE__ */ new Set([
|
|
261
|
+
...changes.addedSkills,
|
|
262
|
+
...changes.sourceChanges.keys(),
|
|
263
|
+
...changes.scopeChanges.keys()
|
|
264
|
+
]);
|
|
265
|
+
const changedAgents = /* @__PURE__ */ new Set([
|
|
266
|
+
...changes.addedAgents,
|
|
267
|
+
...changes.agentScopeChanges.keys(),
|
|
268
|
+
...changes.tuningChanges.keys(),
|
|
269
|
+
...changes.reassignedAgents
|
|
270
|
+
]);
|
|
271
|
+
const dropped = droppedProjectHalves(changes);
|
|
272
|
+
const skillArrives = (skill) => changedSkills.has(skill.id) && !dropped.skillIds.includes(skill.id);
|
|
273
|
+
const agentArrives = (agent) => changedAgents.has(agent.name) && !dropped.agentNames.includes(agent.name);
|
|
274
|
+
return arrivalsByScope(
|
|
275
|
+
result.skills.filter(skillArrives),
|
|
276
|
+
result.agentConfigs.filter(agentArrives)
|
|
277
|
+
);
|
|
311
278
|
}
|
|
312
279
|
function keptStatements(kept) {
|
|
313
280
|
return [...authorshipStatement(kept), ...catalogueStatement(kept)];
|
|
@@ -320,9 +287,20 @@ function catalogueStatement(kept) {
|
|
|
320
287
|
if (kept.unplaceableSkillIds.length === 0) return [];
|
|
321
288
|
return [unplaceableKept(kept.unplaceableSkillIds)];
|
|
322
289
|
}
|
|
323
|
-
function
|
|
324
|
-
if (
|
|
325
|
-
return
|
|
290
|
+
function unassignedStatement(unassigned) {
|
|
291
|
+
if (unassigned.length === 0) return [];
|
|
292
|
+
return [
|
|
293
|
+
unassigned.map(({ skillId, agentName, category }) => keptUnassigned(skillId, agentName, category)).join("\n")
|
|
294
|
+
];
|
|
295
|
+
}
|
|
296
|
+
function keptAsInstalledStatement(held, revisedCarried) {
|
|
297
|
+
const skillIds = [...held.keptAsInstalled.skillIds, ...revisedCarried];
|
|
298
|
+
const { agentNames } = held.keptAsInstalled;
|
|
299
|
+
if (skillIds.length === 0 && agentNames.length === 0) return [];
|
|
300
|
+
return [keptAsInstalledGlobally(skillIds, agentNames)];
|
|
301
|
+
}
|
|
302
|
+
function applyAuthority(editRoot) {
|
|
303
|
+
return editRoot.isGlobal ? "all" : "owned";
|
|
326
304
|
}
|
|
327
305
|
var Edit = class _Edit extends BaseCommand {
|
|
328
306
|
static summary = "Edit skills in the plugin";
|
|
@@ -347,14 +325,20 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
347
325
|
default: false
|
|
348
326
|
}),
|
|
349
327
|
from: Flags.string({
|
|
350
|
-
description: "Apply a configuration shared from agentsinc.sh by its id, removing whatever it leaves out",
|
|
328
|
+
description: "Apply a configuration shared from agentsinc.sh by its id, removing whatever it leaves out \u2014 from a project, only the project's own entries",
|
|
351
329
|
helpValue: "<id>"
|
|
352
330
|
}),
|
|
353
331
|
[EDIT_PROJECT_SETUP_FLAG]: Flags.boolean({
|
|
354
332
|
description: "Internal: this run continues an `init` project setup",
|
|
355
333
|
default: false,
|
|
356
334
|
hidden: true
|
|
357
|
-
})
|
|
335
|
+
}),
|
|
336
|
+
[EDIT_PROJECT_SETUP_MARKETPLACE_FLAG]: Flags.string({
|
|
337
|
+
description: "Internal: the marketplace `init --marketplace` named for that project setup",
|
|
338
|
+
hidden: true,
|
|
339
|
+
dependsOn: [EDIT_PROJECT_SETUP_FLAG]
|
|
340
|
+
}),
|
|
341
|
+
provider: providerFlag()
|
|
358
342
|
};
|
|
359
343
|
/**
|
|
360
344
|
* The command in two statements: do the work, then answer for it.
|
|
@@ -371,11 +355,18 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
371
355
|
async applyEdit() {
|
|
372
356
|
const { flags } = await this.parse(_Edit);
|
|
373
357
|
const cwd = process.cwd();
|
|
374
|
-
if (flags.ui && flags.from !== void 0) return this.openSharedInEditor(flags.from);
|
|
358
|
+
if (flags.ui && flags.from !== void 0) return this.openSharedInEditor(flags.from, cwd);
|
|
359
|
+
await refuseAnAmbiguousInstallation(
|
|
360
|
+
cwd,
|
|
361
|
+
"edit",
|
|
362
|
+
providerNamedBy(flags.provider),
|
|
363
|
+
(message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS })
|
|
364
|
+
);
|
|
375
365
|
await this.ensureConfigReadable(cwd);
|
|
366
|
+
await this.refuseUnofferablePlacements(cwd);
|
|
376
367
|
if (flags.ui) return this.openInEditor(cwd);
|
|
377
368
|
const payload = flags.from === void 0 ? null : await this.fetchSharedConfigOrFail(flags.from);
|
|
378
|
-
const context = await this.loadContextUnderSpinner();
|
|
369
|
+
const context = await this.loadContextUnderSpinner(flags[EDIT_PROJECT_SETUP_MARKETPLACE_FLAG]);
|
|
379
370
|
const editRoot = resolveEditRoot(context.installation, cwd, flags[EDIT_PROJECT_SETUP_FLAG]);
|
|
380
371
|
await this.ensureSavedSkillsReadable(
|
|
381
372
|
context.projectConfig?.skills ?? [],
|
|
@@ -396,26 +387,28 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
396
387
|
agentConfigs: activeNewAgents
|
|
397
388
|
};
|
|
398
389
|
const filteredOldConfig = context.projectConfig ? { ...context.projectConfig, skills: activeOldSkills, agents: activeOldAgents } : null;
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
390
|
+
const planned = withReassignments(
|
|
391
|
+
detectConfigChanges(filteredOldConfig, filteredResult, {
|
|
392
|
+
newSkills: result.skills,
|
|
393
|
+
oldSkills: context.projectConfig?.skills ?? [],
|
|
394
|
+
newAgents: result.agentConfigs,
|
|
395
|
+
oldAgents: context.projectConfig?.agents ?? []
|
|
396
|
+
}),
|
|
397
|
+
filteredResult,
|
|
398
|
+
context.projectConfig?.stack,
|
|
399
|
+
editRoot
|
|
400
|
+
);
|
|
401
|
+
const rewritten = selection.producer === "shared" ? await this.confirmAndWriteCarried(selection, planned, filteredResult) : [];
|
|
402
|
+
const changes = {
|
|
403
|
+
...planned,
|
|
404
|
+
rewrittenSkills: difference(rewritten, planned.addedSkills)
|
|
405
|
+
};
|
|
406
|
+
const authority = applyAuthority(editRoot);
|
|
415
407
|
if (!hasAnyChanges(changes)) {
|
|
416
408
|
this.log(chalk.hex(CLI_COLORS.NEUTRAL)("No changes made."));
|
|
417
409
|
if (!editRoot.isProjectSetup) return;
|
|
418
|
-
await this.writeConfigAndCompile(result, context, editRoot, authority);
|
|
410
|
+
await this.writeConfigAndCompile(result, context, editRoot, authority, selection.producer);
|
|
411
|
+
await this.reportWhatThisHostCannotCarry(editRoot);
|
|
419
412
|
this.logCompletionSummary(changes);
|
|
420
413
|
return;
|
|
421
414
|
}
|
|
@@ -445,16 +438,21 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
445
438
|
context
|
|
446
439
|
);
|
|
447
440
|
await this.applyScopeChanges(changes, filteredResult, context, editRoot);
|
|
441
|
+
await this.applyCollapsedPairs(changes, filteredResult, context, editRoot);
|
|
448
442
|
await this.applySourceChanges(changes, activeOldSkills, editRoot, migratedSkillIds);
|
|
449
443
|
await this.applyPluginChanges(changes, filteredResult, activeOldSkills, context, editRoot);
|
|
450
444
|
await this.copyNewLocalSkills(changes, filteredResult, context, editRoot);
|
|
451
445
|
await this.removeDeletedLocalSkills(changes, activeOldSkills, editRoot);
|
|
452
|
-
await this.writeConfigAndCompile(result, context, editRoot, authority);
|
|
446
|
+
await this.writeConfigAndCompile(result, context, editRoot, authority, selection.producer);
|
|
453
447
|
await this.cleanupStaleAgentFiles(changes, activeOldAgents, editRoot);
|
|
448
|
+
await this.reportWhatThisHostCannotCarry(editRoot);
|
|
454
449
|
this.logCompletionSummary(changes);
|
|
455
450
|
}
|
|
456
451
|
/** The interactive producer: open the wizard on what is installed, return what was chosen. */
|
|
457
452
|
async selectionFromWizard(context, editRoot) {
|
|
453
|
+
if (!process.stdin.isTTY) {
|
|
454
|
+
this.error(wizardNeedsTerminal("edit"), { exit: EXIT_CODES.ERROR });
|
|
455
|
+
}
|
|
458
456
|
const result = await this.runEditWizard(context, editRoot);
|
|
459
457
|
if (!result) return null;
|
|
460
458
|
return { producer: "wizard", result };
|
|
@@ -470,9 +468,12 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
470
468
|
* catalogue cannot place, because a destructive apply removes on intent and never on its own
|
|
471
469
|
* inability. Both are disclosed in the confirm rather than silently excused.
|
|
472
470
|
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
* entry back
|
|
471
|
+
* From a project the global install comes back too, whole: it is one installation every project
|
|
472
|
+
* on the machine reads, so a project run only ADDS to it (owner ruling 2026-10-02). Every global
|
|
473
|
+
* entry the configuration leaves out is put back as installed, every one it states otherwise is
|
|
474
|
+
* held as installed and named in the confirm, and only the global entries the global install
|
|
475
|
+
* lacks arrive — a skill with its rows, on a global sub-agent already there too. At the home
|
|
476
|
+
* directory the run IS the global install, so nothing is held there.
|
|
476
477
|
*/
|
|
477
478
|
async selectionFromSharedConfig(payload, context, editRoot) {
|
|
478
479
|
const { matrix: sourceMatrix } = context.sourceResult;
|
|
@@ -482,22 +483,38 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
482
483
|
sourceMatrix
|
|
483
484
|
);
|
|
484
485
|
this.refuseProjectScopedContentAtHome(result, editRoot.dir);
|
|
485
|
-
|
|
486
|
-
if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));
|
|
486
|
+
const unplaceable = new Set(skippedSkillIds);
|
|
487
487
|
const reconciled = reconcileSharedConfig({
|
|
488
|
-
decoded: result,
|
|
488
|
+
decoded: withUnplaceableAssignees(result, context.projectConfig, payload, unplaceable),
|
|
489
489
|
installed: context.projectConfig,
|
|
490
490
|
authoredHere: await this.readAuthoredHere(context.projectConfig, editRoot.dir),
|
|
491
|
-
|
|
492
|
-
// what STAYS rather than as what did not arrive: the payload named them, so their absence
|
|
493
|
-
// from the decode is this catalogue's limit and not an instruction to delete anything.
|
|
494
|
-
unplaceable: new Set(skippedSkillIds)
|
|
491
|
+
unplaceable
|
|
495
492
|
});
|
|
493
|
+
const held = restoreInstalledGlobal(
|
|
494
|
+
reconciled.result,
|
|
495
|
+
editRoot.isGlobal ? null : await readInstalledGlobal(editRoot.dir)
|
|
496
|
+
);
|
|
497
|
+
const arrivingCarried = notInstalledGlobally(carried, held);
|
|
498
|
+
await this.refuseSharedConfigBeforeAsking(
|
|
499
|
+
held.result,
|
|
500
|
+
arrivingCarried,
|
|
501
|
+
editRoot.dir,
|
|
502
|
+
context.sourceResult
|
|
503
|
+
);
|
|
504
|
+
const heldGlobally = difference(carried, arrivingCarried);
|
|
505
|
+
const revisedGlobally = await carriedSkillsThatDiffer(heldGlobally);
|
|
506
|
+
sayCapturedWarnings(context.startupMessages);
|
|
507
|
+
if (skippedSkillIds.length > 0) this.warn(skippedUnknownSkills(skippedSkillIds));
|
|
508
|
+
if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));
|
|
496
509
|
return {
|
|
497
510
|
producer: "shared",
|
|
498
|
-
result:
|
|
499
|
-
kept:
|
|
500
|
-
|
|
511
|
+
result: held.result,
|
|
512
|
+
kept: [
|
|
513
|
+
...keptStatements(reconciled.kept),
|
|
514
|
+
...unassignedStatement(reconciled.unassigned),
|
|
515
|
+
...keptAsInstalledStatement(held, revisedGlobally)
|
|
516
|
+
],
|
|
517
|
+
carried: arrivingCarried
|
|
501
518
|
};
|
|
502
519
|
}
|
|
503
520
|
/**
|
|
@@ -521,11 +538,17 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
521
538
|
/**
|
|
522
539
|
* The id, fetched — or the run refused before it is.
|
|
523
540
|
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
* that had already spent a round trip would be describing work it never
|
|
541
|
+
* Two questions are answered first, because nothing in the payload can change either answer:
|
|
542
|
+
* an apply with nothing to apply to, or that cannot be confirmed, is over before the store is
|
|
543
|
+
* asked, and a refusal that had already spent a round trip would be describing work it never
|
|
544
|
+
* intended to do. Whether anything is installed comes before the terminal: the terminal
|
|
545
|
+
* refusal's way on is this same command from a terminal, which in a folder with nothing
|
|
546
|
+
* installed would only refuse again.
|
|
527
547
|
*/
|
|
528
548
|
async fetchSharedConfigOrFail(id) {
|
|
549
|
+
if (!await detectProject()) {
|
|
550
|
+
this.error(nothingInstalledToApplyTo(id), { exit: EXIT_CODES.ERROR });
|
|
551
|
+
}
|
|
529
552
|
if (!process.stdin.isTTY) {
|
|
530
553
|
this.error(sharedConfigNeedsTerminal(id), { exit: EXIT_CODES.ERROR });
|
|
531
554
|
}
|
|
@@ -562,11 +585,20 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
562
585
|
this.handleError(error);
|
|
563
586
|
}
|
|
564
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Confirms a shared configuration, then writes the skills it brought with it — answering with
|
|
590
|
+
* those whose files now read differently.
|
|
591
|
+
*/
|
|
592
|
+
async confirmAndWriteCarried(selection, planned, result) {
|
|
593
|
+
await this.confirmSharedConfigOrCancel(planned, selection.kept, applyArrivals(planned, result));
|
|
594
|
+
return this.writeCarriedSkills(selection.carried);
|
|
595
|
+
}
|
|
565
596
|
/** Writes the skills the configuration brought with it, and says which they were. */
|
|
566
597
|
async writeCarriedSkills(carried) {
|
|
567
|
-
if (carried.length === 0) return;
|
|
568
|
-
await writeExternalSkills(carried);
|
|
598
|
+
if (carried.length === 0) return [];
|
|
599
|
+
const rewritten = await writeExternalSkills(carried);
|
|
569
600
|
this.log(carriedSkillsWritten(carried.map((skill) => skill.id)));
|
|
601
|
+
return rewritten;
|
|
570
602
|
}
|
|
571
603
|
/**
|
|
572
604
|
* Shows what applying this configuration takes away, and stops the run unless a person says
|
|
@@ -577,18 +609,15 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
577
609
|
* honesty: nothing is refused over an entry this run cannot remove, and nothing is silent
|
|
578
610
|
* about one either.
|
|
579
611
|
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
* looking at, so it is shown apart and the reach is named.
|
|
612
|
+
* Above it go the two lists every `--from` install prints — what the apply adds or changes in
|
|
613
|
+
* this project, and in the global install — so the question is asked about the whole of what a
|
|
614
|
+
* yes does, not only about what it takes away.
|
|
584
615
|
*/
|
|
585
|
-
async confirmSharedConfigOrCancel(changes, kept,
|
|
586
|
-
const plan =
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
await this.otherRegisteredProjects(editRoot.dir)
|
|
591
|
-
);
|
|
616
|
+
async confirmSharedConfigOrCancel(changes, kept, arrivals) {
|
|
617
|
+
const plan = sharedConfigPlan(changes, kept);
|
|
618
|
+
for (const line of arrivalLines(arrivals)) {
|
|
619
|
+
this.log(line);
|
|
620
|
+
}
|
|
592
621
|
const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(
|
|
593
622
|
RemovalPlanConfirm,
|
|
594
623
|
{
|
|
@@ -605,25 +634,16 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
605
634
|
this.error("Cancelled", { exit: EXIT_CODES.CANCELLED });
|
|
606
635
|
}
|
|
607
636
|
/**
|
|
608
|
-
*
|
|
637
|
+
* Refuses a configuration whose own host cannot place what it asks for, before the wizard runs.
|
|
609
638
|
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
* Best-effort by nature. The list exists to be DISCLOSED, so a home directory that cannot be
|
|
615
|
-
* read leaves the disclosure counting nobody rather than failing an apply — and the statement
|
|
616
|
-
* it produces then is the one that says no other project is registered.
|
|
639
|
+
* `compile` asks the same question of the same roster and `update` asks it too. `edit` is the
|
|
640
|
+
* command that REWRITES the file, so letting it through would mean a user curating a
|
|
641
|
+
* configuration no command will act on — and then saving it back, with the unofferable row
|
|
642
|
+
* carried forward because nothing on the edit path had any reason to drop it.
|
|
617
643
|
*/
|
|
618
|
-
async
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
const here = normalizeProjectPath(editRoot);
|
|
622
|
-
return (global?.config.projects ?? []).filter((projectDir) => projectDir !== here);
|
|
623
|
-
} catch (error) {
|
|
624
|
-
this.warn(`Could not tell which projects share this install: ${getErrorMessage(error)}`);
|
|
625
|
-
return [];
|
|
626
|
-
}
|
|
644
|
+
async refuseUnofferablePlacements(cwd) {
|
|
645
|
+
const [finding] = await unofferablePlacementsFound(cwd);
|
|
646
|
+
if (finding !== void 0) this.error(finding, { exit: EXIT_CODES.ERROR });
|
|
627
647
|
}
|
|
628
648
|
/**
|
|
629
649
|
* The outbound half of the editor round trip: this installation, minted as a configuration
|
|
@@ -637,37 +657,37 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
637
657
|
* Nothing on disk is touched. A configuration is read, not rewritten, so a run that changed
|
|
638
658
|
* anything here would be editing the project on the way to offering to edit it.
|
|
639
659
|
*/
|
|
660
|
+
async openInEditor(projectDir) {
|
|
661
|
+
const prepared = await seedPayloadForInstallation(projectDir);
|
|
662
|
+
if (!prepared.ok) {
|
|
663
|
+
this.error(prepared.error, { exit: EXIT_CODES.ERROR });
|
|
664
|
+
}
|
|
665
|
+
this.log(`Opening ${prepared.skills} skill(s) across ${prepared.agents} sub-agent(s)...`);
|
|
666
|
+
const published = await publishSeedConfig(prepared.payload);
|
|
667
|
+
if (!published.ok) {
|
|
668
|
+
this.error(published.error, { exit: EXIT_CODES.ERROR });
|
|
669
|
+
}
|
|
670
|
+
await this.handToBrowser(published.id);
|
|
671
|
+
}
|
|
640
672
|
/**
|
|
641
673
|
* An id somebody shared, opened rather than applied.
|
|
642
674
|
*
|
|
643
675
|
* The counterpart of `openInEditor` above and deliberately not a variant of it: that one MINTS,
|
|
644
676
|
* because an installation is not yet a configuration the store holds. An id already is one, so
|
|
645
|
-
* there is nothing to publish,
|
|
646
|
-
*
|
|
677
|
+
* there is nothing to publish, and no way for this to fail except the browser refusing to launch
|
|
678
|
+
* — which is a warning beside a link that still works.
|
|
647
679
|
*
|
|
648
680
|
* `--from` without `--ui` remains the destructive apply. Looking and applying are the two
|
|
649
681
|
* things a recipient can do with an id, and this is the one that changes nothing.
|
|
650
682
|
*/
|
|
651
|
-
async openSharedInEditor(id) {
|
|
683
|
+
async openSharedInEditor(id, cwd) {
|
|
652
684
|
const url = editorConfigUrl(id);
|
|
653
685
|
this.log(`Open it at ${url}`);
|
|
654
|
-
this.log(
|
|
686
|
+
this.log(applySharedConfigHere(id, await holdsItsOwnInstallation(cwd)));
|
|
655
687
|
if (!process.stdin.isTTY) return;
|
|
656
688
|
const opened = await openUrl(url);
|
|
657
689
|
if (!opened.ok) this.warn(opened.error);
|
|
658
690
|
}
|
|
659
|
-
async openInEditor(projectDir) {
|
|
660
|
-
const prepared = await seedPayloadForInstallation(projectDir);
|
|
661
|
-
if (!prepared.ok) {
|
|
662
|
-
this.error(prepared.error, { exit: EXIT_CODES.ERROR });
|
|
663
|
-
}
|
|
664
|
-
this.log(`Opening ${prepared.skills} skill(s) across ${prepared.agents} sub-agent(s)...`);
|
|
665
|
-
const published = await publishSeedConfig(prepared.payload);
|
|
666
|
-
if (!published.ok) {
|
|
667
|
-
this.error(published.error, { exit: EXIT_CODES.ERROR });
|
|
668
|
-
}
|
|
669
|
-
await this.handToBrowser(published.id);
|
|
670
|
-
}
|
|
671
691
|
/**
|
|
672
692
|
* The link, printed first and opened second.
|
|
673
693
|
*
|
|
@@ -690,25 +710,20 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
690
710
|
if (!opened.ok) this.warn(opened.error);
|
|
691
711
|
}
|
|
692
712
|
/**
|
|
693
|
-
* The load below, behind a spinner that comes down whichever way the await ends
|
|
694
|
-
*
|
|
695
|
-
* The cleanup is a `finally` because all three of `loadContext`'s refusals are raised
|
|
696
|
-
* while this spinner is mounted, and oclif would otherwise paint its error under an Ink
|
|
697
|
-
* tree still repainting over it. Never a `catch`: the throw reaches oclif untouched, or
|
|
698
|
-
* both the error rendering and the pinned exit codes change with it.
|
|
713
|
+
* The load below, behind a spinner that comes down whichever way the await ends — all
|
|
714
|
+
* three of `loadContext`'s refusals are raised while it is mounted.
|
|
699
715
|
*/
|
|
700
|
-
async loadContextUnderSpinner() {
|
|
701
|
-
|
|
702
|
-
|
|
716
|
+
async loadContextUnderSpinner(setupMarketplace) {
|
|
717
|
+
return awaitUnderSpinner(
|
|
718
|
+
STATUS_MESSAGES.LOADING_SKILLS,
|
|
719
|
+
() => this.loadContext(setupMarketplace)
|
|
703
720
|
);
|
|
704
|
-
try {
|
|
705
|
-
return await this.loadContext();
|
|
706
|
-
} finally {
|
|
707
|
-
clearSpinner();
|
|
708
|
-
unmount();
|
|
709
|
-
}
|
|
710
721
|
}
|
|
711
|
-
|
|
722
|
+
/**
|
|
723
|
+
* @param setupMarketplace - What `init --marketplace` named for the project setup this run
|
|
724
|
+
* continues. Absent, the catalogue is the one the installation stored.
|
|
725
|
+
*/
|
|
726
|
+
async loadContext(setupMarketplace) {
|
|
712
727
|
const detected = await detectProject();
|
|
713
728
|
if (!detected) {
|
|
714
729
|
this.error(ERROR_MESSAGES.NO_INSTALLATION, {
|
|
@@ -720,13 +735,17 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
720
735
|
let sourceResult;
|
|
721
736
|
let startupMessages = [];
|
|
722
737
|
try {
|
|
723
|
-
const loaded = await loadSource({
|
|
738
|
+
const loaded = await loadSource({
|
|
739
|
+
projectDir,
|
|
740
|
+
...setupMarketplace !== void 0 && { sourceFlag: setupMarketplace },
|
|
741
|
+
captureStartupMessages: true
|
|
742
|
+
});
|
|
724
743
|
sourceResult = loaded.sourceResult;
|
|
725
744
|
startupMessages = loaded.startupMessages;
|
|
726
745
|
const sourceInfo = sourceResult.isLocal ? "local" : sourceResult.sourceConfig.sourceOrigin;
|
|
727
746
|
startupMessages.push({
|
|
728
747
|
level: "info",
|
|
729
|
-
text: `Loaded ${Object.keys(matrix.skills).length}
|
|
748
|
+
text: `Loaded ${plural(Object.keys(matrix.skills).length, "skill")} (${sourceInfo})`
|
|
730
749
|
});
|
|
731
750
|
} catch (error) {
|
|
732
751
|
this.handleError(error);
|
|
@@ -744,7 +763,7 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
744
763
|
currentSkillIds = [...mergedIds];
|
|
745
764
|
startupMessages.push({
|
|
746
765
|
level: "info",
|
|
747
|
-
text: `Found ${currentSkillIds.length
|
|
766
|
+
text: `Found ${plural(currentSkillIds.length, "installed skill")}`
|
|
748
767
|
});
|
|
749
768
|
} catch (error) {
|
|
750
769
|
this.handleError(error);
|
|
@@ -755,7 +774,8 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
755
774
|
projectDir,
|
|
756
775
|
sourceResult,
|
|
757
776
|
startupMessages,
|
|
758
|
-
currentSkillIds
|
|
777
|
+
currentSkillIds,
|
|
778
|
+
...setupMarketplace !== void 0 && sourceResult.marketplace !== void 0 && { setupMarketplace: sourceResult.marketplace }
|
|
759
779
|
};
|
|
760
780
|
}
|
|
761
781
|
async runEditWizard(context, editRoot) {
|
|
@@ -771,7 +791,10 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
771
791
|
installedSkillIds: currentSkillIds,
|
|
772
792
|
...projectConfig?.skills !== void 0 && { installedSkillConfigs: projectConfig.skills },
|
|
773
793
|
...projectConfig?.agents !== void 0 && { installedAgentConfigs: projectConfig.agents },
|
|
774
|
-
isEditingFromGlobalScope: editRoot.isGlobal
|
|
794
|
+
isEditingFromGlobalScope: editRoot.isGlobal,
|
|
795
|
+
...context.setupMarketplace !== void 0 && {
|
|
796
|
+
setupMarketplace: context.setupMarketplace
|
|
797
|
+
}
|
|
775
798
|
},
|
|
776
799
|
props: {
|
|
777
800
|
version: this.config.version,
|
|
@@ -840,7 +863,7 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
840
863
|
loadAgents: async () => (await loadAgentDefs()).agents
|
|
841
864
|
}
|
|
842
865
|
);
|
|
843
|
-
this.
|
|
866
|
+
this.reportFanOut(report);
|
|
844
867
|
} catch (error) {
|
|
845
868
|
this.reportIncompleteWork(
|
|
846
869
|
`Could not record global origin change: ${getErrorMessage(error)}`,
|
|
@@ -858,7 +881,10 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
858
881
|
scopeChanges,
|
|
859
882
|
agentScopeChanges,
|
|
860
883
|
dualScopeSkillTransitions,
|
|
861
|
-
dualScopeAgentTransitions
|
|
884
|
+
dualScopeAgentTransitions,
|
|
885
|
+
tuningChanges,
|
|
886
|
+
reassignedAgents,
|
|
887
|
+
rewrittenSkills
|
|
862
888
|
} = changes;
|
|
863
889
|
this.log(`
|
|
864
890
|
${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
@@ -901,10 +927,26 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
901
927
|
for (const [agentName, change] of agentScopeChanges) {
|
|
902
928
|
this.log(formatAgentScopeChangeLine(agentName, change, dualScopeAgentTransitions));
|
|
903
929
|
}
|
|
930
|
+
for (const [agentName, change] of tuningChanges) {
|
|
931
|
+
this.log(formatValueChangeLine(agentName, change, "agent"));
|
|
932
|
+
}
|
|
933
|
+
for (const agentName of reassignedAgents) {
|
|
934
|
+
this.log(
|
|
935
|
+
chalk.hex(CLI_COLORS.WARNING)(` ~ ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (agent: skills reassigned)")
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
for (const skillId of rewrittenSkills) {
|
|
939
|
+
this.log(
|
|
940
|
+
chalk.hex(CLI_COLORS.WARNING)(` ~ ${getSkillDisplayName(skillId)}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (skill: files rewritten)")
|
|
941
|
+
);
|
|
942
|
+
}
|
|
904
943
|
this.log("");
|
|
905
944
|
}
|
|
906
|
-
async applyMigrations(
|
|
907
|
-
const migrationPlan = detectMigrations(
|
|
945
|
+
async applyMigrations(changes, filteredResult, activeOldSkills, context, editRoot) {
|
|
946
|
+
const migrationPlan = detectMigrations(
|
|
947
|
+
withMaskedGlobalsRestored(activeOldSkills, changes.collapsedPairs),
|
|
948
|
+
filteredResult.skills
|
|
949
|
+
);
|
|
908
950
|
const migratedSkillIds = /* @__PURE__ */ new Set([
|
|
909
951
|
...migrationPlan.toEject.map((m) => m.id),
|
|
910
952
|
...migrationPlan.toPlugin.map((m) => m.id)
|
|
@@ -915,7 +957,11 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
915
957
|
}
|
|
916
958
|
if (migrationPlan.toPlugin.length > 0) {
|
|
917
959
|
this.logModeSwitch(migrationPlan.toPlugin.length, INSTALL_MODE_DESCRIPTIONS.plugin);
|
|
918
|
-
await this.requireMarketplaceOrExit(
|
|
960
|
+
await this.requireMarketplaceOrExit(
|
|
961
|
+
context.sourceResult,
|
|
962
|
+
"migrate skills to plugin mode",
|
|
963
|
+
hostAt(editRoot.dir)
|
|
964
|
+
);
|
|
919
965
|
this.announcePluginInstall();
|
|
920
966
|
}
|
|
921
967
|
const migrationResult = await executeMigration(
|
|
@@ -961,8 +1007,13 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
961
1007
|
logModeSwitch(count, modeDescription) {
|
|
962
1008
|
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Switching ${count} skill(s) to ${modeDescription}`));
|
|
963
1009
|
}
|
|
1010
|
+
/**
|
|
1011
|
+
* The scope moves this edit made, on disk. A collapsed `[P][G]` pair is not one of them: its
|
|
1012
|
+
* project half is dropped or folded ({@link applyCollapsedPairs}), and moving every collapse is
|
|
1013
|
+
* what wrote a dropped copy over the global install.
|
|
1014
|
+
*/
|
|
964
1015
|
async applyScopeChanges(changes, filteredResult, context, editRoot) {
|
|
965
|
-
const
|
|
1016
|
+
const scopeChanges = scopeMovesOf(changes);
|
|
966
1017
|
for (const [skillId, change] of scopeChanges) {
|
|
967
1018
|
const skillConfig = filteredResult.skills.find((s) => s.id === skillId);
|
|
968
1019
|
if (skillConfig?.origin === EJECT_SOURCE) {
|
|
@@ -976,7 +1027,8 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
976
1027
|
if (!hasPluginScopeChanges) return;
|
|
977
1028
|
const marketplace = await this.requireMarketplaceOrExit(
|
|
978
1029
|
context.sourceResult,
|
|
979
|
-
"migrate plugin skill scopes"
|
|
1030
|
+
"migrate plugin skill scopes",
|
|
1031
|
+
hostAt(editRoot.dir)
|
|
980
1032
|
);
|
|
981
1033
|
const pluginScopeResult = await migratePluginSkillScopes(
|
|
982
1034
|
scopeChanges,
|
|
@@ -991,6 +1043,63 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
991
1043
|
);
|
|
992
1044
|
}
|
|
993
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* The project's own half of each `[P][G]` pair this edit collapsed. A Local copy `s` folded into
|
|
1048
|
+
* a Local global install moves there, edits included, replacing the global copy every project
|
|
1049
|
+
* reads. Every other half is removed at project scope and nowhere else: its ejected copy deleted,
|
|
1050
|
+
* or its project-scope plugin registration uninstalled.
|
|
1051
|
+
*
|
|
1052
|
+
* The global install's MODE is {@link applyMigrations}' to change, and it changes only when the
|
|
1053
|
+
* collapse carried a new install mode with it — a fold into a plugin installs the plugin there.
|
|
1054
|
+
*
|
|
1055
|
+
* The uninstall is diagnostic, as every plugin uninstall here is: the config no longer names the
|
|
1056
|
+
* registration, so one left behind is untidy rather than wrong.
|
|
1057
|
+
*/
|
|
1058
|
+
async applyCollapsedPairs(changes, filteredResult, context, editRoot) {
|
|
1059
|
+
const [foldedCopies, removedPairs] = partition(
|
|
1060
|
+
changes.collapsedPairs,
|
|
1061
|
+
(pair) => foldsItsCopyIntoGlobal(pair, filteredResult.skills)
|
|
1062
|
+
);
|
|
1063
|
+
const [ejectedHalves, pluginHalves] = partition(
|
|
1064
|
+
removedPairs.map(({ projectHalf }) => projectHalf),
|
|
1065
|
+
(half) => half.origin === EJECT_SOURCE
|
|
1066
|
+
);
|
|
1067
|
+
for (const { projectHalf } of foldedCopies) {
|
|
1068
|
+
await foldLocalSkillIntoGlobal(editRoot.dir, projectHalf.id);
|
|
1069
|
+
}
|
|
1070
|
+
for (const half of ejectedHalves) {
|
|
1071
|
+
await deleteLocalSkill(editRoot.dir, half.id, half.scope);
|
|
1072
|
+
}
|
|
1073
|
+
await this.uninstallProjectPluginHalves(
|
|
1074
|
+
pluginHalves,
|
|
1075
|
+
context.sourceResult.marketplace,
|
|
1076
|
+
editRoot
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
/** The project-scope registrations of collapsed pairs' plugin halves, uninstalled and reported. */
|
|
1080
|
+
async uninstallProjectPluginHalves(pluginHalves, marketplace, editRoot) {
|
|
1081
|
+
if (pluginHalves.length === 0) return;
|
|
1082
|
+
if (marketplace === void 0) {
|
|
1083
|
+
for (const half of pluginHalves) {
|
|
1084
|
+
this.warn(`Could not uninstall this project's plugin for ${half.id}: no marketplace`);
|
|
1085
|
+
}
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
const uninstallResult = await uninstallPluginSkills(
|
|
1089
|
+
pluginHalves.map((half) => half.id),
|
|
1090
|
+
pluginHalves,
|
|
1091
|
+
marketplace,
|
|
1092
|
+
editRoot.dir
|
|
1093
|
+
);
|
|
1094
|
+
if (uninstallResult.uninstalled.length > 0) {
|
|
1095
|
+
this.log(
|
|
1096
|
+
chalk.hex(CLI_COLORS.NEUTRAL)(`Removed ${uninstallResult.uninstalled.length} plugin(s)`)
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
for (const item of uninstallResult.failed) {
|
|
1100
|
+
this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
994
1103
|
async applySourceChanges(changes, activeOldSkills, editRoot, migratedSkillIds) {
|
|
995
1104
|
const { sourceChanges } = changes;
|
|
996
1105
|
for (const [skillId, change] of sourceChanges) {
|
|
@@ -999,8 +1108,7 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
999
1108
|
}
|
|
1000
1109
|
if (change.from === EJECT_SOURCE) {
|
|
1001
1110
|
const oldSkill = activeOldSkills.find((s) => s.id === skillId);
|
|
1002
|
-
|
|
1003
|
-
await deleteLocalSkill(deleteDir, skillId);
|
|
1111
|
+
await deleteLocalSkill(editRoot.dir, skillId, oldSkill?.scope);
|
|
1004
1112
|
}
|
|
1005
1113
|
}
|
|
1006
1114
|
}
|
|
@@ -1015,7 +1123,8 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
1015
1123
|
if (addedPluginSkills.length === 0 && removedPluginSkills.length === 0) return;
|
|
1016
1124
|
const marketplace = await this.requireMarketplaceOrExit(
|
|
1017
1125
|
context.sourceResult,
|
|
1018
|
-
"install or uninstall plugin skills"
|
|
1126
|
+
"install or uninstall plugin skills",
|
|
1127
|
+
hostAt(editRoot.dir)
|
|
1019
1128
|
);
|
|
1020
1129
|
if (addedPluginSkills.length > 0) {
|
|
1021
1130
|
await this.installPluginSkillsReported(
|
|
@@ -1061,11 +1170,10 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
1061
1170
|
for (const skillId of removedSkills) {
|
|
1062
1171
|
const oldSkill = activeOldSkills.find((s) => s.id === skillId);
|
|
1063
1172
|
if (oldSkill?.origin !== EJECT_SOURCE) continue;
|
|
1064
|
-
|
|
1065
|
-
await deleteLocalSkill(deleteDir, skillId);
|
|
1173
|
+
await deleteLocalSkill(editRoot.dir, skillId, oldSkill.scope);
|
|
1066
1174
|
}
|
|
1067
1175
|
}
|
|
1068
|
-
async writeConfigAndCompile(result, context, editRoot, authority) {
|
|
1176
|
+
async writeConfigAndCompile(result, context, editRoot, authority, producer) {
|
|
1069
1177
|
let agentDefsResult;
|
|
1070
1178
|
try {
|
|
1071
1179
|
agentDefsResult = await loadAgentDefs();
|
|
@@ -1090,11 +1198,12 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
1090
1198
|
exit: EXIT_CODES.ERROR
|
|
1091
1199
|
});
|
|
1092
1200
|
}
|
|
1093
|
-
this.reportUnassignedSkills(configResult.config);
|
|
1201
|
+
this.reportUnassignedSkills(configResult.config, result.skills);
|
|
1094
1202
|
try {
|
|
1095
1203
|
const agentScopeMap = activeAgentScopeMap(result.agentConfigs);
|
|
1096
1204
|
const { allSkills } = await discoverInstalledSkills(editRoot.dir);
|
|
1097
|
-
const
|
|
1205
|
+
const compile = compilesGlobalScope(producer, editRoot, configResult.propagation) ? compileAgentsAllScopes : compileProjectScope;
|
|
1206
|
+
const compilationResult = await compile({
|
|
1098
1207
|
projectDir: editRoot.dir,
|
|
1099
1208
|
sourcePath: agentDefsResult.sourcePath,
|
|
1100
1209
|
skills: allSkills,
|
|
@@ -1126,7 +1235,7 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
1126
1235
|
);
|
|
1127
1236
|
this.log(`You can manually recompile with '${CLI_INVOKE_COMMAND} compile'.`);
|
|
1128
1237
|
}
|
|
1129
|
-
this.
|
|
1238
|
+
this.reportFanOut(configResult.propagation);
|
|
1130
1239
|
}
|
|
1131
1240
|
async cleanupStaleAgentFiles(changes, oldAgents, editRoot) {
|
|
1132
1241
|
for (const removal of planStaleAgentRemovals(changes, oldAgents, editRoot.dir)) {
|
|
@@ -1140,6 +1249,24 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
1140
1249
|
}
|
|
1141
1250
|
}
|
|
1142
1251
|
}
|
|
1252
|
+
/**
|
|
1253
|
+
* What this host could not carry, once per run and after the last write: the lines `init` and
|
|
1254
|
+
* `compile` print, from {@link hostCompileNotices}, so `edit` cannot say something different
|
|
1255
|
+
* about the tree it just compiled.
|
|
1256
|
+
*
|
|
1257
|
+
* After {@link cleanupStaleAgentFiles}, because the question is about the tree as it now stands:
|
|
1258
|
+
* an edit that removed the project's last gated sub-agent must not count the file it deleted.
|
|
1259
|
+
*
|
|
1260
|
+
* Not on a run that owes work, which ends on that account instead: such a run may have left
|
|
1261
|
+
* nothing here to read, and a notice that threw over it would turn the run's
|
|
1262
|
+
* `COMPLETED_WITH_FAILURES` exit into an `ERROR`.
|
|
1263
|
+
*/
|
|
1264
|
+
async reportWhatThisHostCannotCarry(editRoot) {
|
|
1265
|
+
if (this.hasIncompleteWork) return;
|
|
1266
|
+
for (const notice of await hostCompileNotices(providerInUse(editRoot.dir), editRoot.dir)) {
|
|
1267
|
+
this.log(notice);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1143
1270
|
logCompletionSummary(_changes) {
|
|
1144
1271
|
if (this.hasIncompleteWork) return;
|
|
1145
1272
|
this.log(`
|
|
@@ -1166,6 +1293,18 @@ function detectConfigChanges(oldConfig, wizardResult, fullEntries) {
|
|
|
1166
1293
|
(a) => a.name,
|
|
1167
1294
|
(a) => a.scope
|
|
1168
1295
|
);
|
|
1296
|
+
const dualScopeSkillTransitions = detectDualScopeTransitions(
|
|
1297
|
+
scopeChanges,
|
|
1298
|
+
fullEntries?.newSkills ?? [],
|
|
1299
|
+
fullEntries?.oldSkills ?? [],
|
|
1300
|
+
(s) => s.id
|
|
1301
|
+
);
|
|
1302
|
+
const collapsedPairs = collapsedPairsOf(
|
|
1303
|
+
scopeChanges,
|
|
1304
|
+
dualScopeSkillTransitions,
|
|
1305
|
+
fullEntries?.oldSkills ?? [],
|
|
1306
|
+
wizardResult.foldedSkillIds ?? []
|
|
1307
|
+
);
|
|
1169
1308
|
return {
|
|
1170
1309
|
addedSkills: difference(newSkillIds, oldSkillIds),
|
|
1171
1310
|
removedSkills: difference(oldSkillIds, newSkillIds),
|
|
@@ -1173,26 +1312,36 @@ function detectConfigChanges(oldConfig, wizardResult, fullEntries) {
|
|
|
1173
1312
|
removedAgents: difference(oldAgentNames, newAgentNames),
|
|
1174
1313
|
sourceChanges: detectPropertyChanges(
|
|
1175
1314
|
wizardResult.skills,
|
|
1176
|
-
|
|
1315
|
+
indexBy(withMaskedGlobalsRestored(oldConfig?.skills ?? [], collapsedPairs), (s) => s.id),
|
|
1177
1316
|
(s) => s.id,
|
|
1178
1317
|
(s) => s.origin
|
|
1179
1318
|
),
|
|
1180
1319
|
scopeChanges,
|
|
1181
1320
|
agentScopeChanges,
|
|
1182
|
-
dualScopeSkillTransitions
|
|
1183
|
-
|
|
1184
|
-
fullEntries?.newSkills ?? [],
|
|
1185
|
-
fullEntries?.oldSkills ?? [],
|
|
1186
|
-
(s) => s.id
|
|
1187
|
-
),
|
|
1321
|
+
dualScopeSkillTransitions,
|
|
1322
|
+
collapsedPairs,
|
|
1188
1323
|
dualScopeAgentTransitions: detectDualScopeTransitions(
|
|
1189
1324
|
agentScopeChanges,
|
|
1190
1325
|
fullEntries?.newAgents ?? [],
|
|
1191
1326
|
fullEntries?.oldAgents ?? [],
|
|
1192
1327
|
(a) => a.name
|
|
1328
|
+
),
|
|
1329
|
+
tuningChanges: detectPropertyChanges(
|
|
1330
|
+
wizardResult.agentConfigs,
|
|
1331
|
+
oldAgentsByName,
|
|
1332
|
+
(a) => a.name,
|
|
1333
|
+
describeTuning
|
|
1193
1334
|
)
|
|
1194
1335
|
};
|
|
1195
1336
|
}
|
|
1337
|
+
var RESTING_TUNING = "defaults";
|
|
1338
|
+
function describeTuning(agent) {
|
|
1339
|
+
const settings = [
|
|
1340
|
+
agent.model === void 0 ? void 0 : `model ${agent.model}`,
|
|
1341
|
+
agent.effort === void 0 ? void 0 : `effort ${agent.effort}`
|
|
1342
|
+
].filter((setting) => setting !== void 0);
|
|
1343
|
+
return settings.length === 0 ? RESTING_TUNING : settings.join(", ");
|
|
1344
|
+
}
|
|
1196
1345
|
function detectPropertyChanges(newItems, oldByKey, getKey, getValue) {
|
|
1197
1346
|
const changes = /* @__PURE__ */ new Map();
|
|
1198
1347
|
for (const item of newItems) {
|
|
@@ -1216,6 +1365,46 @@ function detectDualScopeTransitions(scopeChanges, fullNew, fullOld, getKey) {
|
|
|
1216
1365
|
}
|
|
1217
1366
|
return result;
|
|
1218
1367
|
}
|
|
1368
|
+
function collapsedPairsOf(scopeChanges, dualScopeSkillTransitions, fullOldSkills, foldedSkillIds) {
|
|
1369
|
+
return [...scopeChanges].filter(([id, change]) => change.to === "global" && dualScopeSkillTransitions.has(id)).map(([id]) => ({
|
|
1370
|
+
projectHalf: oldHalfOf(fullOldSkills, id, (skill) => isActiveAt(skill, "project")),
|
|
1371
|
+
maskedGlobal: oldHalfOf(fullOldSkills, id, isGlobalTombstone),
|
|
1372
|
+
folded: foldedSkillIds.includes(id)
|
|
1373
|
+
}));
|
|
1374
|
+
}
|
|
1375
|
+
function foldsItsCopyIntoGlobal(pair, newSkills) {
|
|
1376
|
+
const { projectHalf, folded } = pair;
|
|
1377
|
+
const globalEntry = newSkills.find(
|
|
1378
|
+
(skill) => skill.id === projectHalf.id && isActiveAt(skill, "global")
|
|
1379
|
+
);
|
|
1380
|
+
return folded && projectHalf.origin === EJECT_SOURCE && globalEntry?.origin === EJECT_SOURCE;
|
|
1381
|
+
}
|
|
1382
|
+
function oldHalfOf(fullOldSkills, id, isHalf) {
|
|
1383
|
+
const half = fullOldSkills.find((skill) => skill.id === id && isHalf(skill));
|
|
1384
|
+
if (half === void 0) {
|
|
1385
|
+
throw new Error(`The config before this edit holds no such half of the pair for '${id}'`);
|
|
1386
|
+
}
|
|
1387
|
+
return half;
|
|
1388
|
+
}
|
|
1389
|
+
function withMaskedGlobalsRestored(oldSkills, collapsedPairs) {
|
|
1390
|
+
const maskedById = indexBy(
|
|
1391
|
+
collapsedPairs.map(({ maskedGlobal }) => maskedGlobal),
|
|
1392
|
+
(skill) => skill.id
|
|
1393
|
+
);
|
|
1394
|
+
return oldSkills.map((skill) => {
|
|
1395
|
+
const masked = maskedById[skill.id];
|
|
1396
|
+
if (masked === void 0 || skill.scope !== "project") return skill;
|
|
1397
|
+
return installRecordedBy(masked);
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
function installRecordedBy(tombstone) {
|
|
1401
|
+
const { excluded: _masked, ...install } = tombstone;
|
|
1402
|
+
return install;
|
|
1403
|
+
}
|
|
1404
|
+
function scopeMovesOf(changes) {
|
|
1405
|
+
const collapsed = new Set(changes.collapsedPairs.map(({ projectHalf }) => projectHalf.id));
|
|
1406
|
+
return new Map([...changes.scopeChanges].filter(([id]) => !collapsed.has(id)));
|
|
1407
|
+
}
|
|
1219
1408
|
var STALE_AGENT_SCOPES = ["project", "global"];
|
|
1220
1409
|
var UNRECORDED_AGENT_SCOPE = "project";
|
|
1221
1410
|
function installedScope(name, oldAgents) {
|
|
@@ -1235,9 +1424,10 @@ function planStaleAgentRemovals(changes, oldAgents, editRoot) {
|
|
|
1235
1424
|
return STALE_AGENT_SCOPES.map(removalAtScope).filter((removal) => removal.agents.length > 0);
|
|
1236
1425
|
}
|
|
1237
1426
|
function hasAnyChanges(changes) {
|
|
1238
|
-
return changes.addedSkills.length > 0 || changes.removedSkills.length > 0 || changes.addedAgents.length > 0 || changes.removedAgents.length > 0 || changes.sourceChanges.size > 0 || changes.scopeChanges.size > 0 || changes.agentScopeChanges.size > 0;
|
|
1427
|
+
return changes.reassignedAgents.length > 0 || changes.rewrittenSkills.length > 0 || changes.addedSkills.length > 0 || changes.removedSkills.length > 0 || changes.addedAgents.length > 0 || changes.removedAgents.length > 0 || changes.sourceChanges.size > 0 || changes.scopeChanges.size > 0 || changes.agentScopeChanges.size > 0 || changes.tuningChanges.size > 0;
|
|
1239
1428
|
}
|
|
1240
1429
|
async function migratePluginSkillScopes(scopeChanges, skills, marketplace, projectDir) {
|
|
1430
|
+
const host = hostAt(projectDir);
|
|
1241
1431
|
const migrated = [];
|
|
1242
1432
|
const failed = [];
|
|
1243
1433
|
for (const [skillId, change] of scopeChanges) {
|
|
@@ -1245,13 +1435,12 @@ async function migratePluginSkillScopes(scopeChanges, skills, marketplace, proje
|
|
|
1245
1435
|
if (!skillConfig || skillConfig.origin === EJECT_SOURCE) {
|
|
1246
1436
|
continue;
|
|
1247
1437
|
}
|
|
1248
|
-
const newPluginScope = toClaudePluginScope(change.to);
|
|
1249
1438
|
const pluginRef = buildMarketplacePluginRef(skillId, marketplace);
|
|
1250
1439
|
try {
|
|
1251
1440
|
if (change.from === "project") {
|
|
1252
|
-
await
|
|
1441
|
+
await host.uninstallPlugin(pluginRef, "project", projectDir);
|
|
1253
1442
|
}
|
|
1254
|
-
await
|
|
1443
|
+
await host.installPlugin(pluginRef, change.to, projectDir);
|
|
1255
1444
|
migrated.push(skillId);
|
|
1256
1445
|
} catch (error) {
|
|
1257
1446
|
failed.push({ id: skillId, error: getErrorMessage(error) });
|