agents-inc 0.170.0 → 0.170.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/{chunk-BMRUNMPV.js → chunk-2YA4DDRM.js} +35 -35
- package/dist/chunk-2YA4DDRM.js.map +1 -0
- package/dist/{chunk-44TE3RKH.js → chunk-3ED3KHHD.js} +5 -4
- package/dist/chunk-3ED3KHHD.js.map +1 -0
- package/dist/{chunk-3G7X2WKI.js → chunk-5BNX73OU.js} +18 -38
- package/dist/chunk-5BNX73OU.js.map +1 -0
- package/dist/{chunk-7RDMTR64.js → chunk-66AEVERM.js} +785 -256
- package/dist/chunk-66AEVERM.js.map +1 -0
- package/dist/{chunk-PJWGTNOX.js → chunk-7C3PFRBU.js} +144 -186
- package/dist/chunk-7C3PFRBU.js.map +1 -0
- package/dist/{chunk-52HDHJ7I.js → chunk-AUNRHWH4.js} +32 -21
- package/dist/chunk-AUNRHWH4.js.map +1 -0
- package/dist/{chunk-KOLDW6SF.js → chunk-BBDGYJHX.js} +2 -2
- package/dist/chunk-BBDGYJHX.js.map +1 -0
- package/dist/{chunk-SZYQISA2.js → chunk-ELV5WDS3.js} +43 -29
- package/dist/chunk-ELV5WDS3.js.map +1 -0
- package/dist/{chunk-MQ6CGZNJ.js → chunk-GAKVZNTX.js} +1879 -2019
- package/dist/chunk-GAKVZNTX.js.map +1 -0
- package/dist/chunk-GEMW5RQ2.js +1169 -0
- package/dist/chunk-GEMW5RQ2.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-WTWMGH2C.js → chunk-HACRR422.js} +2 -2
- package/dist/chunk-HACRR422.js.map +1 -0
- package/dist/{chunk-F2BHT5C4.js → chunk-IWY5IR4F.js} +129 -151
- package/dist/chunk-IWY5IR4F.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-USVBYQSQ.js → chunk-O4LN3HFI.js} +16 -6
- package/dist/chunk-O4LN3HFI.js.map +1 -0
- package/dist/{chunk-RIPSGNLU.js → chunk-OCAVW6N5.js} +3 -3
- package/dist/chunk-OCAVW6N5.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-PLFANHRZ.js +35 -0
- package/dist/chunk-PLFANHRZ.js.map +1 -0
- package/dist/{chunk-6ZRH5RHC.js → chunk-PMUZR4XO.js} +4 -4
- package/dist/chunk-PMUZR4XO.js.map +1 -0
- package/dist/{chunk-F5EBEATU.js → chunk-PSUTNOQ2.js} +34 -46
- package/dist/chunk-PSUTNOQ2.js.map +1 -0
- package/dist/chunk-RIK45Q4I.js +103 -0
- package/dist/chunk-RIK45Q4I.js.map +1 -0
- package/dist/{chunk-HED2DAXZ.js → chunk-THO7LO5B.js} +5 -5
- package/dist/chunk-THO7LO5B.js.map +1 -0
- package/dist/{chunk-OYJQUA3D.js → chunk-YGDWHDOY.js} +31 -13
- package/dist/chunk-YGDWHDOY.js.map +1 -0
- package/dist/{chunk-NCWDK6L7.js → chunk-YXKTY5WM.js} +254 -379
- package/dist/chunk-YXKTY5WM.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-6QUUMGHK.js +14 -0
- package/dist/recompile-project-agents-I33KQJFB.js +65 -0
- package/dist/recompile-project-agents-I33KQJFB.js.map +1 -0
- package/dist/{source-loader-C5SQXZXI.js → source-loader-TTJVW2ER.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-6QUUMGHK.js.map} +0 -0
- /package/dist/{recompile-project-agents-SZ76WNTW.js.map → source-loader-TTJVW2ER.js.map} +0 -0
package/dist/commands/eject.js
CHANGED
|
@@ -5,21 +5,20 @@ import {
|
|
|
5
5
|
loadSource,
|
|
6
6
|
mutateGlobal,
|
|
7
7
|
writeProjectPartial
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-66AEVERM.js";
|
|
9
|
+
import "../chunk-IWY5IR4F.js";
|
|
10
|
+
import "../chunk-THO7LO5B.js";
|
|
11
|
+
import "../chunk-5BNX73OU.js";
|
|
12
|
+
import "../chunk-2YA4DDRM.js";
|
|
13
13
|
import {
|
|
14
14
|
providerFlag,
|
|
15
15
|
providerNamedBy,
|
|
16
16
|
refuseAnAmbiguousInstallation
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-OCAVW6N5.js";
|
|
18
18
|
import {
|
|
19
19
|
BaseCommand,
|
|
20
20
|
EXIT_CODES
|
|
21
|
-
} from "../chunk-
|
|
22
|
-
import "../chunk-CLPUWOSA.js";
|
|
21
|
+
} from "../chunk-GEMW5RQ2.js";
|
|
23
22
|
import {
|
|
24
23
|
INCOMPLETE_WORK_RECOVERY,
|
|
25
24
|
INFO_MESSAGES,
|
|
@@ -31,23 +30,24 @@ import {
|
|
|
31
30
|
getErrorMessage,
|
|
32
31
|
getProjectConfigPath,
|
|
33
32
|
isHomeDirectory,
|
|
33
|
+
isSymlink,
|
|
34
34
|
listDirectories,
|
|
35
|
-
loadProjectSourceConfig,
|
|
36
|
-
plural,
|
|
37
35
|
providerInUse,
|
|
38
36
|
relativeConfigPath,
|
|
39
37
|
resolveInstallPaths,
|
|
40
38
|
resolveSource,
|
|
41
39
|
sourceFolderInUse
|
|
42
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-GAKVZNTX.js";
|
|
43
41
|
import {
|
|
44
|
-
matrix
|
|
45
|
-
|
|
42
|
+
matrix,
|
|
43
|
+
plural
|
|
44
|
+
} from "../chunk-AUNRHWH4.js";
|
|
46
45
|
import {
|
|
47
46
|
DIRS,
|
|
48
|
-
PROJECT_ROOT
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
PROJECT_ROOT,
|
|
48
|
+
bytewise
|
|
49
|
+
} from "../chunk-7C3PFRBU.js";
|
|
50
|
+
import "../chunk-GHHJYNAN.js";
|
|
51
51
|
|
|
52
52
|
// src/cli/commands/eject.ts
|
|
53
53
|
import { Args, Flags } from "@oclif/core";
|
|
@@ -98,10 +98,7 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
98
98
|
}),
|
|
99
99
|
output: Flags.string({
|
|
100
100
|
char: "o",
|
|
101
|
-
// No
|
|
102
|
-
// destination and this flag replaces all three at once. The reference page carries
|
|
103
|
-
// the table; a one-line description that picked one of the three would be wrong
|
|
104
|
-
// about the other two, which is what it was.
|
|
101
|
+
// No default: each eject type has its own destination and this replaces all three.
|
|
105
102
|
description: "Write everything into this directory instead of each eject type's own destination"
|
|
106
103
|
})
|
|
107
104
|
};
|
|
@@ -126,13 +123,7 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
126
123
|
await this.ensureConfig(projectDir, sourceResult);
|
|
127
124
|
this.reportEnding();
|
|
128
125
|
}
|
|
129
|
-
/**
|
|
130
|
-
* The command's last word.
|
|
131
|
-
*
|
|
132
|
-
* `Eject complete!` claims the whole eject landed, so it is withheld whenever part of it did
|
|
133
|
-
* not — the account {@link BaseCommand.exitIfWorkIncomplete} prints replaces that tick rather
|
|
134
|
-
* than sitting under it, and carries the non-zero exit with it.
|
|
135
|
-
*/
|
|
126
|
+
/** Withholds `Eject complete!` when part of the eject did not land. */
|
|
136
127
|
reportEnding() {
|
|
137
128
|
this.log("");
|
|
138
129
|
if (!this.hasIncompleteWork) this.logSuccess("Eject complete!");
|
|
@@ -153,17 +144,23 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
153
144
|
return typeArg;
|
|
154
145
|
}
|
|
155
146
|
async resolveOutputBase(flags, projectDir) {
|
|
156
|
-
if (flags.output)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
147
|
+
if (!flags.output) return sourceFolderInUse(projectDir, providerInUse(projectDir)).dir;
|
|
148
|
+
const outputBase = path.resolve(projectDir, expandHome(flags.output));
|
|
149
|
+
await this.refuseUnwritableOutput(outputBase);
|
|
150
|
+
return outputBase;
|
|
151
|
+
}
|
|
152
|
+
async refuseUnwritableOutput(outputBase) {
|
|
153
|
+
if (await isSymlink(outputBase)) {
|
|
154
|
+
this.error(`Output path is a link: ${outputBase}. Name the folder it points to instead.`, {
|
|
155
|
+
exit: EXIT_CODES.INVALID_ARGS
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const namesAFile = await fileExists(outputBase) && !await directoryExists(outputBase);
|
|
159
|
+
if (namesAFile) {
|
|
160
|
+
this.error(`Output path exists as a file: ${outputBase}`, {
|
|
161
|
+
exit: EXIT_CODES.INVALID_ARGS
|
|
162
|
+
});
|
|
165
163
|
}
|
|
166
|
-
return sourceFolderInUse(projectDir, providerInUse(projectDir)).dir;
|
|
167
164
|
}
|
|
168
165
|
printHeader(brandingName, outputBase) {
|
|
169
166
|
this.log("");
|
|
@@ -193,16 +190,24 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
193
190
|
if (!sourceResult) {
|
|
194
191
|
throw new Error("The marketplace must be loaded for skills eject");
|
|
195
192
|
}
|
|
196
|
-
await this.handleSkills(
|
|
193
|
+
await this.handleSkills(
|
|
194
|
+
skillsDestination(projectDir, directOutput, outputBase),
|
|
195
|
+
flags.force,
|
|
196
|
+
sourceResult
|
|
197
|
+
);
|
|
197
198
|
break;
|
|
198
|
-
case "all":
|
|
199
|
+
case "all": {
|
|
199
200
|
if (!sourceResult) {
|
|
200
201
|
throw new Error("The marketplace must be loaded for full eject");
|
|
201
202
|
}
|
|
202
203
|
await this.handleAgentPartials(outputBase, flags.force, directOutput, false);
|
|
203
|
-
await this.
|
|
204
|
-
|
|
204
|
+
await this.handleSkills(
|
|
205
|
+
skillsDestination(projectDir, directOutput, outputBase),
|
|
206
|
+
flags.force,
|
|
207
|
+
sourceResult
|
|
208
|
+
);
|
|
205
209
|
break;
|
|
210
|
+
}
|
|
206
211
|
default: {
|
|
207
212
|
const _exhaustive = ejectType;
|
|
208
213
|
return _exhaustive;
|
|
@@ -210,17 +215,8 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
217
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* It can refuse, and by the time it does the ejection has already landed — the templates,
|
|
217
|
-
* partials or skills are on disk and stay there. So the throw is caught rather than left to
|
|
218
|
-
* become the process's exit code: an `ERROR` tells the caller nothing landed and the run can
|
|
219
|
-
* be repeated, which is the wrong instruction for a tree that now holds an ejection. What is
|
|
220
|
-
* owed is the account and `EXIT_CODES.COMPLETED_WITH_FAILURES`.
|
|
221
|
-
*
|
|
222
|
-
* The refusal itself is right and is not weakened here: `ensureMinimalConfig` will not invent
|
|
223
|
-
* a config recording a marketplace it read out of a file it could not evaluate.
|
|
218
|
+
* Writes a minimal config so `compile` works afterwards. A refusal is reported as incomplete
|
|
219
|
+
* work rather than thrown, because the ejection has already landed.
|
|
224
220
|
*/
|
|
225
221
|
async ensureConfig(projectDir, sourceResult) {
|
|
226
222
|
const configTsRel = relativeConfigPath(projectDir, providerInUse(projectDir));
|
|
@@ -250,6 +246,9 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
250
246
|
this.warn(result.skipReason);
|
|
251
247
|
return;
|
|
252
248
|
}
|
|
249
|
+
if (result.skippedSubAgents.length > 0) {
|
|
250
|
+
this.warn(subAgentsAlreadyThere(result.destDir, result.skippedSubAgents));
|
|
251
|
+
}
|
|
253
252
|
if (result.templatesSkipped) {
|
|
254
253
|
this.warn(
|
|
255
254
|
"Agent templates already exist \u2014 skipping templates, only ejecting agent partials."
|
|
@@ -262,19 +261,36 @@ var Eject = class _Eject extends BaseCommand {
|
|
|
262
261
|
templatesOnly ? "You can now customize agent templates locally." : INFO_MESSAGES.AGENT_PARTIALS_CUSTOMIZABLE
|
|
263
262
|
);
|
|
264
263
|
}
|
|
265
|
-
async handleSkills(
|
|
266
|
-
const
|
|
267
|
-
const result = await ejectSkills({ destDir, force, sourceResult, matrix });
|
|
264
|
+
async handleSkills(destinationDir, force, sourceResult) {
|
|
265
|
+
const result = await ejectSkills({ destinationDir, force, sourceResult, matrix });
|
|
268
266
|
if (result.skipped) {
|
|
269
267
|
this.warn(result.skipReason);
|
|
270
268
|
return;
|
|
271
269
|
}
|
|
270
|
+
if (result.skippedSkillCount > 0) {
|
|
271
|
+
this.warn(skillsAlreadyThere(destinationDir, result.skippedSkillCount));
|
|
272
|
+
}
|
|
272
273
|
this.logSuccess(
|
|
273
|
-
`${plural(result.copiedSkills.length, "skill")} ejected to ${
|
|
274
|
+
`${plural(result.copiedSkills.length, "skill")} ejected to ${destinationDir} from ${result.sourceLabel}`
|
|
274
275
|
);
|
|
275
276
|
this.log("You can now customize skill content locally.");
|
|
276
277
|
}
|
|
277
278
|
};
|
|
279
|
+
function expandHome(outputPath) {
|
|
280
|
+
return outputPath.startsWith("~") ? path.join(os.homedir(), outputPath.slice(1)) : outputPath;
|
|
281
|
+
}
|
|
282
|
+
function subAgentsAlreadyThere(destDir, subAgents) {
|
|
283
|
+
return `Agent partials already exist at ${destDir} \u2014 skipped ${plural(subAgents.length, "sub-agent")}: ${subAgents.join(", ")}. Use --force to overwrite them.`;
|
|
284
|
+
}
|
|
285
|
+
function skillsAlreadyThere(destinationDir, skippedCount) {
|
|
286
|
+
return `Skills already exist at ${destinationDir} \u2014 skipped ${plural(skippedCount, "skill")}. Use --force to overwrite them.`;
|
|
287
|
+
}
|
|
288
|
+
async function alreadyIn(dir, names) {
|
|
289
|
+
const checked = await Promise.all(
|
|
290
|
+
names.map(async (name) => ({ name, there: await fileExists(path.join(dir, name)) }))
|
|
291
|
+
);
|
|
292
|
+
return checked.filter(({ there }) => there).map(({ name }) => name);
|
|
293
|
+
}
|
|
278
294
|
function resolveEjectDestDir(outputBase, directOutput, templatesOnly) {
|
|
279
295
|
if (directOutput) return outputBase;
|
|
280
296
|
const agentsDir = path.join(outputBase, path.basename(DIRS.agents));
|
|
@@ -282,75 +298,95 @@ function resolveEjectDestDir(outputBase, directOutput, templatesOnly) {
|
|
|
282
298
|
}
|
|
283
299
|
async function ejectAgentPartials(options) {
|
|
284
300
|
const { outputBase, force, directOutput = false, templatesOnly = false } = options;
|
|
285
|
-
const
|
|
301
|
+
const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);
|
|
302
|
+
return templatesOnly ? ejectTemplates(destDir, force) : ejectSubAgentPartials(destDir, force);
|
|
303
|
+
}
|
|
304
|
+
async function ejectTemplates(destDir, force) {
|
|
305
|
+
const sourceDir = path.join(PROJECT_ROOT, DIRS.templates);
|
|
286
306
|
if (!await directoryExists(sourceDir)) {
|
|
307
|
+
return { skipped: true, skipReason: "No agent templates found in CLI." };
|
|
308
|
+
}
|
|
309
|
+
if (await directoryExists(destDir) && !force) {
|
|
287
310
|
return {
|
|
288
311
|
skipped: true,
|
|
289
|
-
skipReason:
|
|
290
|
-
templatesSkipped: false
|
|
312
|
+
skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`
|
|
291
313
|
};
|
|
292
314
|
}
|
|
293
|
-
const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);
|
|
294
|
-
const templatesBasename = path.basename(DIRS.templates);
|
|
295
|
-
if (await directoryExists(destDir) && !force) {
|
|
296
|
-
if (templatesOnly) {
|
|
297
|
-
return {
|
|
298
|
-
skipped: true,
|
|
299
|
-
skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,
|
|
300
|
-
templatesSkipped: false
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));
|
|
304
|
-
if (await hasAgentPartialDirs(destDir) && !hasTemplates) {
|
|
305
|
-
return {
|
|
306
|
-
skipped: true,
|
|
307
|
-
skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,
|
|
308
|
-
templatesSkipped: false
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
315
|
await ensureDir(destDir);
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
} else {
|
|
321
|
-
await copy(sourceDir, destDir);
|
|
316
|
+
await copy(sourceDir, destDir);
|
|
317
|
+
return { skipped: false, destDir, skippedSubAgents: [], templatesSkipped: false };
|
|
318
|
+
}
|
|
319
|
+
async function ejectSubAgentPartials(destDir, force) {
|
|
320
|
+
const sourceDir = path.join(PROJECT_ROOT, DIRS.agents);
|
|
321
|
+
if (!await directoryExists(sourceDir)) {
|
|
322
|
+
return { skipped: true, skipReason: "No agent partials found in CLI." };
|
|
322
323
|
}
|
|
324
|
+
const units = await partialUnitsIn(sourceDir);
|
|
325
|
+
const present = force ? [] : await alreadyIn(destDir, units);
|
|
326
|
+
const absent = units.filter((unit) => !present.includes(unit));
|
|
327
|
+
if (absent.length === 0) {
|
|
328
|
+
return {
|
|
329
|
+
skipped: true,
|
|
330
|
+
skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
await copyUnits(absent, sourceDir, destDir);
|
|
323
334
|
return {
|
|
324
335
|
skipped: false,
|
|
325
336
|
destDir,
|
|
326
|
-
|
|
337
|
+
skippedSubAgents: subAgentNames(present),
|
|
338
|
+
templatesSkipped: present.some(isTemplatesUnit)
|
|
327
339
|
};
|
|
328
340
|
}
|
|
341
|
+
var TEMPLATES_UNIT = path.basename(DIRS.templates);
|
|
342
|
+
function isTemplatesUnit(unit) {
|
|
343
|
+
return unit === TEMPLATES_UNIT;
|
|
344
|
+
}
|
|
345
|
+
async function partialUnitsIn(agentsSourceDir) {
|
|
346
|
+
const entries = await listDirectories(agentsSourceDir);
|
|
347
|
+
const categories = entries.filter((entry) => !isTemplatesUnit(entry));
|
|
348
|
+
const subAgentDirs = await Promise.all(
|
|
349
|
+
categories.map((category) => subAgentDirsOf(agentsSourceDir, category))
|
|
350
|
+
);
|
|
351
|
+
return [...entries.filter(isTemplatesUnit), ...subAgentDirs.flat()];
|
|
352
|
+
}
|
|
353
|
+
async function subAgentDirsOf(agentsSourceDir, category) {
|
|
354
|
+
const agents = await listDirectories(path.join(agentsSourceDir, category));
|
|
355
|
+
return agents.map((agent) => path.join(category, agent));
|
|
356
|
+
}
|
|
357
|
+
function subAgentNames(units) {
|
|
358
|
+
return units.filter((unit) => !isTemplatesUnit(unit)).map((unit) => path.basename(unit)).sort(bytewise);
|
|
359
|
+
}
|
|
360
|
+
async function copyUnits(units, sourceDir, destDir) {
|
|
361
|
+
for (const unit of units) {
|
|
362
|
+
await copy(path.join(sourceDir, unit), path.join(destDir, unit));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function skillsDestination(projectDir, directOutput, outputBase) {
|
|
366
|
+
return directOutput ? outputBase : installedSkillsDir(projectDir);
|
|
367
|
+
}
|
|
329
368
|
async function ejectSkills(options) {
|
|
330
|
-
const {
|
|
331
|
-
|
|
369
|
+
const { destinationDir, force, sourceResult, matrix: matrix2 } = options;
|
|
370
|
+
const marketplaceSkillIds = [...sourceResult.marketplaceSkillIds];
|
|
371
|
+
const alreadyThere = force ? [] : await alreadyIn(destinationDir, marketplaceSkillIds);
|
|
372
|
+
const notThere = marketplaceSkillIds.filter((skillId) => !alreadyThere.includes(skillId));
|
|
373
|
+
const skillIds = notThere.filter((skillId) => !matrix2.skills[skillId]?.local);
|
|
374
|
+
if (skillIds.length === 0 && alreadyThere.length > 0) {
|
|
332
375
|
return {
|
|
333
376
|
skipped: true,
|
|
334
|
-
skipReason: `Skills already exist at ${
|
|
335
|
-
copiedSkills: []
|
|
377
|
+
skipReason: `Skills already exist at ${destinationDir}. Use --force to overwrite.`
|
|
336
378
|
};
|
|
337
379
|
}
|
|
338
|
-
const skillIds = [...sourceResult.marketplaceSkillIds].filter(
|
|
339
|
-
(skillId) => !matrix2.skills[skillId]?.local
|
|
340
|
-
);
|
|
341
380
|
if (skillIds.length === 0) {
|
|
342
|
-
return {
|
|
343
|
-
skipped: true,
|
|
344
|
-
skipReason: "No skills found in the marketplace to eject.",
|
|
345
|
-
copiedSkills: []
|
|
346
|
-
};
|
|
381
|
+
return { skipped: true, skipReason: "No skills found in the marketplace to eject." };
|
|
347
382
|
}
|
|
348
|
-
await ensureDir(
|
|
349
|
-
const copiedSkills = await copySkillsToLocalFlattened(skillIds,
|
|
383
|
+
await ensureDir(destinationDir);
|
|
384
|
+
const copiedSkills = await copySkillsToLocalFlattened(skillIds, destinationDir, sourceResult);
|
|
350
385
|
const sourceLabel = sourceResult.isLocal ? sourceResult.sourcePath : sourceResult.marketplace || sourceResult.sourceConfig.source;
|
|
351
386
|
return {
|
|
352
387
|
skipped: false,
|
|
353
388
|
copiedSkills,
|
|
389
|
+
skippedSkillCount: alreadyThere.length,
|
|
354
390
|
sourceLabel
|
|
355
391
|
};
|
|
356
392
|
}
|
|
@@ -366,11 +402,10 @@ async function ensureMinimalConfig(options) {
|
|
|
366
402
|
return { configPath: tsConfigPath, created: false };
|
|
367
403
|
}
|
|
368
404
|
const resolvedConfig = sourceResult?.sourceConfig ?? await resolveSource({ caller: "stored", projectDir });
|
|
369
|
-
const existingProjectConfig = await loadProjectSourceConfig(projectDir);
|
|
370
405
|
const source = resolvedConfig.source || void 0;
|
|
371
406
|
if (isHomeDirectory(projectDir)) {
|
|
372
407
|
await ensureBlankPair(provider);
|
|
373
|
-
if (source) await
|
|
408
|
+
if (source) await recordSourceInGlobal(projectDir, source);
|
|
374
409
|
return { configPath: tsConfigPath, created: true };
|
|
375
410
|
}
|
|
376
411
|
await writeProjectPartial(
|
|
@@ -379,34 +414,18 @@ async function ensureMinimalConfig(options) {
|
|
|
379
414
|
skills: [],
|
|
380
415
|
agents: [],
|
|
381
416
|
...source ? { marketplace: source } : {},
|
|
382
|
-
...resolvedConfig.marketplace ? { marketplaceName: resolvedConfig.marketplace } : {}
|
|
383
|
-
...existingProjectConfig?.author ? { author: existingProjectConfig.author } : {},
|
|
384
|
-
...existingProjectConfig?.agentsSource ? { agentsSource: existingProjectConfig.agentsSource } : {}
|
|
417
|
+
...resolvedConfig.marketplace ? { marketplaceName: resolvedConfig.marketplace } : {}
|
|
385
418
|
},
|
|
386
419
|
{ fallbackName: path.basename(projectDir) }
|
|
387
420
|
);
|
|
388
421
|
return { configPath: tsConfigPath, created: true };
|
|
389
422
|
}
|
|
390
|
-
async function
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
lazyGateDeps(projectDir)
|
|
395
|
-
);
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
const existing = await loadProjectSourceConfig(projectDir) ?? {};
|
|
399
|
-
await writeProjectPartial(
|
|
400
|
-
projectDir,
|
|
401
|
-
{ ...existing, marketplace: source },
|
|
402
|
-
{ fallbackName: path.basename(projectDir) }
|
|
423
|
+
async function recordSourceInGlobal(projectDir, source) {
|
|
424
|
+
await mutateGlobal(
|
|
425
|
+
{ kind: "set-source", source, fallbackName: path.basename(projectDir) },
|
|
426
|
+
lazyGateDeps(projectDir)
|
|
403
427
|
);
|
|
404
428
|
}
|
|
405
|
-
async function hasAgentPartialDirs(agentsDir) {
|
|
406
|
-
const subdirs = await listDirectories(agentsDir);
|
|
407
|
-
const templatesBasename = path.basename(DIRS.templates);
|
|
408
|
-
return subdirs.some((dir) => dir !== templatesBasename);
|
|
409
|
-
}
|
|
410
429
|
export {
|
|
411
430
|
Eject as default
|
|
412
431
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { copy, ensureDir, directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport { DIRS, PROJECT_ROOT } from \"../consts.js\";\nimport {\n providerInUse,\n relativeConfigPath,\n sourceFolderInUse,\n} from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport {\n resolveSource,\n loadProjectSourceConfig,\n getProjectConfigPath,\n} from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport { INCOMPLETE_WORK_RECOVERY, INFO_MESSAGES } from \"../utils/messages.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { plural } from \"../utils/string.js\";\nimport type { MergedSkillsMatrix } from \"../types/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the marketplace this installation is configured to read \" +\n \"(the public one by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n provider: providerFlag(),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n // No `default:`, and no default named here either: each eject type has its own\n // destination and this flag replaces all three at once. The reference page carries\n // the table; a one-line description that picked one of the three would be wrong\n // about the other two, which is what it was.\n description:\n \"Write everything into this directory instead of each eject type's own destination\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n // Above the layout settle, because that refusal is about two FOLDER NAMES of one installation\n // and this one is about two installations. Both have to be answered before anything is\n // written, and this one decides which installation the other is even asking about.\n await refuseAnAmbiguousInstallation(\n projectDir,\n \"eject\",\n providerNamedBy(flags.provider),\n (message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n\n // Before anything is copied: a config nobody can read is recreated, not ejected over, and a\n // refusal past this point would follow files already written.\n await this.ensureConfigReadable(projectDir);\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(\n await this.resolveBrandingName(projectDir),\n flags.output ? outputBase : undefined,\n );\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.ensureConfig(projectDir, sourceResult);\n\n this.reportEnding();\n }\n\n /**\n * The command's last word.\n *\n * `Eject complete!` claims the whole eject landed, so it is withheld whenever part of it did\n * not — the account {@link BaseCommand.exitIfWorkIncomplete} prints replaces that tick rather\n * than sitting under it, and carries the non-zero exit with it.\n */\n private reportEnding(): void {\n this.log(\"\");\n if (!this.hasIncompleteWork) this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n\n this.exitIfWorkIncomplete();\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(\n flags: { output: string | undefined },\n projectDir: string,\n ): Promise<string> {\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n const outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return outputBase;\n }\n\n return sourceFolderInUse(projectDir, providerInUse(projectDir)).dir;\n }\n\n private printHeader(brandingName: string, outputBase?: string): void {\n this.log(\"\");\n this.log(`${brandingName} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({ projectDir });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output: string | undefined },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for skills eject\");\n }\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n case \"all\":\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for full eject\");\n }\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleAgentPartials(outputBase, true, directOutput, true);\n await this.handleSkills(projectDir, flags.force, sourceResult, directOutput, outputBase);\n break;\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n /**\n * The convenience step after the eject: a minimal `config.ts` so a later `compile` has\n * something to read.\n *\n * It can refuse, and by the time it does the ejection has already landed — the templates,\n * partials or skills are on disk and stay there. So the throw is caught rather than left to\n * become the process's exit code: an `ERROR` tells the caller nothing landed and the run can\n * be repeated, which is the wrong instruction for a tree that now holds an ejection. What is\n * owed is the account and `EXIT_CODES.COMPLETED_WITH_FAILURES`.\n *\n * The refusal itself is right and is not weakened here: `ensureMinimalConfig` will not invent\n * a config recording a marketplace it read out of a file it could not evaluate.\n */\n private async ensureConfig(\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n // Named once, before the write, so the success line and the failure line cannot name\n // different files: the provider is read off the disk and the write may create the folder.\n const configTsRel = relativeConfigPath(projectDir, providerInUse(projectDir));\n\n try {\n const configResult = await ensureMinimalConfig({\n projectDir,\n ...(sourceResult !== undefined && { sourceResult }),\n });\n if (configResult.created) {\n this.logSuccess(`Created ${configTsRel}`);\n }\n } catch (error) {\n this.reportIncompleteWork(\n `Could not create ${configTsRel}: ${getErrorMessage(error)}`,\n INCOMPLETE_WORK_RECOVERY.INSPECT_INSTALLATION,\n );\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : INFO_MESSAGES.AGENT_PARTIALS_CUSTOMIZABLE,\n );\n }\n\n private async handleSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput: boolean,\n outputBase: string,\n ): Promise<void> {\n const destDir = directOutput ? outputBase : installedSkillsDir(projectDir);\n const result = await ejectSkills({ destDir, force, sourceResult, matrix });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n this.logSuccess(\n `${plural(result.copiedSkills.length, \"skill\")} ejected to ${destDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n /** When true, outputBase is used directly as the destination (no subdirectory nesting). */\n directOutput?: boolean;\n /** When true, ejects only the _templates directory instead of the full agents directory. */\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n templatesSkipped: false;\n }\n | {\n skipped: false;\n /** Destination directory that was written to. */\n destDir: string;\n /** Whether templates were skipped during a full agent-partials eject (existing templates preserved). */\n templatesSkipped: boolean;\n };\n\n/** Direct output writes to the base itself; otherwise agents/ (plus templates/ in templates-only mode). */\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\n/**\n * Copies agent partials or templates from the CLI source to a target directory.\n *\n * When `templatesOnly` is true, copies only the _templates subdirectory.\n * When false, copies the full agents directory (optionally skipping existing templates).\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n\n const sourceDir = templatesOnly\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return {\n skipped: true,\n skipReason: templatesOnly\n ? \"No agent templates found in CLI.\"\n : \"No agent partials found in CLI.\",\n templatesSkipped: false,\n };\n }\n\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesOnly) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await hasAgentPartialDirs(destDir)) && !hasTemplates) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n templatesSkipped: false,\n };\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesOnly && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n } else {\n await copy(sourceDir, destDir);\n }\n\n return {\n skipped: false,\n destDir,\n templatesSkipped: skipTemplates,\n };\n}\n\ntype EjectSkillsOptions = {\n destDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n copiedSkills: [];\n }\n | {\n skipped: false;\n /** Array of skills that were copied. */\n copiedSkills: CopiedSkill[];\n /** Label describing the source that skills were copied from. */\n sourceLabel: string;\n };\n\n/**\n * Copies the marketplace's own skills from source to a target directory.\n *\n * Only the skills the loaded marketplace carries, because those are the only ones its folder\n * holds: a global installation's skill seated from another marketplace is in the matrix and not\n * on disk here. Skills already marked as local are filtered out too, then the remaining skills\n * are copied using copySkillsToLocalFlattened.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const { destDir, force, sourceResult, matrix } = options;\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destDir}. Use --force to overwrite.`,\n copiedSkills: [],\n };\n }\n\n const skillIds = [...sourceResult.marketplaceSkillIds].filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n return {\n skipped: true,\n skipReason: \"No skills found in the marketplace to eject.\",\n copiedSkills: [],\n };\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n sourceLabel,\n };\n}\n\n/**\n * The skills folder the install copies into for the installation `projectDir` roots — at the\n * scope that directory is, on the provider this run is about — so an eject lands where that\n * installation's host reads skills: `.claude/skills`, `<repo>/.agents/skills` or\n * `$CODEX_HOME/skills`.\n */\nfunction installedSkillsDir(projectDir: string): string {\n const scope = isHomeDirectory(projectDir) ? \"global\" : \"project\";\n return resolveInstallPaths(projectDir, scope).skillsDir;\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n /** Path to the config file. */\n configPath: string;\n /** Whether a new config was created. */\n created: boolean;\n};\n\n/**\n * Ensures a minimal config.ts exists so `npx agents-inc compile` works after eject.\n *\n * If the config already exists, returns immediately with `created: false`.\n * Otherwise generates a minimal config from the resolved source and project metadata.\n *\n * Returns structured data — the command decides what to log.\n */\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceResult } = options;\n\n // One read for the whole function: the config it may invent, and the blank global pair it may\n // create beside it, belong to the same installation.\n const provider = providerInUse(projectDir);\n const tsConfigPath = getProjectConfigPath(projectDir, provider);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n // ABORT on an unreadable config. The project has none — the guard above returned for that — so\n // what these two can meet is an unreadable GLOBAL config, and the file about to be invented\n // would record a marketplace read from nowhere. The second call is unreachable for the same\n // reason the guard exists: this project's own config is not there to be unreadable.\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource({ caller: \"stored\", projectDir }));\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n const source = resolvedConfig.source || undefined;\n\n // At the home directory the invented config IS the global manifest, and the\n // file it opens with `import type { ProjectConfig } from \"./config-types\"`\n // cannot resolve its own types without the sibling. The gate writes the pair.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair(provider);\n if (source) await recordSource(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { marketplace: source } : {}),\n ...(resolvedConfig.marketplace ? { marketplaceName: resolvedConfig.marketplace } : {}),\n ...(existingProjectConfig?.author ? { author: existingProjectConfig.author } : {}),\n ...(existingProjectConfig?.agentsSource\n ? { agentsSource: existingProjectConfig.agentsSource }\n : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/**\n * Records the marketplace ref in whichever scope's config `projectDir` names. At the home\n * directory that config is the global manifest every project's generated types\n * import from, so the write goes through the gate: registered projects inline\n * the scalar and follow it.\n */\nasync function recordSource(projectDir: string, source: string): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n return;\n }\n\n // ABORT on an unreadable config. The `?? {}` is a fallback for a config that is not THERE; on\n // one that is there and unreadable it would hand the writer an empty partial, and this scalar\n // write would replace the user's whole file with a two-field one under an invented name.\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n await writeProjectPartial(\n projectDir,\n { ...existing, marketplace: source },\n { fallbackName: path.basename(projectDir) },\n );\n}\n\n/** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\nasync function hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n}\n"],"mappings":"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","names":["matrix"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n copy,\n ensureDir,\n directoryExists,\n fileExists,\n isSymlink,\n listDirectories,\n} from \"../utils/fs.js\";\nimport { DIRS, PROJECT_ROOT } from \"../consts.js\";\nimport {\n providerInUse,\n relativeConfigPath,\n sourceFolderInUse,\n} from \"../lib/installation/install-layout.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { loadSource } from \"../lib/operations/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { resolveSource, getProjectConfigPath } from \"../lib/configuration/index.js\";\nimport {\n ensureBlankPair,\n lazyGateDeps,\n mutateGlobal,\n writeProjectPartial,\n} from \"../lib/config-gate/index.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../lib/installation/index.js\";\nimport {\n providerFlag,\n providerNamedBy,\n refuseAnAmbiguousInstallation,\n} from \"../lib/installation/provider-flag.js\";\nimport { copySkillsToLocalFlattened, type CopiedSkill } from \"../lib/skills/index.js\";\nimport { INCOMPLETE_WORK_RECOVERY, INFO_MESSAGES } from \"../utils/messages.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { bytewise, plural } from \"../utils/string.js\";\nimport type { MergedSkillsMatrix } from \"../types/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the marketplace this installation is configured to read \" +\n \"(the public one by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n provider: providerFlag(),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n // No default: each eject type has its own destination and this replaces all three.\n description:\n \"Write everything into this directory instead of each eject type's own destination\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n // Before the layout settle: this decides which installation that refusal is about.\n await refuseAnAmbiguousInstallation(\n projectDir,\n \"eject\",\n providerNamedBy(flags.provider),\n (message) => this.error(message, { exit: EXIT_CODES.INVALID_ARGS }),\n );\n\n // Before anything is copied, so a refusal never follows files already written.\n await this.ensureConfigReadable(projectDir);\n const ejectType = this.validateEjectType(args.type);\n const outputBase = await this.resolveOutputBase(flags, projectDir);\n\n this.printHeader(\n await this.resolveBrandingName(projectDir),\n flags.output ? outputBase : undefined,\n );\n\n const sourceResult = await this.loadSourceIfNeeded(ejectType, projectDir);\n await this.executeEject(ejectType, outputBase, flags, projectDir, sourceResult);\n await this.ensureConfig(projectDir, sourceResult);\n\n this.reportEnding();\n }\n\n /** Withholds `Eject complete!` when part of the eject did not land. */\n private reportEnding(): void {\n this.log(\"\");\n if (!this.hasIncompleteWork) this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n\n this.exitIfWorkIncomplete();\n }\n\n private validateEjectType(typeArg: string | undefined): EjectType {\n if (!typeArg) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(typeArg)) {\n this.error(`Unknown eject type: ${typeArg}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n return typeArg;\n }\n\n private async resolveOutputBase(\n flags: { output: string | undefined },\n projectDir: string,\n ): Promise<string> {\n if (!flags.output) return sourceFolderInUse(projectDir, providerInUse(projectDir)).dir;\n\n const outputBase = path.resolve(projectDir, expandHome(flags.output));\n await this.refuseUnwritableOutput(outputBase);\n return outputBase;\n }\n\n private async refuseUnwritableOutput(outputBase: string): Promise<void> {\n // First, as the checks below follow a link, and so would every write.\n if (await isSymlink(outputBase)) {\n this.error(`Output path is a link: ${outputBase}. Name the folder it points to instead.`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n // `fileExists` is true of a directory too; an existing directory is written into, and each\n // kind then skips what it would write there already unless --force.\n const namesAFile = (await fileExists(outputBase)) && !(await directoryExists(outputBase));\n if (namesAFile) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n }\n\n private printHeader(brandingName: string, outputBase?: string): void {\n this.log(\"\");\n this.log(`${brandingName} Eject`);\n this.log(\"\");\n\n if (outputBase) {\n this.log(`Output directory: ${outputBase}`);\n }\n }\n\n private async loadSourceIfNeeded(\n ejectType: EjectType,\n projectDir: string,\n ): Promise<SourceLoadResult | undefined> {\n if (ejectType === \"skills\" || ejectType === \"all\") {\n const loaded = await loadSource({ projectDir });\n return loaded.sourceResult;\n }\n return undefined;\n }\n\n private async executeEject(\n ejectType: EjectType,\n outputBase: string,\n flags: { force: boolean; output: string | undefined },\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n const directOutput = !!flags.output;\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.handleAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for skills eject\");\n }\n await this.handleSkills(\n skillsDestination(projectDir, directOutput, outputBase),\n flags.force,\n sourceResult,\n );\n break;\n case \"all\": {\n if (!sourceResult) {\n throw new Error(\"The marketplace must be loaded for full eject\");\n }\n // The partials carry the templates as one unit, so they arrive once and obey --force.\n await this.handleAgentPartials(outputBase, flags.force, directOutput, false);\n await this.handleSkills(\n skillsDestination(projectDir, directOutput, outputBase),\n flags.force,\n sourceResult,\n );\n break;\n }\n default: {\n const _exhaustive: never = ejectType;\n return _exhaustive;\n }\n }\n }\n\n /**\n * Writes a minimal config so `compile` works afterwards. A refusal is reported as incomplete\n * work rather than thrown, because the ejection has already landed.\n */\n private async ensureConfig(\n projectDir: string,\n sourceResult: SourceLoadResult | undefined,\n ): Promise<void> {\n // Named before the write, which may create the provider folder.\n const configTsRel = relativeConfigPath(projectDir, providerInUse(projectDir));\n\n try {\n const configResult = await ensureMinimalConfig({\n projectDir,\n ...(sourceResult !== undefined && { sourceResult }),\n });\n if (configResult.created) {\n this.logSuccess(`Created ${configTsRel}`);\n }\n } catch (error) {\n this.reportIncompleteWork(\n `Could not create ${configTsRel}: ${getErrorMessage(error)}`,\n INCOMPLETE_WORK_RECOVERY.INSPECT_INSTALLATION,\n );\n }\n }\n\n private async handleAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput: boolean,\n templatesOnly: boolean,\n ): Promise<void> {\n const result = await ejectAgentPartials({\n outputBase,\n force,\n directOutput,\n templatesOnly,\n });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.skippedSubAgents.length > 0) {\n this.warn(subAgentsAlreadyThere(result.destDir, result.skippedSubAgents));\n }\n\n if (result.templatesSkipped) {\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n }\n\n this.logSuccess(\n `${templatesOnly ? \"Agent templates\" : \"Agent partials\"} ejected to ${result.destDir}`,\n );\n this.log(\n templatesOnly\n ? \"You can now customize agent templates locally.\"\n : INFO_MESSAGES.AGENT_PARTIALS_CUSTOMIZABLE,\n );\n }\n\n private async handleSkills(\n destinationDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n ): Promise<void> {\n const result = await ejectSkills({ destinationDir, force, sourceResult, matrix });\n\n if (result.skipped) {\n this.warn(result.skipReason);\n return;\n }\n\n if (result.skippedSkillCount > 0) {\n this.warn(skillsAlreadyThere(destinationDir, result.skippedSkillCount));\n }\n\n this.logSuccess(\n `${plural(result.copiedSkills.length, \"skill\")} ejected to ${destinationDir} from ${result.sourceLabel}`,\n );\n this.log(\"You can now customize skill content locally.\");\n }\n}\n\nfunction expandHome(outputPath: string): string {\n return outputPath.startsWith(\"~\") ? path.join(os.homedir(), outputPath.slice(1)) : outputPath;\n}\n\n/** Some of what an eject copies was already there: named, with the rest copied beside it. */\nfunction subAgentsAlreadyThere(destDir: string, subAgents: readonly string[]): string {\n return `Agent partials already exist at ${destDir} — skipped ${plural(subAgents.length, \"sub-agent\")}: ${subAgents.join(\", \")}. Use --force to overwrite them.`;\n}\n\n/** Counted rather than named: a re-run into a nearly full folder skips most of the marketplace. */\nfunction skillsAlreadyThere(destinationDir: string, skippedCount: number): string {\n return `Skills already exist at ${destinationDir} — skipped ${plural(skippedCount, \"skill\")}. Use --force to overwrite them.`;\n}\n\n/** Those of `names` already at `dir`, file or folder: what an eject without --force leaves. */\nasync function alreadyIn<Name extends string>(\n dir: string,\n names: readonly Name[],\n): Promise<Name[]> {\n const checked = await Promise.all(\n names.map(async (name) => ({ name, there: await fileExists(path.join(dir, name)) })),\n );\n return checked.filter(({ there }) => there).map(({ name }) => name);\n}\n\ntype EjectAgentPartialsOptions = {\n outputBase: string;\n force: boolean;\n directOutput?: boolean;\n templatesOnly?: boolean;\n};\n\ntype EjectAgentPartialsResult =\n | {\n skipped: true;\n skipReason: string;\n }\n | {\n skipped: false;\n destDir: string;\n /** The sub-agents left as they were, by name, bytewise-sorted. */\n skippedSubAgents: string[];\n templatesSkipped: boolean;\n };\n\nfunction resolveEjectDestDir(\n outputBase: string,\n directOutput: boolean,\n templatesOnly: boolean,\n): string {\n if (directOutput) return outputBase;\n const agentsDir = path.join(outputBase, path.basename(DIRS.agents));\n return templatesOnly ? path.join(agentsDir, path.basename(DIRS.templates)) : agentsDir;\n}\n\nasync function ejectAgentPartials(\n options: EjectAgentPartialsOptions,\n): Promise<EjectAgentPartialsResult> {\n const { outputBase, force, directOutput = false, templatesOnly = false } = options;\n const destDir = resolveEjectDestDir(outputBase, directOutput, templatesOnly);\n\n return templatesOnly ? ejectTemplates(destDir, force) : ejectSubAgentPartials(destDir, force);\n}\n\n/** Whole or not at all: a templates folder already there is kept unless --force. */\nasync function ejectTemplates(destDir: string, force: boolean): Promise<EjectAgentPartialsResult> {\n const sourceDir = path.join(PROJECT_ROOT, DIRS.templates);\n\n if (!(await directoryExists(sourceDir))) {\n return { skipped: true, skipReason: \"No agent templates found in CLI.\" };\n }\n\n if ((await directoryExists(destDir)) && !force) {\n return {\n skipped: true,\n skipReason: `Agent templates already exist at ${destDir}. Use --force to overwrite.`,\n };\n }\n\n await ensureDir(destDir);\n await copy(sourceDir, destDir);\n return { skipped: false, destDir, skippedSubAgents: [], templatesSkipped: false };\n}\n\n/** Unit by unit: one already there is kept unless --force, and the rest are copied beside it. */\nasync function ejectSubAgentPartials(\n destDir: string,\n force: boolean,\n): Promise<EjectAgentPartialsResult> {\n const sourceDir = path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n return { skipped: true, skipReason: \"No agent partials found in CLI.\" };\n }\n\n const units = await partialUnitsIn(sourceDir);\n const present = force ? [] : await alreadyIn(destDir, units);\n const absent = units.filter((unit) => !present.includes(unit));\n\n if (absent.length === 0) {\n return {\n skipped: true,\n skipReason: `Agent partials already exist at ${destDir}. Use --force to overwrite.`,\n };\n }\n\n await copyUnits(absent, sourceDir, destDir);\n\n return {\n skipped: false,\n destDir,\n skippedSubAgents: subAgentNames(present),\n templatesSkipped: present.some(isTemplatesUnit),\n };\n}\n\nconst TEMPLATES_UNIT = path.basename(DIRS.templates);\n\nfunction isTemplatesUnit(unit: string): boolean {\n return unit === TEMPLATES_UNIT;\n}\n\n/**\n * What a re-eject keeps or copies whole: each sub-agent's directory, as `<category>/<agent>`, and\n * the templates. A category folder is not one, so a file of the user's in it is written beside.\n */\nasync function partialUnitsIn(agentsSourceDir: string): Promise<string[]> {\n const entries = await listDirectories(agentsSourceDir);\n const categories = entries.filter((entry) => !isTemplatesUnit(entry));\n const subAgentDirs = await Promise.all(\n categories.map((category) => subAgentDirsOf(agentsSourceDir, category)),\n );\n return [...entries.filter(isTemplatesUnit), ...subAgentDirs.flat()];\n}\n\nasync function subAgentDirsOf(agentsSourceDir: string, category: string): Promise<string[]> {\n const agents = await listDirectories(path.join(agentsSourceDir, category));\n return agents.map((agent) => path.join(category, agent));\n}\n\n/** As the skipped-list warning names them: by directory name, bytewise-sorted. */\nfunction subAgentNames(units: readonly string[]): string[] {\n return units\n .filter((unit) => !isTemplatesUnit(unit))\n .map((unit) => path.basename(unit))\n .sort(bytewise);\n}\n\n/** `copy` makes the folders above each unit. */\nasync function copyUnits(\n units: readonly string[],\n sourceDir: string,\n destDir: string,\n): Promise<void> {\n for (const unit of units) {\n await copy(path.join(sourceDir, unit), path.join(destDir, unit));\n }\n}\n\nfunction skillsDestination(projectDir: string, directOutput: boolean, outputBase: string): string {\n return directOutput ? outputBase : installedSkillsDir(projectDir);\n}\n\ntype EjectSkillsOptions = {\n destinationDir: string;\n force: boolean;\n sourceResult: SourceLoadResult;\n matrix: MergedSkillsMatrix;\n};\n\ntype EjectSkillsResult =\n | {\n skipped: true;\n skipReason: string;\n }\n | {\n skipped: false;\n copiedSkills: CopiedSkill[];\n /** How many skills were left as they were. */\n skippedSkillCount: number;\n sourceLabel: string;\n };\n\n/**\n * Only the loaded marketplace's own non-local skills: others' skills are not on disk here. One\n * already in the destination is skipped first, as the local copy may be the one there.\n */\nasync function ejectSkills(options: EjectSkillsOptions): Promise<EjectSkillsResult> {\n const { destinationDir, force, sourceResult, matrix } = options;\n\n const marketplaceSkillIds = [...sourceResult.marketplaceSkillIds];\n const alreadyThere = force ? [] : await alreadyIn(destinationDir, marketplaceSkillIds);\n const notThere = marketplaceSkillIds.filter((skillId) => !alreadyThere.includes(skillId));\n const skillIds = notThere.filter((skillId) => !matrix.skills[skillId]?.local);\n\n if (skillIds.length === 0 && alreadyThere.length > 0) {\n return {\n skipped: true,\n skipReason: `Skills already exist at ${destinationDir}. Use --force to overwrite.`,\n };\n }\n\n if (skillIds.length === 0) {\n return { skipped: true, skipReason: \"No skills found in the marketplace to eject.\" };\n }\n\n await ensureDir(destinationDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destinationDir, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n return {\n skipped: false,\n copiedSkills,\n skippedSkillCount: alreadyThere.length,\n sourceLabel,\n };\n}\n\n/** Where the host of the installation `projectDir` roots reads skills. */\nfunction installedSkillsDir(projectDir: string): string {\n const scope = isHomeDirectory(projectDir) ? \"global\" : \"project\";\n return resolveInstallPaths(projectDir, scope).skillsDir;\n}\n\ntype EnsureMinimalConfigOptions = {\n projectDir: string;\n sourceResult?: SourceLoadResult;\n};\n\ntype EnsureMinimalConfigResult = {\n configPath: string;\n created: boolean;\n};\n\nasync function ensureMinimalConfig(\n options: EnsureMinimalConfigOptions,\n): Promise<EnsureMinimalConfigResult> {\n const { projectDir, sourceResult } = options;\n\n const provider = providerInUse(projectDir);\n const tsConfigPath = getProjectConfigPath(projectDir, provider);\n\n if (await fileExists(tsConfigPath)) {\n return { configPath: tsConfigPath, created: false };\n }\n\n // ABORT on an unreadable global config: the invented file would record a marketplace from nowhere.\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource({ caller: \"stored\", projectDir }));\n const source = resolvedConfig.source || undefined;\n\n // At home the invented config is the global manifest, which needs its config-types sibling.\n if (isHomeDirectory(projectDir)) {\n await ensureBlankPair(provider);\n if (source) await recordSourceInGlobal(projectDir, source);\n return { configPath: tsConfigPath, created: true };\n }\n\n await writeProjectPartial(\n projectDir,\n {\n skills: [],\n agents: [],\n ...(source ? { marketplace: source } : {}),\n ...(resolvedConfig.marketplace ? { marketplaceName: resolvedConfig.marketplace } : {}),\n },\n { fallbackName: path.basename(projectDir) },\n );\n\n return { configPath: tsConfigPath, created: true };\n}\n\n/** At home the config is the global manifest projects inline from, so it goes through the gate. */\nasync function recordSourceInGlobal(projectDir: string, source: string): Promise<void> {\n await mutateGlobal(\n { kind: \"set-source\", source, fallbackName: path.basename(projectDir) },\n lazyGateDeps(projectDir),\n );\n}\n"],"mappings":"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","names":["matrix"]}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,38 +2,31 @@
|
|
|
2
2
|
import {
|
|
3
3
|
Dashboard,
|
|
4
4
|
Init,
|
|
5
|
-
dashboardCountLines,
|
|
6
5
|
formatDashboardText,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-OYJQUA3D.js";
|
|
14
|
-
import "../chunk-4AAOOAIN.js";
|
|
6
|
+
runDashboardFlow
|
|
7
|
+
} from "../chunk-YXKTY5WM.js";
|
|
8
|
+
import "../chunk-3ED3KHHD.js";
|
|
9
|
+
import "../chunk-PLFANHRZ.js";
|
|
10
|
+
import "../chunk-YGDWHDOY.js";
|
|
11
|
+
import "../chunk-P6CYS4JK.js";
|
|
15
12
|
import "../chunk-OZXAJNLA.js";
|
|
16
|
-
import "../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-NQW25DCF.js";
|
|
13
|
+
import "../chunk-PSUTNOQ2.js";
|
|
14
|
+
import "../chunk-66AEVERM.js";
|
|
15
|
+
import "../chunk-IWY5IR4F.js";
|
|
16
|
+
import "../chunk-THO7LO5B.js";
|
|
17
|
+
import "../chunk-5BNX73OU.js";
|
|
18
|
+
import "../chunk-2YA4DDRM.js";
|
|
19
|
+
import "../chunk-KIK5EZYD.js";
|
|
20
|
+
import "../chunk-OCAVW6N5.js";
|
|
21
|
+
import "../chunk-GEMW5RQ2.js";
|
|
22
|
+
import "../chunk-GAKVZNTX.js";
|
|
23
|
+
import "../chunk-AUNRHWH4.js";
|
|
24
|
+
import "../chunk-7C3PFRBU.js";
|
|
25
|
+
import "../chunk-GHHJYNAN.js";
|
|
30
26
|
export {
|
|
31
27
|
Dashboard,
|
|
32
|
-
dashboardCountLines,
|
|
33
28
|
Init as default,
|
|
34
29
|
formatDashboardText,
|
|
35
|
-
|
|
36
|
-
runDashboardFlow,
|
|
37
|
-
showDashboard
|
|
30
|
+
runDashboardFlow
|
|
38
31
|
};
|
|
39
32
|
//# sourceMappingURL=init.js.map
|