agents-inc 0.170.1 → 0.171.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 +30 -0
- package/dist/{chunk-52HDHJ7I.js → chunk-24OD7IP4.js} +32 -21
- package/dist/chunk-24OD7IP4.js.map +1 -0
- package/dist/{chunk-MQ6CGZNJ.js → chunk-3YYHL76L.js} +1879 -2019
- package/dist/chunk-3YYHL76L.js.map +1 -0
- package/dist/chunk-4RQKCV6I.js +103 -0
- package/dist/chunk-4RQKCV6I.js.map +1 -0
- package/dist/{chunk-USVBYQSQ.js → chunk-5FM77WKW.js} +16 -6
- package/dist/chunk-5FM77WKW.js.map +1 -0
- package/dist/{chunk-HED2DAXZ.js → chunk-7IVLVEHX.js} +5 -5
- package/dist/chunk-7IVLVEHX.js.map +1 -0
- package/dist/{chunk-PJWGTNOX.js → chunk-A6OWEJGC.js} +144 -186
- package/dist/chunk-A6OWEJGC.js.map +1 -0
- package/dist/{chunk-BMRUNMPV.js → chunk-AWWCRL5A.js} +35 -35
- package/dist/chunk-AWWCRL5A.js.map +1 -0
- package/dist/{chunk-F2BHT5C4.js → chunk-EOKNEGRD.js} +129 -151
- package/dist/chunk-EOKNEGRD.js.map +1 -0
- package/dist/{chunk-NQW25DCF.js → chunk-GHHJYNAN.js} +1 -7
- package/dist/chunk-GHHJYNAN.js.map +1 -0
- package/dist/chunk-JGPE4RRE.js +35 -0
- package/dist/chunk-JGPE4RRE.js.map +1 -0
- package/dist/{chunk-JFLVEFFP.js → chunk-KIK5EZYD.js} +1 -1
- package/dist/chunk-KIK5EZYD.js.map +1 -0
- package/dist/{chunk-NCWDK6L7.js → chunk-KMOCMVK5.js} +254 -379
- package/dist/chunk-KMOCMVK5.js.map +1 -0
- package/dist/{chunk-4AAOOAIN.js → chunk-P6CYS4JK.js} +2 -2
- package/dist/chunk-P6CYS4JK.js.map +1 -0
- package/dist/chunk-QIR56IDM.js +1169 -0
- package/dist/chunk-QIR56IDM.js.map +1 -0
- package/dist/{chunk-6ZRH5RHC.js → chunk-R572RLTI.js} +4 -4
- package/dist/chunk-R572RLTI.js.map +1 -0
- package/dist/{chunk-WTWMGH2C.js → chunk-RDXY4GRO.js} +2 -2
- package/dist/chunk-RDXY4GRO.js.map +1 -0
- package/dist/{chunk-7RDMTR64.js → chunk-S2SKVJT2.js} +785 -256
- package/dist/chunk-S2SKVJT2.js.map +1 -0
- package/dist/{chunk-SZYQISA2.js → chunk-TNFYBKVD.js} +43 -29
- package/dist/chunk-TNFYBKVD.js.map +1 -0
- package/dist/{chunk-RIPSGNLU.js → chunk-W4KAY26P.js} +3 -3
- package/dist/chunk-W4KAY26P.js.map +1 -0
- package/dist/{chunk-OYJQUA3D.js → chunk-WDH6HHA3.js} +31 -13
- package/dist/chunk-WDH6HHA3.js.map +1 -0
- package/dist/{chunk-3G7X2WKI.js → chunk-WII6GOPM.js} +18 -38
- package/dist/chunk-WII6GOPM.js.map +1 -0
- package/dist/{chunk-F5EBEATU.js → chunk-WM2N2D6Q.js} +34 -46
- package/dist/chunk-WM2N2D6Q.js.map +1 -0
- package/dist/{chunk-KOLDW6SF.js → chunk-YLUOGAW7.js} +2 -2
- package/dist/chunk-YLUOGAW7.js.map +1 -0
- package/dist/{chunk-44TE3RKH.js → chunk-ZC6GC66J.js} +5 -4
- package/dist/chunk-ZC6GC66J.js.map +1 -0
- package/dist/{chunk-NEZ4OAOL.js → chunk-ZEGM3MVR.js} +3 -5
- package/dist/chunk-ZEGM3MVR.js.map +1 -0
- package/dist/commands/build/marketplace.js +46 -46
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +25 -28
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +87 -178
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +510 -360
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +451 -357
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +144 -125
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +20 -27
- package/dist/commands/list.js +39 -55
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +6 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +35 -32
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +17 -77
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +159 -222
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +9 -32
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/prompt-confirm.js +2 -2
- package/dist/components/common/removal-plan-confirm.js +2 -2
- package/dist/components/common/scroll-affordance.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +4 -4
- package/dist/components/common/spinner.js +2 -4
- package/dist/components/common/summary-panel.js +5 -5
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/config-exports.js +7 -3
- package/dist/config-exports.js.map +1 -1
- package/dist/hooks/init.js +18 -19
- package/dist/hooks/init.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/load-agent-defs-UBWITIEI.js +14 -0
- package/dist/recompile-project-agents-IQANWGOP.js +65 -0
- package/dist/recompile-project-agents-IQANWGOP.js.map +1 -0
- package/dist/{source-loader-C5SQXZXI.js → source-loader-YGG7DY2W.js} +5 -5
- package/dist/src/agents/developer/ai-developer/playbook.md +2 -5
- package/dist/src/agents/developer/api-developer/playbook.md +2 -5
- package/dist/src/agents/developer/cli-developer/playbook.md +2 -5
- package/dist/src/agents/developer/web-developer/playbook.md +2 -5
- package/dist/src/agents/meta/agent-summoner/output.md +2 -2
- package/dist/src/agents/meta/agent-summoner/playbook.md +1 -13
- package/dist/src/agents/meta/codex-keeper/critical-requirements.md +2 -5
- package/dist/src/agents/meta/convention-keeper/critical-requirements.md +2 -4
- package/dist/src/agents/tester/ai-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/ai-tester/playbook.md +2 -0
- package/dist/src/agents/tester/api-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/api-tester/playbook.md +2 -0
- package/dist/src/agents/tester/cli-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/cli-tester/playbook.md +2 -0
- package/dist/src/agents/tester/web-tester/critical-requirements.md +1 -2
- package/dist/src/agents/tester/web-tester/playbook.md +2 -0
- package/package.json +9 -8
- package/src/agents/developer/ai-developer/playbook.md +2 -5
- package/src/agents/developer/api-developer/playbook.md +2 -5
- package/src/agents/developer/cli-developer/playbook.md +2 -5
- package/src/agents/developer/web-developer/playbook.md +2 -5
- package/src/agents/meta/agent-summoner/output.md +2 -2
- package/src/agents/meta/agent-summoner/playbook.md +1 -13
- package/src/agents/meta/codex-keeper/critical-requirements.md +2 -5
- package/src/agents/meta/convention-keeper/critical-requirements.md +2 -4
- package/src/agents/tester/ai-tester/critical-requirements.md +1 -2
- package/src/agents/tester/ai-tester/playbook.md +2 -0
- package/src/agents/tester/api-tester/critical-requirements.md +1 -2
- package/src/agents/tester/api-tester/playbook.md +2 -0
- package/src/agents/tester/cli-tester/critical-requirements.md +1 -2
- package/src/agents/tester/cli-tester/playbook.md +2 -0
- package/src/agents/tester/web-tester/critical-requirements.md +1 -2
- package/src/agents/tester/web-tester/playbook.md +2 -0
- package/src/schemas/project-config.schema.json +0 -3
- package/src/schemas/project-source-config.schema.json +0 -6
- package/dist/chunk-3G7X2WKI.js.map +0 -1
- package/dist/chunk-44TE3RKH.js.map +0 -1
- package/dist/chunk-4AAOOAIN.js.map +0 -1
- package/dist/chunk-52HDHJ7I.js.map +0 -1
- package/dist/chunk-6HNXYYVF.js +0 -373
- package/dist/chunk-6HNXYYVF.js.map +0 -1
- package/dist/chunk-6ZRH5RHC.js.map +0 -1
- package/dist/chunk-7RDMTR64.js.map +0 -1
- package/dist/chunk-BMRUNMPV.js.map +0 -1
- package/dist/chunk-CLPUWOSA.js +0 -46
- package/dist/chunk-CLPUWOSA.js.map +0 -1
- package/dist/chunk-F2BHT5C4.js.map +0 -1
- package/dist/chunk-F5EBEATU.js.map +0 -1
- package/dist/chunk-HED2DAXZ.js.map +0 -1
- package/dist/chunk-JFLVEFFP.js.map +0 -1
- package/dist/chunk-KOLDW6SF.js.map +0 -1
- package/dist/chunk-MQ6CGZNJ.js.map +0 -1
- package/dist/chunk-NCWDK6L7.js.map +0 -1
- package/dist/chunk-NEZ4OAOL.js.map +0 -1
- package/dist/chunk-NIHUOWE4.js +0 -106
- package/dist/chunk-NIHUOWE4.js.map +0 -1
- package/dist/chunk-NQW25DCF.js.map +0 -1
- package/dist/chunk-OYJQUA3D.js.map +0 -1
- package/dist/chunk-PJWGTNOX.js.map +0 -1
- package/dist/chunk-RIPSGNLU.js.map +0 -1
- package/dist/chunk-SZYQISA2.js.map +0 -1
- package/dist/chunk-USVBYQSQ.js.map +0 -1
- package/dist/chunk-V3KTSP3Q.js +0 -940
- package/dist/chunk-V3KTSP3Q.js.map +0 -1
- package/dist/chunk-WTWMGH2C.js.map +0 -1
- package/dist/load-agent-defs-YMDWBFDP.js +0 -14
- package/dist/recompile-project-agents-SZ76WNTW.js +0 -18
- package/dist/source-loader-C5SQXZXI.js.map +0 -1
- /package/dist/{load-agent-defs-YMDWBFDP.js.map → load-agent-defs-UBWITIEI.js.map} +0 -0
- /package/dist/{recompile-project-agents-SZ76WNTW.js.map → source-loader-YGG7DY2W.js.map} +0 -0
package/dist/commands/edit.js
CHANGED
|
@@ -1,78 +1,79 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
awaitUnderSpinner
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-ZEGM3MVR.js";
|
|
5
5
|
import {
|
|
6
6
|
publishSeedConfig,
|
|
7
7
|
seedPayloadForInstallation,
|
|
8
8
|
skillsAuthoredHere
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-TNFYBKVD.js";
|
|
10
10
|
import {
|
|
11
11
|
RemovalPlanConfirm
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-5FM77WKW.js";
|
|
13
13
|
import {
|
|
14
14
|
unofferablePlacementsFound
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-RDXY4GRO.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
joinedStatement,
|
|
20
|
-
notInstalledGlobally,
|
|
21
|
-
openUrl,
|
|
22
|
-
readInstalledGlobal,
|
|
23
|
-
reconcileSharedConfig,
|
|
24
|
-
restoreInstalledGlobal,
|
|
25
|
-
sameAssignments,
|
|
26
|
-
skillLabel,
|
|
27
|
-
withUnplaceableAssignees
|
|
28
|
-
} from "../chunk-6HNXYYVF.js";
|
|
17
|
+
openUrl
|
|
18
|
+
} from "../chunk-JGPE4RRE.js";
|
|
29
19
|
import {
|
|
30
20
|
fetchSeedConfig
|
|
31
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-WDH6HHA3.js";
|
|
32
22
|
import {
|
|
33
23
|
promptConfirm
|
|
34
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-P6CYS4JK.js";
|
|
35
25
|
import "../chunk-OZXAJNLA.js";
|
|
36
26
|
import {
|
|
37
27
|
hostCompileNotices
|
|
38
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-WM2N2D6Q.js";
|
|
39
29
|
import {
|
|
40
30
|
compileAgentsAllScopes,
|
|
41
31
|
compileProjectScope,
|
|
42
32
|
detectProject,
|
|
43
33
|
loadSource,
|
|
44
34
|
movedGlobalAgentInputs,
|
|
35
|
+
projectsAFanOutReaches,
|
|
45
36
|
sayCapturedWarnings,
|
|
46
37
|
writeProjectConfig
|
|
47
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-S2SKVJT2.js";
|
|
48
39
|
import {
|
|
49
40
|
copyLocalSkills,
|
|
50
41
|
discoverInstalledSkills,
|
|
51
42
|
removeCompiledAgents,
|
|
52
43
|
uninstallPluginSkills
|
|
53
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-EOKNEGRD.js";
|
|
54
45
|
import {
|
|
55
46
|
loadAgentDefs
|
|
56
|
-
} from "../chunk-
|
|
57
|
-
import "../chunk-
|
|
58
|
-
import "../chunk-
|
|
47
|
+
} from "../chunk-7IVLVEHX.js";
|
|
48
|
+
import "../chunk-WII6GOPM.js";
|
|
49
|
+
import "../chunk-AWWCRL5A.js";
|
|
59
50
|
import {
|
|
60
51
|
formatScopeTag
|
|
61
|
-
} from "../chunk-
|
|
62
|
-
import "../chunk-
|
|
52
|
+
} from "../chunk-4RQKCV6I.js";
|
|
53
|
+
import "../chunk-KIK5EZYD.js";
|
|
63
54
|
import {
|
|
64
55
|
providerFlag,
|
|
65
56
|
providerNamedBy,
|
|
66
57
|
refuseAnAmbiguousInstallation
|
|
67
|
-
} from "../chunk-
|
|
58
|
+
} from "../chunk-W4KAY26P.js";
|
|
68
59
|
import {
|
|
69
60
|
BaseCommand,
|
|
70
61
|
EXIT_CODES,
|
|
62
|
+
arrivalLines,
|
|
63
|
+
arrivalsByScope,
|
|
71
64
|
carriedSkillsThatDiffer,
|
|
65
|
+
installsAtHome,
|
|
66
|
+
joinedStatement,
|
|
67
|
+
notInstalledGlobally,
|
|
68
|
+
readInstalledGlobal,
|
|
69
|
+
reconcileSharedConfig,
|
|
72
70
|
registerExternalSkills,
|
|
71
|
+
restoreInstalledGlobal,
|
|
72
|
+
sameAssignments,
|
|
73
|
+
skillLabel,
|
|
74
|
+
withUnplaceableAssignees,
|
|
73
75
|
writeExternalSkills
|
|
74
|
-
} from "../chunk-
|
|
75
|
-
import "../chunk-CLPUWOSA.js";
|
|
76
|
+
} from "../chunk-QIR56IDM.js";
|
|
76
77
|
import {
|
|
77
78
|
ERROR_MESSAGES,
|
|
78
79
|
INCOMPLETE_WORK_RECOVERY,
|
|
@@ -85,6 +86,7 @@ import {
|
|
|
85
86
|
authoredHereKept,
|
|
86
87
|
buildMarketplacePluginRef,
|
|
87
88
|
carriedSkillsWritten,
|
|
89
|
+
copyingBesideGlobalPlugins,
|
|
88
90
|
deleteLocalSkill,
|
|
89
91
|
detectMigrations,
|
|
90
92
|
editorSkillMetadataUnusableError,
|
|
@@ -93,28 +95,31 @@ import {
|
|
|
93
95
|
getErrorMessage,
|
|
94
96
|
holdsItsOwnInstallation,
|
|
95
97
|
hostAt,
|
|
98
|
+
installingBesideGlobalCopies,
|
|
96
99
|
isHomeDirectory,
|
|
100
|
+
keepsGlobalInstall,
|
|
97
101
|
keptAsInstalledGlobally,
|
|
98
102
|
keptUnassigned,
|
|
99
103
|
loadProjectConfig,
|
|
100
104
|
localSkillsCopied,
|
|
101
105
|
migrateLocalSkillScope,
|
|
102
106
|
nothingInstalledToApplyTo,
|
|
107
|
+
projectCopyMovedToGlobal,
|
|
103
108
|
projectCopyRemoved,
|
|
104
109
|
providerInUse,
|
|
105
110
|
recompileSummary,
|
|
111
|
+
registeredProjectsRewritten,
|
|
106
112
|
resolveInstallPaths,
|
|
107
113
|
seedToInstallSelection,
|
|
108
114
|
sharedConfigDestinations,
|
|
109
115
|
sharedConfigNeedsTerminal,
|
|
110
|
-
skippedUnknownAgents,
|
|
111
|
-
skippedUnknownSkills,
|
|
112
116
|
unplaceableKept
|
|
113
|
-
} from "../chunk-
|
|
117
|
+
} from "../chunk-3YYHL76L.js";
|
|
114
118
|
import {
|
|
115
119
|
getSkillById,
|
|
116
|
-
getSkillDisplayName
|
|
117
|
-
|
|
120
|
+
getSkillDisplayName,
|
|
121
|
+
stripTerminalControls
|
|
122
|
+
} from "../chunk-24OD7IP4.js";
|
|
118
123
|
import {
|
|
119
124
|
CLI_COLORS,
|
|
120
125
|
CLI_INVOKE_COMMAND,
|
|
@@ -124,61 +129,110 @@ import {
|
|
|
124
129
|
formatSourceDisplayName,
|
|
125
130
|
isActiveAt,
|
|
126
131
|
isGlobalTombstone
|
|
127
|
-
} from "../chunk-
|
|
128
|
-
import "../chunk-
|
|
132
|
+
} from "../chunk-A6OWEJGC.js";
|
|
133
|
+
import "../chunk-GHHJYNAN.js";
|
|
129
134
|
|
|
130
135
|
// src/cli/commands/edit.tsx
|
|
131
136
|
import path from "path";
|
|
132
137
|
import chalk from "chalk";
|
|
133
138
|
import { Flags } from "@oclif/core";
|
|
134
|
-
import { difference, indexBy, partition } from "remeda";
|
|
139
|
+
import { difference, indexBy, partition, unique } from "remeda";
|
|
135
140
|
import { jsx } from "react/jsx-runtime";
|
|
136
141
|
var RECOMPILE_SUBJECT = "agent";
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
var CHANGE_MARKER_COLORS = {
|
|
143
|
+
"+": CLI_COLORS.SUCCESS,
|
|
144
|
+
"-": CLI_COLORS.ERROR,
|
|
145
|
+
"~": CLI_COLORS.WARNING
|
|
146
|
+
};
|
|
147
|
+
var AGENT_DETAIL = " (agent)";
|
|
148
|
+
function changeLine(marker, subject, detail) {
|
|
149
|
+
const head = chalk.hex(CHANGE_MARKER_COLORS[marker])(` ${marker} ${subject}`);
|
|
150
|
+
return detail === void 0 ? head : head + chalk.hex(CLI_COLORS.NEUTRAL)(detail);
|
|
151
|
+
}
|
|
152
|
+
function dualScopeTransitionLine(subject, to, detail) {
|
|
153
|
+
return changeLine(to === "project" ? "+" : "-", `${subject} [P]`, detail);
|
|
142
154
|
}
|
|
143
155
|
function formatSkillScopeChangeLine(skillId, change, dualScopeSkillTransitions) {
|
|
144
156
|
const displayName = getSkillDisplayName(skillId);
|
|
145
157
|
if (dualScopeSkillTransitions.has(skillId)) {
|
|
146
|
-
return
|
|
158
|
+
return dualScopeTransitionLine(displayName, change.to);
|
|
147
159
|
}
|
|
148
160
|
const isGlobalToProject = change.from === "global" && change.to === "project";
|
|
149
|
-
|
|
150
|
-
const color = isGlobalToProject ? CLI_COLORS.SUCCESS : CLI_COLORS.WARNING;
|
|
151
|
-
return chalk.hex(color)(` ${prefix} ${displayName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(scopeArrow(change));
|
|
161
|
+
return changeLine(isGlobalToProject ? "+" : "~", displayName, scopeArrow(change));
|
|
152
162
|
}
|
|
153
163
|
function formatAgentScopeChangeLine(agentName, change, dualScopeAgentTransitions) {
|
|
154
|
-
const agentSuffix = chalk.hex(CLI_COLORS.NEUTRAL)(" (agent)");
|
|
155
164
|
if (dualScopeAgentTransitions.has(agentName)) {
|
|
156
|
-
return
|
|
165
|
+
return dualScopeTransitionLine(agentName, change.to, AGENT_DETAIL);
|
|
157
166
|
}
|
|
158
|
-
return
|
|
167
|
+
return changeLine("~", agentName, scopeArrow(change));
|
|
159
168
|
}
|
|
160
169
|
function scopeArrow(change) {
|
|
161
170
|
return ` (${formatScopeTag(change.from)} \u2192 ${formatScopeTag(change.to)})`;
|
|
162
171
|
}
|
|
163
172
|
function formatValueChangeLine(subject, change, kind) {
|
|
164
|
-
return
|
|
173
|
+
return changeLine("~", subject, ` (${kind}: ${change.from} \u2192 ${change.to})`);
|
|
174
|
+
}
|
|
175
|
+
function sourceChangeLine(skillId, change) {
|
|
176
|
+
const from = formatSourceDisplayName(change.from);
|
|
177
|
+
const to = formatSourceDisplayName(change.to);
|
|
178
|
+
return changeLine("~", getSkillDisplayName(skillId), ` (${from} \u2192 ${to})`);
|
|
179
|
+
}
|
|
180
|
+
function scopeLabelOf(skillId, skills) {
|
|
181
|
+
const skill = skills.find((s) => s.id === skillId);
|
|
182
|
+
return skill === void 0 ? "" : ` ${formatScopeTag(skill.scope)}`;
|
|
183
|
+
}
|
|
184
|
+
function changeSummaryLines(changes, newSkills, oldSkills) {
|
|
185
|
+
const addedSkill = (id) => changeLine(
|
|
186
|
+
"+",
|
|
187
|
+
`${stripTerminalControls(getSkillById(id).displayName)}${scopeLabelOf(id, newSkills)}`
|
|
188
|
+
);
|
|
189
|
+
const removedSkill = (id) => changeLine("-", `${getSkillDisplayName(id)}${scopeLabelOf(id, oldSkills)}`);
|
|
190
|
+
const joinedGlobalDetail = ` ${formatScopeTag("global")} (agent: skills added)`;
|
|
191
|
+
return [
|
|
192
|
+
...changes.addedSkills.map(addedSkill),
|
|
193
|
+
...changes.removedSkills.map(removedSkill),
|
|
194
|
+
...changes.addedAgents.map((name) => changeLine("+", name, AGENT_DETAIL)),
|
|
195
|
+
...changes.removedAgents.map((name) => changeLine("-", name, AGENT_DETAIL)),
|
|
196
|
+
...[...changes.sourceChanges].map(([id, change]) => sourceChangeLine(id, change)),
|
|
197
|
+
...[...changes.scopeChanges].map(
|
|
198
|
+
([id, change]) => formatSkillScopeChangeLine(id, change, changes.dualScopeSkillTransitions)
|
|
199
|
+
),
|
|
200
|
+
...[...changes.agentScopeChanges].map(
|
|
201
|
+
([name, change]) => formatAgentScopeChangeLine(name, change, changes.dualScopeAgentTransitions)
|
|
202
|
+
),
|
|
203
|
+
...[...changes.tuningChanges].map(
|
|
204
|
+
([name, change]) => formatValueChangeLine(name, change, "agent")
|
|
205
|
+
),
|
|
206
|
+
...changes.reassignedAgents.map((name) => changeLine("~", name, " (agent: skills reassigned)")),
|
|
207
|
+
...changes.joinedGlobalAgents.map((name) => changeLine("~", name, joinedGlobalDetail)),
|
|
208
|
+
...changes.rewrittenSkills.map(
|
|
209
|
+
(id) => changeLine("~", getSkillDisplayName(id), " (skill: files rewritten)")
|
|
210
|
+
)
|
|
211
|
+
];
|
|
165
212
|
}
|
|
166
213
|
function resolveEditRoot(installation) {
|
|
167
214
|
const dir = installation.projectDir;
|
|
168
215
|
return { dir, isGlobal: isHomeDirectory(dir) };
|
|
169
216
|
}
|
|
170
|
-
function sharedConfigPlan(changes,
|
|
217
|
+
function sharedConfigPlan(changes, overwrittenSkillIds2, statements) {
|
|
171
218
|
const dropped = droppedProjectHalves(changes);
|
|
219
|
+
const moved = movedToGlobal(changes);
|
|
172
220
|
const skillLines = [
|
|
173
221
|
...changes.removedSkills.map(skillLabel),
|
|
174
|
-
...dropped.skillIds.map(
|
|
222
|
+
...dropped.skillIds.map((id) => projectCopyRemoved(skillLabel(id))),
|
|
223
|
+
...moved.skillIds.map((id) => projectCopyMovedToGlobal(skillLabel(id)))
|
|
224
|
+
];
|
|
225
|
+
const agentLines = [
|
|
226
|
+
...changes.removedAgents,
|
|
227
|
+
...dropped.agentNames.map(projectCopyRemoved),
|
|
228
|
+
...moved.agentNames.map(projectCopyMovedToGlobal)
|
|
175
229
|
];
|
|
176
|
-
const agentLines = [...changes.removedAgents, ...dropped.agentNames.map(projectCopyRemoved)];
|
|
177
230
|
const sections = removalSections(skillLines, agentLines);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
231
|
+
const overwritten = {
|
|
232
|
+
label: SHARED_CONFIG_APPLY.OVERWRITTEN_HEADING,
|
|
233
|
+
items: overwrittenSkillIds2.map(skillLabel)
|
|
234
|
+
};
|
|
235
|
+
return { ...planHeading(sections, overwritten), sections, overwritten, statements };
|
|
182
236
|
}
|
|
183
237
|
function removalSections(skills, agents) {
|
|
184
238
|
return [
|
|
@@ -195,17 +249,54 @@ function droppedProjectHalves(changes) {
|
|
|
195
249
|
agentNames: droppedAgents.map(([name]) => name)
|
|
196
250
|
};
|
|
197
251
|
}
|
|
198
|
-
function
|
|
199
|
-
|
|
200
|
-
|
|
252
|
+
function movedToGlobal(changes) {
|
|
253
|
+
const skillMoves = [...scopeMovesOf(changes)].filter(([, change]) => change.to === "global");
|
|
254
|
+
const agentMoves = [...changes.agentScopeChanges].filter(
|
|
255
|
+
([name, change]) => change.to === "global" && !changes.dualScopeAgentTransitions.has(name)
|
|
256
|
+
);
|
|
257
|
+
return {
|
|
258
|
+
skillIds: skillMoves.map(([id]) => id),
|
|
259
|
+
agentNames: agentMoves.map(([name]) => name)
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function planHeading(sections, overwritten) {
|
|
263
|
+
if (sections.length > 0) return { heading: SHARED_CONFIG_APPLY.PREVIEW_HEADING };
|
|
264
|
+
if (overwritten.items.length > 0) return {};
|
|
265
|
+
return { heading: SHARED_CONFIG_APPLY.NOTHING_REMOVED };
|
|
266
|
+
}
|
|
267
|
+
function overwrittenSkillIds(changes, active) {
|
|
268
|
+
const leaving = new Set(movedToGlobal(changes).skillIds);
|
|
269
|
+
const switched = ejectedCopiesSwitchedToPlugins(migrationPlanOf(changes, active));
|
|
270
|
+
return unique([...changes.rewrittenSkills, ...switched]).filter((id) => !leaving.has(id));
|
|
271
|
+
}
|
|
272
|
+
function ejectedCopiesSwitchedToPlugins(plan) {
|
|
273
|
+
return plan.toPlugin.filter((migration) => !keepsGlobalInstall(migration)).map(({ id }) => id);
|
|
274
|
+
}
|
|
275
|
+
function migrationPlanOf(changes, active) {
|
|
276
|
+
return detectMigrations(
|
|
277
|
+
withMaskedGlobalsRestored(active.oldSkills, changes.collapsedPairs),
|
|
278
|
+
active.selection.skills
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
async function carriedThatChange(carried) {
|
|
282
|
+
const changing = new Set(await carriedSkillsThatDiffer(carried));
|
|
283
|
+
return carried.filter((skill) => changing.has(skill.id));
|
|
284
|
+
}
|
|
285
|
+
function withRewrittenCarried(planned, carriedToWrite) {
|
|
286
|
+
const writtenIds = carriedToWrite.map((skill) => skill.id);
|
|
287
|
+
return { ...planned, rewrittenSkills: difference(writtenIds, skillsNewHere(planned)) };
|
|
201
288
|
}
|
|
202
289
|
function compilesGlobalScope(editRoot, written) {
|
|
203
290
|
return editRoot.isGlobal || movedGlobalAgentInputs(written);
|
|
204
291
|
}
|
|
205
292
|
function withReassignments(changes, result, installedStack, editRoot) {
|
|
206
293
|
const { assignedStack } = result;
|
|
294
|
+
const arrivingCopies = arrivingProjectHalves(
|
|
295
|
+
changes.agentScopeChanges,
|
|
296
|
+
changes.dualScopeAgentTransitions
|
|
297
|
+
);
|
|
207
298
|
const ownedHere = (agent) => editRoot.isGlobal || isActiveAt(agent, "project");
|
|
208
|
-
const countedAsAdded = (agent) => changes.addedAgents.includes(agent.name);
|
|
299
|
+
const countedAsAdded = (agent) => changes.addedAgents.includes(agent.name) || arrivingCopies.has(agent.name);
|
|
209
300
|
const rowsMoved = (agent) => !sameAssignments(assignedStack[agent.name], installedStack?.[agent.name]);
|
|
210
301
|
const reassigned = result.agentConfigs.filter(
|
|
211
302
|
(agent) => ownedHere(agent) && !countedAsAdded(agent) && rowsMoved(agent)
|
|
@@ -249,15 +340,50 @@ function unassignedStatement(unassigned) {
|
|
|
249
340
|
unassigned.map(({ skillId, agentName, category }) => keptUnassigned(skillId, agentName, category)).join("\n")
|
|
250
341
|
];
|
|
251
342
|
}
|
|
252
|
-
function
|
|
343
|
+
function keptOnApply(reconciled, held, revisedCarried, idAppliedAtHome) {
|
|
344
|
+
return [
|
|
345
|
+
...keptStatements(reconciled.kept),
|
|
346
|
+
...unassignedStatement(reconciled.unassigned),
|
|
347
|
+
...joinedStatement(held),
|
|
348
|
+
...keptAsInstalledStatement(held, revisedCarried, idAppliedAtHome)
|
|
349
|
+
];
|
|
350
|
+
}
|
|
351
|
+
function keptAsInstalledStatement(held, revisedCarried, idAppliedAtHome) {
|
|
253
352
|
const skillIds = [...held.keptAsInstalled.skillIds, ...revisedCarried];
|
|
254
353
|
const { agentNames } = held.keptAsInstalled;
|
|
255
354
|
if (skillIds.length === 0 && agentNames.length === 0) return [];
|
|
256
|
-
return [keptAsInstalledGlobally(skillIds, agentNames)];
|
|
355
|
+
return [keptAsInstalledGlobally(skillIds, agentNames, idAppliedAtHome)];
|
|
257
356
|
}
|
|
258
357
|
function applyAuthority(editRoot) {
|
|
259
358
|
return editRoot.isGlobal ? "all" : "owned";
|
|
260
359
|
}
|
|
360
|
+
function activeEntriesOf(result, projectConfig) {
|
|
361
|
+
const oldSkills = (projectConfig?.skills ?? []).filter((s) => !s.excluded);
|
|
362
|
+
const oldAgents = (projectConfig?.agents ?? []).filter((a) => !a.excluded);
|
|
363
|
+
return {
|
|
364
|
+
selection: {
|
|
365
|
+
...result,
|
|
366
|
+
skills: result.skills.filter((s) => !s.excluded),
|
|
367
|
+
agentConfigs: result.agentConfigs.filter((a) => !a.excluded)
|
|
368
|
+
},
|
|
369
|
+
oldConfig: projectConfig ? { ...projectConfig, skills: oldSkills, agents: oldAgents } : null,
|
|
370
|
+
oldSkills,
|
|
371
|
+
oldAgents
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function planChanges(selection, active, projectConfig, editRoot) {
|
|
375
|
+
const keptInstalled = globalHalvesKeptInstalled(selection.installedGlobal);
|
|
376
|
+
const changes = detectConfigChanges(active.oldConfig, active.selection, {
|
|
377
|
+
newSkills: [...selection.result.skills, ...keptInstalled.skills],
|
|
378
|
+
oldSkills: projectConfig?.skills ?? [],
|
|
379
|
+
newAgents: [...selection.result.agentConfigs, ...keptInstalled.agents],
|
|
380
|
+
oldAgents: projectConfig?.agents ?? []
|
|
381
|
+
});
|
|
382
|
+
return {
|
|
383
|
+
...withReassignments(changes, active.selection, projectConfig?.stack, editRoot),
|
|
384
|
+
joinedGlobalAgents: selection.joinedGlobalAgents
|
|
385
|
+
};
|
|
386
|
+
}
|
|
261
387
|
var Edit = class _Edit extends BaseCommand {
|
|
262
388
|
static summary = "Open this installation in the editor, or apply a configuration with --from";
|
|
263
389
|
static description = "Open this installation in agentsinc.sh/editor, or apply a configuration built there with --from";
|
|
@@ -294,17 +420,23 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
294
420
|
async applyEdit() {
|
|
295
421
|
const { flags } = await this.parse(_Edit);
|
|
296
422
|
const cwd = process.cwd();
|
|
297
|
-
|
|
423
|
+
const namedProvider = providerNamedBy(flags.provider);
|
|
424
|
+
if (flags.ui && flags.from !== void 0) {
|
|
425
|
+
return this.openSharedInEditor(flags.from, cwd, namedProvider);
|
|
426
|
+
}
|
|
298
427
|
await refuseAnAmbiguousInstallation(
|
|
299
428
|
cwd,
|
|
300
429
|
"edit",
|
|
301
|
-
|
|
430
|
+
namedProvider,
|
|
302
431
|
(message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS })
|
|
303
432
|
);
|
|
304
433
|
await this.ensureConfigReadable(cwd);
|
|
305
434
|
await this.refuseUnofferablePlacements(cwd);
|
|
306
435
|
if (flags.from === void 0) return this.openInEditor(cwd);
|
|
307
|
-
|
|
436
|
+
return this.applySharedConfig(flags.from, namedProvider);
|
|
437
|
+
}
|
|
438
|
+
async applySharedConfig(id, namedProvider) {
|
|
439
|
+
const payload = await this.fetchSharedConfigOrFail(id, namedProvider);
|
|
308
440
|
const context = await this.loadContextUnderSpinner();
|
|
309
441
|
const editRoot = resolveEditRoot(context.installation);
|
|
310
442
|
await this.ensureSavedSkillsReadable(
|
|
@@ -312,87 +444,46 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
312
444
|
context.sourceResult.matrix,
|
|
313
445
|
editRoot.dir
|
|
314
446
|
);
|
|
315
|
-
const selection = await this.selectionFromSharedConfig(payload, context, editRoot);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const
|
|
319
|
-
const
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
oldSkills: context.projectConfig?.skills ?? [],
|
|
333
|
-
newAgents: result.agentConfigs,
|
|
334
|
-
oldAgents: context.projectConfig?.agents ?? []
|
|
335
|
-
}),
|
|
336
|
-
filteredResult,
|
|
337
|
-
context.projectConfig?.stack,
|
|
338
|
-
editRoot
|
|
339
|
-
),
|
|
340
|
-
joinedGlobalAgents: selection.joinedGlobalAgents
|
|
341
|
-
};
|
|
342
|
-
const rewritten = await this.confirmAndWriteCarried(selection, planned, filteredResult);
|
|
343
|
-
const changes = {
|
|
344
|
-
...planned,
|
|
345
|
-
rewrittenSkills: difference(rewritten, planned.addedSkills)
|
|
346
|
-
};
|
|
347
|
-
const authority = applyAuthority(editRoot);
|
|
348
|
-
if (!hasAnyChanges(changes)) {
|
|
349
|
-
this.log(chalk.hex(CLI_COLORS.NEUTRAL)("No changes made."));
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
this.logChangeSummary(changes, filteredResult.skills, filteredOldConfig?.skills ?? []);
|
|
353
|
-
const migratedSkillIds = await this.applyMigrations(
|
|
354
|
-
changes,
|
|
355
|
-
filteredResult,
|
|
356
|
-
activeOldSkills,
|
|
357
|
-
context,
|
|
358
|
-
editRoot
|
|
359
|
-
);
|
|
360
|
-
await this.applyScopeChanges(changes, filteredResult, context, editRoot);
|
|
447
|
+
const selection = await this.selectionFromSharedConfig(id, payload, context, editRoot);
|
|
448
|
+
this.reportValidationErrors(selection.result.validation);
|
|
449
|
+
const active = activeEntriesOf(selection.result, context.projectConfig);
|
|
450
|
+
const planned = planChanges(selection, active, context.projectConfig, editRoot);
|
|
451
|
+
const carriedToWrite = await carriedThatChange(selection.carried);
|
|
452
|
+
const changes = withRewrittenCarried(planned, carriedToWrite);
|
|
453
|
+
if (!hasAnyChanges(changes)) return this.sayNothingChanged(selection.kept);
|
|
454
|
+
const plan = await this.planToConfirm(changes, active, selection.kept, context, editRoot);
|
|
455
|
+
await this.confirmSharedConfigOrCancel(plan, applyArrivals(changes, active.selection));
|
|
456
|
+
await this.writeCarriedSkills(carriedToWrite);
|
|
457
|
+
await this.applyApprovedChanges(changes, active, selection.result, context, editRoot);
|
|
458
|
+
}
|
|
459
|
+
async applyApprovedChanges(changes, active, result, context, editRoot) {
|
|
460
|
+
const { selection: activeSelection, oldSkills, oldAgents } = active;
|
|
461
|
+
this.logChangeSummary(changes, activeSelection.skills, oldSkills);
|
|
462
|
+
await this.applyMigrations(changes, active, context, editRoot);
|
|
463
|
+
await this.applyScopeChanges(changes, activeSelection, context, editRoot);
|
|
361
464
|
await this.applyCollapsedPairs(changes, context, editRoot);
|
|
362
|
-
await this.
|
|
363
|
-
await this.
|
|
364
|
-
await this.
|
|
365
|
-
await this.
|
|
366
|
-
await this.
|
|
367
|
-
await this.cleanupStaleAgentFiles(changes, activeOldAgents, editRoot);
|
|
465
|
+
await this.applyPluginChanges(changes, activeSelection, oldSkills, context, editRoot);
|
|
466
|
+
await this.copyNewLocalSkills(changes, activeSelection, context, editRoot);
|
|
467
|
+
await this.removeDeletedLocalSkills(changes, oldSkills, editRoot);
|
|
468
|
+
await this.writeConfigAndCompile(result, context, editRoot);
|
|
469
|
+
await this.cleanupStaleAgentFiles(changes, oldAgents, editRoot);
|
|
368
470
|
await this.reportWhatThisHostCannotCarry(editRoot);
|
|
369
|
-
this.logCompletionSummary(
|
|
471
|
+
this.logCompletionSummary();
|
|
370
472
|
}
|
|
371
473
|
/**
|
|
372
474
|
* A shared configuration applies destructively, except for a skill written here (`forkedFrom`)
|
|
373
475
|
* and an id this catalogue cannot place — both disclosed in the confirm. From a project the
|
|
374
|
-
* global install is only added to
|
|
375
|
-
* states otherwise are held as installed, and only what it lacks arrives.
|
|
476
|
+
* global install is only added to.
|
|
376
477
|
*/
|
|
377
|
-
async selectionFromSharedConfig(payload, context, editRoot) {
|
|
478
|
+
async selectionFromSharedConfig(id, payload, context, editRoot) {
|
|
378
479
|
const { matrix: sourceMatrix } = context.sourceResult;
|
|
379
480
|
const carried = this.registerExternalSkillsOrFail(payload, sourceMatrix, editRoot.dir);
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
sourceMatrix
|
|
383
|
-
);
|
|
481
|
+
const mapping = this.decodeSeedOrFail(payload, sourceMatrix);
|
|
482
|
+
const { result } = mapping;
|
|
384
483
|
this.refuseProjectScopedContentAtHome(result, editRoot.dir);
|
|
385
|
-
const
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
installed: context.projectConfig,
|
|
389
|
-
authoredHere: await this.readAuthoredHere(context.projectConfig, editRoot.dir),
|
|
390
|
-
unplaceable
|
|
391
|
-
});
|
|
392
|
-
const held = restoreInstalledGlobal(
|
|
393
|
-
reconciled.result,
|
|
394
|
-
editRoot.isGlobal ? null : await readInstalledGlobal(editRoot.dir)
|
|
395
|
-
);
|
|
484
|
+
const reconciled = await this.reconcileWithInstallation(mapping, payload, context, editRoot);
|
|
485
|
+
const installedGlobal = editRoot.isGlobal ? null : await readInstalledGlobal(editRoot.dir);
|
|
486
|
+
const held = restoreInstalledGlobal(reconciled.result, installedGlobal);
|
|
396
487
|
const arrivingCarried = notInstalledGlobally(carried, held);
|
|
397
488
|
await this.refuseSharedConfigBeforeAsking(
|
|
398
489
|
held.result,
|
|
@@ -400,23 +491,30 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
400
491
|
editRoot.dir,
|
|
401
492
|
context.sourceResult
|
|
402
493
|
);
|
|
403
|
-
const
|
|
404
|
-
const revisedGlobally = await carriedSkillsThatDiffer(heldGlobally);
|
|
494
|
+
const revisedGlobally = await carriedSkillsThatDiffer(difference(carried, arrivingCarried));
|
|
405
495
|
sayCapturedWarnings(context.startupMessages);
|
|
406
|
-
|
|
407
|
-
if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));
|
|
496
|
+
this.warnOfSkippedEntries(mapping, held.result.selectedAgents);
|
|
408
497
|
return {
|
|
409
498
|
result: held.result,
|
|
410
|
-
kept:
|
|
411
|
-
...keptStatements(reconciled.kept),
|
|
412
|
-
...unassignedStatement(reconciled.unassigned),
|
|
413
|
-
...joinedStatement(held),
|
|
414
|
-
...keptAsInstalledStatement(held, revisedGlobally)
|
|
415
|
-
],
|
|
499
|
+
kept: keptOnApply(reconciled, held, revisedGlobally, installsAtHome(result) ? id : void 0),
|
|
416
500
|
carried: arrivingCarried,
|
|
417
|
-
joinedGlobalAgents: held.joined.map(({ agentName }) => agentName)
|
|
501
|
+
joinedGlobalAgents: held.joined.map(({ agentName }) => agentName),
|
|
502
|
+
installedGlobal
|
|
418
503
|
};
|
|
419
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Ids the decode could not place stay, as does a sub-agent only they carried in: a catalogue
|
|
507
|
+
* limit is not an instruction to delete.
|
|
508
|
+
*/
|
|
509
|
+
async reconcileWithInstallation({ result, skippedSkillIds }, payload, { projectConfig }, editRoot) {
|
|
510
|
+
const unplaceable = new Set(skippedSkillIds);
|
|
511
|
+
return reconcileSharedConfig({
|
|
512
|
+
decoded: withUnplaceableAssignees(result, projectConfig, payload, unplaceable),
|
|
513
|
+
installed: projectConfig,
|
|
514
|
+
authoredHere: await this.readAuthoredHere(projectConfig, editRoot.dir),
|
|
515
|
+
unplaceable
|
|
516
|
+
});
|
|
517
|
+
}
|
|
420
518
|
/** Best-effort: an unreadable directory protects nothing and must not fail an apply. */
|
|
421
519
|
async readAuthoredHere(projectConfig, editRoot) {
|
|
422
520
|
if (!projectConfig) return /* @__PURE__ */ new Set();
|
|
@@ -427,13 +525,16 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
427
525
|
return /* @__PURE__ */ new Set();
|
|
428
526
|
}
|
|
429
527
|
}
|
|
430
|
-
/**
|
|
431
|
-
|
|
528
|
+
/**
|
|
529
|
+
* Refuses an empty directory, or a missing terminal, before spending a round trip: a destructive
|
|
530
|
+
* apply nobody can confirm must never become a yes.
|
|
531
|
+
*/
|
|
532
|
+
async fetchSharedConfigOrFail(id, namedProvider) {
|
|
432
533
|
if (!await detectProject()) {
|
|
433
|
-
this.error(nothingInstalledToApplyTo(id), { exit: EXIT_CODES.ERROR });
|
|
534
|
+
this.error(nothingInstalledToApplyTo(id, namedProvider), { exit: EXIT_CODES.ERROR });
|
|
434
535
|
}
|
|
435
536
|
if (!process.stdin.isTTY) {
|
|
436
|
-
this.error(sharedConfigNeedsTerminal(id), { exit: EXIT_CODES.ERROR });
|
|
537
|
+
this.error(sharedConfigNeedsTerminal(id, namedProvider), { exit: EXIT_CODES.ERROR });
|
|
437
538
|
}
|
|
438
539
|
this.log(`Fetching configuration ${id}...`);
|
|
439
540
|
const fetched = await fetchSeedConfig(id);
|
|
@@ -456,31 +557,50 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
456
557
|
this.handleError(error);
|
|
457
558
|
}
|
|
458
559
|
}
|
|
459
|
-
async confirmAndWriteCarried(selection, planned, result) {
|
|
460
|
-
await this.confirmSharedConfigOrCancel(planned, selection.kept, applyArrivals(planned, result));
|
|
461
|
-
return this.writeCarriedSkills(selection.carried);
|
|
462
|
-
}
|
|
463
560
|
async writeCarriedSkills(carried) {
|
|
464
|
-
if (carried.length === 0) return
|
|
465
|
-
|
|
561
|
+
if (carried.length === 0) return;
|
|
562
|
+
await writeExternalSkills(carried);
|
|
466
563
|
this.log(carriedSkillsWritten(carried.map((skill) => skill.id)));
|
|
467
|
-
|
|
564
|
+
}
|
|
565
|
+
/** What the run removes and overwrites, then what it keeps and what else it rewrites. */
|
|
566
|
+
async planToConfirm(changes, active, kept, context, editRoot) {
|
|
567
|
+
const reachedProjects = await this.registeredProjectsStatement(changes, context, editRoot);
|
|
568
|
+
return sharedConfigPlan(changes, overwrittenSkillIds(changes, active), [
|
|
569
|
+
...kept,
|
|
570
|
+
...reachedProjects
|
|
571
|
+
]);
|
|
572
|
+
}
|
|
573
|
+
/** Nothing to confirm; what the run keeps still says why nothing changed. */
|
|
574
|
+
sayNothingChanged(kept) {
|
|
575
|
+
for (const statement of kept) {
|
|
576
|
+
this.log(statement);
|
|
577
|
+
}
|
|
578
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(INFO_MESSAGES.NO_CHANGES_MADE));
|
|
468
579
|
}
|
|
469
580
|
/**
|
|
470
|
-
*
|
|
471
|
-
*
|
|
581
|
+
* At home every registered project inlines the global config, so a change to it rewrites each
|
|
582
|
+
* one the fan-out reaches. Rewritten carried files alone leave the config as it was.
|
|
472
583
|
*/
|
|
473
|
-
async
|
|
474
|
-
|
|
584
|
+
async registeredProjectsStatement(changes, context, editRoot) {
|
|
585
|
+
if (!editRoot.isGlobal || !changesTheConfig(changes)) return [];
|
|
586
|
+
const reached = await projectsAFanOutReaches(
|
|
587
|
+
context.projectConfig?.projects ?? [],
|
|
588
|
+
providerInUse(editRoot.dir)
|
|
589
|
+
);
|
|
590
|
+
return reached.length === 0 ? [] : [registeredProjectsRewritten(reached)];
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* The plan and the apply read the same changes, so what is approved is what is removed. The
|
|
594
|
+
* arrivals print above it, so the question covers the whole of what a yes does.
|
|
595
|
+
*/
|
|
596
|
+
async confirmSharedConfigOrCancel(plan, arrivals) {
|
|
475
597
|
for (const line of arrivalLines(arrivals)) {
|
|
476
598
|
this.log(line);
|
|
477
599
|
}
|
|
478
600
|
const outcome = await promptConfirm(({ onConfirm, onCancel }) => /* @__PURE__ */ jsx(
|
|
479
601
|
RemovalPlanConfirm,
|
|
480
602
|
{
|
|
481
|
-
|
|
482
|
-
sections: plan.sections,
|
|
483
|
-
statements: plan.statements,
|
|
603
|
+
...plan,
|
|
484
604
|
message: SHARED_CONFIG_APPLY.CONFIRM,
|
|
485
605
|
onConfirm,
|
|
486
606
|
onCancel
|
|
@@ -527,10 +647,10 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
527
647
|
);
|
|
528
648
|
}
|
|
529
649
|
/** Opens an id rather than applying it; `--from` without `--ui` is the destructive apply. */
|
|
530
|
-
async openSharedInEditor(id, cwd) {
|
|
650
|
+
async openSharedInEditor(id, cwd, namedProvider) {
|
|
531
651
|
const url = editorConfigUrl(id);
|
|
532
652
|
this.log(`Open it at ${url}`);
|
|
533
|
-
this.log(applySharedConfigHere(id, await holdsItsOwnInstallation(cwd)));
|
|
653
|
+
this.log(applySharedConfigHere(id, await holdsItsOwnInstallation(cwd), namedProvider));
|
|
534
654
|
if (!process.stdin.isTTY) return;
|
|
535
655
|
const opened = await openUrl(url);
|
|
536
656
|
if (!opened.ok) this.warn(opened.error);
|
|
@@ -567,94 +687,18 @@ var Edit = class _Edit extends BaseCommand {
|
|
|
567
687
|
}
|
|
568
688
|
}
|
|
569
689
|
logChangeSummary(changes, newSkills, oldSkills) {
|
|
570
|
-
const {
|
|
571
|
-
addedSkills,
|
|
572
|
-
removedSkills,
|
|
573
|
-
addedAgents,
|
|
574
|
-
removedAgents,
|
|
575
|
-
sourceChanges,
|
|
576
|
-
scopeChanges,
|
|
577
|
-
agentScopeChanges,
|
|
578
|
-
dualScopeSkillTransitions,
|
|
579
|
-
dualScopeAgentTransitions,
|
|
580
|
-
tuningChanges,
|
|
581
|
-
reassignedAgents,
|
|
582
|
-
joinedGlobalAgents,
|
|
583
|
-
rewrittenSkills
|
|
584
|
-
} = changes;
|
|
585
690
|
this.log(`
|
|
586
691
|
${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
587
|
-
for (const
|
|
588
|
-
|
|
589
|
-
const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : "";
|
|
590
|
-
this.log(
|
|
591
|
-
chalk.hex(CLI_COLORS.SUCCESS)(` + ${getSkillById(skillId).displayName}${scopeLabel}`)
|
|
592
|
-
);
|
|
593
|
-
}
|
|
594
|
-
for (const skillId of removedSkills) {
|
|
595
|
-
const scope = oldSkills.find((s) => s.id === skillId)?.scope;
|
|
596
|
-
const scopeLabel = scope ? ` ${formatScopeTag(scope)}` : "";
|
|
597
|
-
this.log(chalk.hex(CLI_COLORS.ERROR)(` - ${getSkillDisplayName(skillId)}${scopeLabel}`));
|
|
598
|
-
}
|
|
599
|
-
for (const agentName of addedAgents) {
|
|
600
|
-
this.log(
|
|
601
|
-
chalk.hex(CLI_COLORS.SUCCESS)(` + ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (agent)")
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
for (const agentName of removedAgents) {
|
|
605
|
-
this.log(
|
|
606
|
-
chalk.hex(CLI_COLORS.ERROR)(` - ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (agent)")
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
for (const [skillId, change] of sourceChanges) {
|
|
610
|
-
const displayName = getSkillDisplayName(skillId);
|
|
611
|
-
const fromLabel = formatSourceDisplayName(change.from);
|
|
612
|
-
const toLabel = formatSourceDisplayName(change.to);
|
|
613
|
-
this.log(
|
|
614
|
-
chalk.hex(CLI_COLORS.WARNING)(` ~ ${displayName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(` (${fromLabel} \u2192 ${toLabel})`)
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
for (const [skillId, change] of scopeChanges) {
|
|
618
|
-
this.log(formatSkillScopeChangeLine(skillId, change, dualScopeSkillTransitions));
|
|
619
|
-
}
|
|
620
|
-
for (const [agentName, change] of agentScopeChanges) {
|
|
621
|
-
this.log(formatAgentScopeChangeLine(agentName, change, dualScopeAgentTransitions));
|
|
622
|
-
}
|
|
623
|
-
for (const [agentName, change] of tuningChanges) {
|
|
624
|
-
this.log(formatValueChangeLine(agentName, change, "agent"));
|
|
625
|
-
}
|
|
626
|
-
for (const agentName of reassignedAgents) {
|
|
627
|
-
this.log(
|
|
628
|
-
chalk.hex(CLI_COLORS.WARNING)(` ~ ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (agent: skills reassigned)")
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
for (const agentName of joinedGlobalAgents) {
|
|
632
|
-
this.log(
|
|
633
|
-
chalk.hex(CLI_COLORS.WARNING)(` ~ ${agentName}`) + chalk.hex(CLI_COLORS.NEUTRAL)(` ${formatScopeTag("global")} (agent: skills added)`)
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
for (const skillId of rewrittenSkills) {
|
|
637
|
-
this.log(
|
|
638
|
-
chalk.hex(CLI_COLORS.WARNING)(` ~ ${getSkillDisplayName(skillId)}`) + chalk.hex(CLI_COLORS.NEUTRAL)(" (skill: files rewritten)")
|
|
639
|
-
);
|
|
692
|
+
for (const line of changeSummaryLines(changes, newSkills, oldSkills)) {
|
|
693
|
+
this.log(line);
|
|
640
694
|
}
|
|
641
695
|
this.log("");
|
|
642
696
|
}
|
|
643
|
-
async applyMigrations(changes,
|
|
644
|
-
const migrationPlan =
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
);
|
|
648
|
-
const migratedSkillIds = /* @__PURE__ */ new Set([
|
|
649
|
-
...migrationPlan.toEject.map((m) => m.id),
|
|
650
|
-
...migrationPlan.toPlugin.map((m) => m.id)
|
|
651
|
-
]);
|
|
652
|
-
if (migratedSkillIds.size === 0) return migratedSkillIds;
|
|
653
|
-
if (migrationPlan.toEject.length > 0) {
|
|
654
|
-
this.logModeSwitch(migrationPlan.toEject.length, INSTALL_MODE_DESCRIPTIONS.eject);
|
|
655
|
-
}
|
|
697
|
+
async applyMigrations(changes, active, context, editRoot) {
|
|
698
|
+
const migrationPlan = migrationPlanOf(changes, active);
|
|
699
|
+
if (migrationPlan.toEject.length === 0 && migrationPlan.toPlugin.length === 0) return;
|
|
700
|
+
this.announceMigrations(migrationPlan);
|
|
656
701
|
if (migrationPlan.toPlugin.length > 0) {
|
|
657
|
-
this.logModeSwitch(migrationPlan.toPlugin.length, INSTALL_MODE_DESCRIPTIONS.plugin);
|
|
658
702
|
await this.requireMarketplaceOrExit(
|
|
659
703
|
context.sourceResult,
|
|
660
704
|
"migrate skills to plugin mode",
|
|
@@ -676,7 +720,6 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
676
720
|
if (migrationPlan.toPlugin.length > 0) {
|
|
677
721
|
this.reportPluginInstalls(migrationResult.pluginInstalls);
|
|
678
722
|
}
|
|
679
|
-
return migratedSkillIds;
|
|
680
723
|
}
|
|
681
724
|
/**
|
|
682
725
|
* Mirrors `BaseCommand.reportPluginInstalls` for the plugin→eject half. The count line names no
|
|
@@ -691,26 +734,46 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
691
734
|
}
|
|
692
735
|
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(localSkillsCopied(result.copied.length)));
|
|
693
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* One line per kind, each counting its own: a mode switch, then a skill added in the project
|
|
739
|
+
* beside the global install it keeps (`keepsGlobalInstall` decides both the keep and the line).
|
|
740
|
+
*/
|
|
741
|
+
announceMigrations(plan) {
|
|
742
|
+
const [copiesBesideGlobalPlugin, switchesToEject] = partition(plan.toEject, keepsGlobalInstall);
|
|
743
|
+
const [installsBesideGlobalCopy, switchesToPlugin] = partition(
|
|
744
|
+
plan.toPlugin,
|
|
745
|
+
keepsGlobalInstall
|
|
746
|
+
);
|
|
747
|
+
if (switchesToEject.length > 0) {
|
|
748
|
+
this.logModeSwitch(switchesToEject.length, INSTALL_MODE_DESCRIPTIONS.eject);
|
|
749
|
+
}
|
|
750
|
+
if (copiesBesideGlobalPlugin.length > 0) {
|
|
751
|
+
this.logCopiesBesideGlobalPlugins(copiesBesideGlobalPlugin.length);
|
|
752
|
+
}
|
|
753
|
+
if (switchesToPlugin.length > 0) {
|
|
754
|
+
this.logModeSwitch(switchesToPlugin.length, INSTALL_MODE_DESCRIPTIONS.plugin);
|
|
755
|
+
}
|
|
756
|
+
if (installsBesideGlobalCopy.length > 0) {
|
|
757
|
+
this.logInstallsBesideGlobalCopies(installsBesideGlobalCopy.length);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
694
760
|
logModeSwitch(count, modeDescription) {
|
|
695
761
|
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Switching ${count} skill(s) to ${modeDescription}`));
|
|
696
762
|
}
|
|
763
|
+
logCopiesBesideGlobalPlugins(count) {
|
|
764
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(copyingBesideGlobalPlugins(count)));
|
|
765
|
+
}
|
|
766
|
+
logInstallsBesideGlobalCopies(count) {
|
|
767
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(installingBesideGlobalCopies(count)));
|
|
768
|
+
}
|
|
697
769
|
/**
|
|
698
770
|
* A collapsed `[P][G]` pair is not a move: its project half is dropped
|
|
699
771
|
* ({@link applyCollapsedPairs}).
|
|
700
772
|
*/
|
|
701
773
|
async applyScopeChanges(changes, filteredResult, context, editRoot) {
|
|
702
774
|
const scopeChanges = scopeMovesOf(changes);
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
if (skillConfig?.origin === EJECT_SOURCE) {
|
|
706
|
-
await migrateLocalSkillScope(skillId, change.from, editRoot.dir);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
const hasPluginScopeChanges = [...scopeChanges.keys()].some((skillId) => {
|
|
710
|
-
const skillConfig = filteredResult.skills.find((s) => s.id === skillId);
|
|
711
|
-
return skillConfig && skillConfig.origin !== EJECT_SOURCE;
|
|
712
|
-
});
|
|
713
|
-
if (!hasPluginScopeChanges) return;
|
|
775
|
+
await moveEjectedSkillCopies(scopeChanges, filteredResult.skills, editRoot.dir);
|
|
776
|
+
if (!movesAPluginSkill(scopeChanges, filteredResult.skills)) return;
|
|
714
777
|
const marketplace = await this.requireMarketplaceOrExit(
|
|
715
778
|
context.sourceResult,
|
|
716
779
|
"migrate plugin skill scopes",
|
|
@@ -755,33 +818,27 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
755
818
|
}
|
|
756
819
|
return;
|
|
757
820
|
}
|
|
758
|
-
|
|
821
|
+
await this.uninstallPluginSkillsReported(
|
|
759
822
|
pluginHalves.map((half) => half.id),
|
|
760
823
|
pluginHalves,
|
|
761
824
|
marketplace,
|
|
762
825
|
editRoot.dir
|
|
763
826
|
);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
827
|
+
}
|
|
828
|
+
async uninstallPluginSkillsReported(skillIds, oldSkills, marketplace, projectDir) {
|
|
829
|
+
const { uninstalled, failed } = await uninstallPluginSkills(
|
|
830
|
+
skillIds,
|
|
831
|
+
oldSkills,
|
|
832
|
+
marketplace,
|
|
833
|
+
projectDir
|
|
834
|
+
);
|
|
835
|
+
if (uninstalled.length > 0) {
|
|
836
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(`Removed ${uninstalled.length} plugin(s)`));
|
|
768
837
|
}
|
|
769
|
-
for (const item of
|
|
838
|
+
for (const item of failed) {
|
|
770
839
|
this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);
|
|
771
840
|
}
|
|
772
841
|
}
|
|
773
|
-
async applySourceChanges(changes, activeOldSkills, editRoot, migratedSkillIds) {
|
|
774
|
-
const { sourceChanges } = changes;
|
|
775
|
-
for (const [skillId, change] of sourceChanges) {
|
|
776
|
-
if (migratedSkillIds.has(skillId)) {
|
|
777
|
-
continue;
|
|
778
|
-
}
|
|
779
|
-
if (change.from === EJECT_SOURCE) {
|
|
780
|
-
const oldSkill = activeOldSkills.find((s) => s.id === skillId);
|
|
781
|
-
await deleteLocalSkill(editRoot.dir, skillId, oldSkill?.scope);
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
842
|
async applyPluginChanges(changes, filteredResult, activeOldSkills, context, editRoot) {
|
|
786
843
|
const { addedSkills, removedSkills } = changes;
|
|
787
844
|
const addedPluginSkills = filteredResult.skills.filter(
|
|
@@ -805,20 +862,12 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
805
862
|
);
|
|
806
863
|
}
|
|
807
864
|
if (removedPluginSkills.length > 0) {
|
|
808
|
-
|
|
865
|
+
await this.uninstallPluginSkillsReported(
|
|
809
866
|
removedPluginSkills,
|
|
810
867
|
activeOldSkills,
|
|
811
868
|
marketplace,
|
|
812
869
|
editRoot.dir
|
|
813
870
|
);
|
|
814
|
-
if (uninstallResult.uninstalled.length > 0) {
|
|
815
|
-
this.log(
|
|
816
|
-
chalk.hex(CLI_COLORS.NEUTRAL)(`Removed ${uninstallResult.uninstalled.length} plugin(s)`)
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
for (const item of uninstallResult.failed) {
|
|
820
|
-
this.warn(`Failed to uninstall plugin ${item.id}: ${item.error}`);
|
|
821
|
-
}
|
|
822
871
|
}
|
|
823
872
|
}
|
|
824
873
|
async copyNewLocalSkills(changes, filteredResult, context, editRoot) {
|
|
@@ -843,57 +892,48 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
843
892
|
await deleteLocalSkill(editRoot.dir, skillId, oldSkill.scope);
|
|
844
893
|
}
|
|
845
894
|
}
|
|
846
|
-
async writeConfigAndCompile(result, context, editRoot
|
|
847
|
-
|
|
895
|
+
async writeConfigAndCompile(result, context, editRoot) {
|
|
896
|
+
const agentDefs = await this.loadAgentDefsOrFail();
|
|
897
|
+
const configResult = await this.writeConfigOrFail(result, context, editRoot, agentDefs);
|
|
898
|
+
this.reportUnassignedSkills(configResult.config, result.skills);
|
|
899
|
+
await this.recompileAgents(result, editRoot, configResult.propagation, agentDefs.sourcePath);
|
|
900
|
+
this.reportFanOut(configResult.propagation);
|
|
901
|
+
}
|
|
902
|
+
async loadAgentDefsOrFail() {
|
|
848
903
|
try {
|
|
849
|
-
|
|
904
|
+
return await loadAgentDefs();
|
|
850
905
|
} catch (error) {
|
|
851
906
|
this.handleError(error);
|
|
852
907
|
}
|
|
853
|
-
|
|
908
|
+
}
|
|
909
|
+
/** Fatal: every mutation has landed and config.ts is their only record. */
|
|
910
|
+
async writeConfigOrFail(result, context, editRoot, agentDefs) {
|
|
854
911
|
try {
|
|
855
|
-
|
|
912
|
+
return await writeProjectConfig({
|
|
856
913
|
selection: result,
|
|
857
914
|
sourceResult: context.sourceResult,
|
|
858
915
|
projectDir: editRoot.dir,
|
|
859
|
-
agentDefs
|
|
860
|
-
authoritativeScope:
|
|
916
|
+
agentDefs,
|
|
917
|
+
authoritativeScope: applyAuthority(editRoot)
|
|
861
918
|
});
|
|
862
919
|
} catch (error) {
|
|
863
920
|
this.error(`Could not update config: ${getErrorMessage(error)}`, {
|
|
864
921
|
exit: EXIT_CODES.ERROR
|
|
865
922
|
});
|
|
866
923
|
}
|
|
867
|
-
|
|
924
|
+
}
|
|
925
|
+
async recompileAgents(result, editRoot, propagation, sourcePath) {
|
|
868
926
|
try {
|
|
869
927
|
const agentScopeMap = activeAgentScopeMap(result.agentConfigs);
|
|
870
928
|
const { allSkills } = await discoverInstalledSkills(editRoot.dir);
|
|
871
|
-
const compile = compilesGlobalScope(editRoot,
|
|
872
|
-
const
|
|
929
|
+
const compile = compilesGlobalScope(editRoot, propagation) ? compileAgentsAllScopes : compileProjectScope;
|
|
930
|
+
const compilation = await compile({
|
|
873
931
|
projectDir: editRoot.dir,
|
|
874
|
-
sourcePath
|
|
932
|
+
sourcePath,
|
|
875
933
|
skills: allSkills,
|
|
876
934
|
agentScopeMap
|
|
877
935
|
});
|
|
878
|
-
|
|
879
|
-
const summary = recompileSummary(
|
|
880
|
-
rewritten.length,
|
|
881
|
-
compiled.length - rewritten.length,
|
|
882
|
-
RECOMPILE_SUBJECT
|
|
883
|
-
);
|
|
884
|
-
if (failed.length > 0) {
|
|
885
|
-
this.log(
|
|
886
|
-
chalk.hex(CLI_COLORS.NEUTRAL)(summary) + chalk.hex(CLI_COLORS.WARNING)(` (${failed.length} failed)`)
|
|
887
|
-
);
|
|
888
|
-
for (const warning of warnings) {
|
|
889
|
-
this.warn(warning);
|
|
890
|
-
}
|
|
891
|
-
this.recordIncompleteWork(agentsNotCompiled(failed), INCOMPLETE_WORK_RECOVERY.RECOMPILE);
|
|
892
|
-
} else if (compiled.length > 0) {
|
|
893
|
-
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(summary));
|
|
894
|
-
} else {
|
|
895
|
-
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE));
|
|
896
|
-
}
|
|
936
|
+
this.reportRecompile(compilation);
|
|
897
937
|
} catch (error) {
|
|
898
938
|
this.reportIncompleteWork(
|
|
899
939
|
`Agent recompilation failed: ${getErrorMessage(error)}`,
|
|
@@ -901,7 +941,26 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
901
941
|
);
|
|
902
942
|
this.log(`You can manually recompile with '${CLI_INVOKE_COMMAND} compile'.`);
|
|
903
943
|
}
|
|
904
|
-
|
|
944
|
+
}
|
|
945
|
+
reportRecompile({ compiled, rewritten, failed, warnings }) {
|
|
946
|
+
const summary = recompileSummary(
|
|
947
|
+
rewritten.length,
|
|
948
|
+
compiled.length - rewritten.length,
|
|
949
|
+
RECOMPILE_SUBJECT
|
|
950
|
+
);
|
|
951
|
+
if (failed.length > 0) {
|
|
952
|
+
this.log(
|
|
953
|
+
chalk.hex(CLI_COLORS.NEUTRAL)(summary) + chalk.hex(CLI_COLORS.WARNING)(` (${failed.length} failed)`)
|
|
954
|
+
);
|
|
955
|
+
for (const warning of warnings) {
|
|
956
|
+
this.warn(warning);
|
|
957
|
+
}
|
|
958
|
+
this.recordIncompleteWork(agentsNotCompiled(failed), INCOMPLETE_WORK_RECOVERY.RECOMPILE);
|
|
959
|
+
} else if (compiled.length > 0) {
|
|
960
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(summary));
|
|
961
|
+
} else {
|
|
962
|
+
this.log(chalk.hex(CLI_COLORS.NEUTRAL)(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE));
|
|
963
|
+
}
|
|
905
964
|
}
|
|
906
965
|
async cleanupStaleAgentFiles(changes, oldAgents, editRoot) {
|
|
907
966
|
for (const removal of planStaleAgentRemovals(changes, oldAgents, editRoot.dir)) {
|
|
@@ -926,7 +985,7 @@ ${chalk.hex(CLI_COLORS.WHITE).bold("Changes:")}`);
|
|
|
926
985
|
this.log(notice);
|
|
927
986
|
}
|
|
928
987
|
}
|
|
929
|
-
logCompletionSummary(
|
|
988
|
+
logCompletionSummary() {
|
|
930
989
|
if (this.hasIncompleteWork) return;
|
|
931
990
|
this.log(`
|
|
932
991
|
${chalk.hex(CLI_COLORS.SUCCESS)("\u2713 Done")}
|
|
@@ -954,44 +1013,63 @@ function detectConfigChanges(oldConfig, selection, fullEntries) {
|
|
|
954
1013
|
);
|
|
955
1014
|
const dualScopeSkillTransitions = detectDualScopeTransitions(
|
|
956
1015
|
scopeChanges,
|
|
957
|
-
fullEntries
|
|
958
|
-
fullEntries
|
|
1016
|
+
fullEntries.newSkills,
|
|
1017
|
+
fullEntries.oldSkills,
|
|
959
1018
|
(s) => s.id
|
|
960
1019
|
);
|
|
961
1020
|
const collapsedPairs = collapsedPairsOf(
|
|
962
1021
|
scopeChanges,
|
|
963
1022
|
dualScopeSkillTransitions,
|
|
964
|
-
fullEntries
|
|
1023
|
+
fullEntries.oldSkills
|
|
1024
|
+
);
|
|
1025
|
+
const dualScopeAgentTransitions = detectDualScopeTransitions(
|
|
1026
|
+
agentScopeChanges,
|
|
1027
|
+
fullEntries.newAgents,
|
|
1028
|
+
fullEntries.oldAgents,
|
|
1029
|
+
(a) => a.name
|
|
965
1030
|
);
|
|
1031
|
+
const arrivingSkills = arrivingProjectHalves(scopeChanges, dualScopeSkillTransitions);
|
|
966
1032
|
return {
|
|
967
1033
|
addedSkills: difference(newSkillIds, oldSkillIds),
|
|
968
1034
|
removedSkills: difference(oldSkillIds, newSkillIds),
|
|
969
1035
|
addedAgents: difference(newAgentNames, oldAgentNames),
|
|
970
1036
|
removedAgents: difference(oldAgentNames, newAgentNames),
|
|
971
|
-
sourceChanges:
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1037
|
+
sourceChanges: withoutKeys(
|
|
1038
|
+
detectPropertyChanges(
|
|
1039
|
+
selection.skills,
|
|
1040
|
+
indexBy(withMaskedGlobalsRestored(oldConfig?.skills ?? [], collapsedPairs), (s) => s.id),
|
|
1041
|
+
(s) => s.id,
|
|
1042
|
+
(s) => s.origin
|
|
1043
|
+
),
|
|
1044
|
+
arrivingSkills
|
|
976
1045
|
),
|
|
977
1046
|
scopeChanges,
|
|
978
1047
|
agentScopeChanges,
|
|
979
1048
|
dualScopeSkillTransitions,
|
|
980
1049
|
collapsedPairs,
|
|
981
|
-
dualScopeAgentTransitions
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
),
|
|
987
|
-
tuningChanges: detectPropertyChanges(
|
|
988
|
-
selection.agentConfigs,
|
|
989
|
-
oldAgentsByName,
|
|
990
|
-
(a) => a.name,
|
|
991
|
-
describeTuning
|
|
1050
|
+
dualScopeAgentTransitions,
|
|
1051
|
+
// Either half of a pair is measured against the other install, which this edit never retunes.
|
|
1052
|
+
tuningChanges: withoutKeys(
|
|
1053
|
+
detectPropertyChanges(selection.agentConfigs, oldAgentsByName, (a) => a.name, describeTuning),
|
|
1054
|
+
dualScopeAgentTransitions
|
|
992
1055
|
)
|
|
993
1056
|
};
|
|
994
1057
|
}
|
|
1058
|
+
function skillsNewHere(changes) {
|
|
1059
|
+
return [
|
|
1060
|
+
...changes.addedSkills,
|
|
1061
|
+
...arrivingProjectHalves(changes.scopeChanges, changes.dualScopeSkillTransitions)
|
|
1062
|
+
];
|
|
1063
|
+
}
|
|
1064
|
+
function arrivingProjectHalves(scopeChanges, dualScopeTransitions) {
|
|
1065
|
+
const arriving = [...scopeChanges].filter(
|
|
1066
|
+
([key, change]) => change.to === "project" && dualScopeTransitions.has(key)
|
|
1067
|
+
);
|
|
1068
|
+
return new Set(arriving.map(([key]) => key));
|
|
1069
|
+
}
|
|
1070
|
+
function withoutKeys(changes, keys) {
|
|
1071
|
+
return new Map([...changes].filter(([key]) => !keys.has(key)));
|
|
1072
|
+
}
|
|
995
1073
|
var RESTING_TUNING = "defaults";
|
|
996
1074
|
function describeTuning(agent) {
|
|
997
1075
|
const settings = [
|
|
@@ -1012,17 +1090,20 @@ function detectPropertyChanges(newItems, oldByKey, getKey, getValue) {
|
|
|
1012
1090
|
}
|
|
1013
1091
|
return changes;
|
|
1014
1092
|
}
|
|
1093
|
+
function globalHalvesKeptInstalled(installedGlobal) {
|
|
1094
|
+
if (installedGlobal === null) return { skills: [], agents: [] };
|
|
1095
|
+
return {
|
|
1096
|
+
skills: installedGlobal.skills.map(asTombstone),
|
|
1097
|
+
agents: installedGlobal.agents.map(asTombstone)
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function asTombstone(entry) {
|
|
1101
|
+
return { ...entry, excluded: true };
|
|
1102
|
+
}
|
|
1015
1103
|
function detectDualScopeTransitions(scopeChanges, fullNew, fullOld, getKey) {
|
|
1016
|
-
const hasGlobalTombstone = (items, key) => items.some((item) => getKey(item) === key && item
|
|
1017
|
-
const
|
|
1018
|
-
|
|
1019
|
-
if (change.from === "global" && change.to === "project" && hasGlobalTombstone(fullNew, key)) {
|
|
1020
|
-
result.add(key);
|
|
1021
|
-
} else if (change.from === "project" && change.to === "global" && hasGlobalTombstone(fullOld, key)) {
|
|
1022
|
-
result.add(key);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
return result;
|
|
1104
|
+
const hasGlobalTombstone = (items, key) => items.some((item) => getKey(item) === key && isGlobalTombstone(item));
|
|
1105
|
+
const isDualScope = ([key, { from, to }]) => from === "global" && to === "project" && hasGlobalTombstone(fullNew, key) || from === "project" && to === "global" && hasGlobalTombstone(fullOld, key);
|
|
1106
|
+
return new Set([...scopeChanges].filter(isDualScope).map(([key]) => key));
|
|
1026
1107
|
}
|
|
1027
1108
|
function collapsedPairsOf(scopeChanges, dualScopeSkillTransitions, fullOldSkills) {
|
|
1028
1109
|
return [...scopeChanges].filter(([id, change]) => change.to === "global" && dualScopeSkillTransitions.has(id)).map(([id]) => ({
|
|
@@ -1056,6 +1137,20 @@ function scopeMovesOf(changes) {
|
|
|
1056
1137
|
const collapsed = new Set(changes.collapsedPairs.map(({ projectHalf }) => projectHalf.id));
|
|
1057
1138
|
return new Map([...changes.scopeChanges].filter(([id]) => !collapsed.has(id)));
|
|
1058
1139
|
}
|
|
1140
|
+
async function moveEjectedSkillCopies(scopeMoves, skills, projectDir) {
|
|
1141
|
+
for (const [skillId, change] of scopeMoves) {
|
|
1142
|
+
const skillConfig = skills.find((s) => s.id === skillId);
|
|
1143
|
+
if (skillConfig?.origin === EJECT_SOURCE) {
|
|
1144
|
+
await migrateLocalSkillScope(skillId, change.from, projectDir);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
function movesAPluginSkill(scopeMoves, skills) {
|
|
1149
|
+
return [...scopeMoves.keys()].some((skillId) => {
|
|
1150
|
+
const skill = skills.find((s) => s.id === skillId);
|
|
1151
|
+
return skill !== void 0 && skill.origin !== EJECT_SOURCE;
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1059
1154
|
var STALE_AGENT_SCOPES = ["project", "global"];
|
|
1060
1155
|
var UNRECORDED_AGENT_SCOPE = "project";
|
|
1061
1156
|
function installedScope(name, oldAgents) {
|
|
@@ -1075,11 +1170,13 @@ function planStaleAgentRemovals(changes, oldAgents, editRoot) {
|
|
|
1075
1170
|
return STALE_AGENT_SCOPES.map(removalAtScope).filter((removal) => removal.agents.length > 0);
|
|
1076
1171
|
}
|
|
1077
1172
|
function hasAnyChanges(changes) {
|
|
1078
|
-
return changes.
|
|
1173
|
+
return changes.rewrittenSkills.length > 0 || changesTheConfig(changes);
|
|
1174
|
+
}
|
|
1175
|
+
function changesTheConfig(changes) {
|
|
1176
|
+
return changes.reassignedAgents.length > 0 || changes.joinedGlobalAgents.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;
|
|
1079
1177
|
}
|
|
1080
1178
|
async function migratePluginSkillScopes(scopeChanges, skills, marketplace, projectDir) {
|
|
1081
1179
|
const host = hostAt(projectDir);
|
|
1082
|
-
const migrated = [];
|
|
1083
1180
|
const failed = [];
|
|
1084
1181
|
for (const [skillId, change] of scopeChanges) {
|
|
1085
1182
|
const skillConfig = skills.find((s) => s.id === skillId);
|
|
@@ -1092,16 +1189,13 @@ async function migratePluginSkillScopes(scopeChanges, skills, marketplace, proje
|
|
|
1092
1189
|
await host.uninstallPlugin(pluginRef, "project", projectDir);
|
|
1093
1190
|
}
|
|
1094
1191
|
await host.installPlugin(pluginRef, change.to, projectDir);
|
|
1095
|
-
migrated.push(skillId);
|
|
1096
1192
|
} catch (error) {
|
|
1097
1193
|
failed.push({ id: skillId, error: getErrorMessage(error) });
|
|
1098
1194
|
}
|
|
1099
1195
|
}
|
|
1100
|
-
return {
|
|
1196
|
+
return { failed };
|
|
1101
1197
|
}
|
|
1102
1198
|
export {
|
|
1103
|
-
Edit as default
|
|
1104
|
-
detectConfigChanges,
|
|
1105
|
-
migratePluginSkillScopes
|
|
1199
|
+
Edit as default
|
|
1106
1200
|
};
|
|
1107
1201
|
//# sourceMappingURL=edit.js.map
|