harnessed 3.4.2 → 3.4.3
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/dist/cli.mjs +242 -96
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/workflows/auto/SKILL.md +9 -0
- package/workflows/discuss/auto/SKILL.md +10 -2
- package/workflows/discuss/phase/SKILL.md +29 -9
- package/workflows/discuss/strategic/SKILL.md +32 -10
- package/workflows/discuss/subtask/SKILL.md +29 -9
- package/workflows/plan/architecture/SKILL.md +31 -9
- package/workflows/plan/auto/SKILL.md +10 -2
- package/workflows/plan/phase/SKILL.md +31 -9
- package/workflows/research/SKILL.md +31 -2
- package/workflows/retro/SKILL.md +29 -18
- package/workflows/role-prompts.yaml +477 -0
- package/workflows/task/auto/SKILL.md +10 -2
- package/workflows/task/clarify/SKILL.md +29 -24
- package/workflows/task/code/SKILL.md +31 -24
- package/workflows/task/deliver/SKILL.md +31 -24
- package/workflows/task/test/SKILL.md +31 -24
- package/workflows/verify/auto/SKILL.md +9 -1
- package/workflows/verify/code-review/SKILL.md +34 -19
- package/workflows/verify/design/SKILL.md +33 -18
- package/workflows/verify/multispec/SKILL.md +32 -19
- package/workflows/verify/paranoid/SKILL.md +36 -19
- package/workflows/verify/progress/SKILL.md +29 -18
- package/workflows/verify/qa/SKILL.md +32 -19
- package/workflows/verify/security/SKILL.md +34 -19
- package/workflows/verify/simplify/SKILL.md +32 -19
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { homedir } from 'os';
|
|
|
6
6
|
import { Type } from '@sinclair/typebox';
|
|
7
7
|
import { Value } from '@sinclair/typebox/value';
|
|
8
8
|
import { LineCounter, parseDocument, parse, isSeq, isScalar } from 'yaml';
|
|
9
|
-
import { readFile, readdir, unlink, writeFile, stat, rm, cp,
|
|
9
|
+
import { readFile, readdir, unlink, writeFile, stat, rm, cp, mkdir, access, rename } from 'fs/promises';
|
|
10
10
|
import lockfile from 'proper-lockfile';
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import { Ajv } from 'ajv';
|
|
@@ -847,7 +847,7 @@ var init_resume = __esm({
|
|
|
847
847
|
|
|
848
848
|
// package.json
|
|
849
849
|
var package_default = {
|
|
850
|
-
version: "3.4.
|
|
850
|
+
version: "3.4.3"};
|
|
851
851
|
|
|
852
852
|
// src/manifest/errors.ts
|
|
853
853
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -4854,6 +4854,109 @@ ${t("rollback.metadata_unreadable.fix")}`
|
|
|
4854
4854
|
console.log(t("rollback.restored", { count: meta.files.length, timestamp }));
|
|
4855
4855
|
});
|
|
4856
4856
|
}
|
|
4857
|
+
function readInstalledPlugins(homedirOverride) {
|
|
4858
|
+
const home = homedir();
|
|
4859
|
+
const path = join(home, ".claude", "plugins", "installed_plugins.json");
|
|
4860
|
+
let raw;
|
|
4861
|
+
try {
|
|
4862
|
+
raw = readFileSync(path, "utf8");
|
|
4863
|
+
} catch {
|
|
4864
|
+
return /* @__PURE__ */ new Set();
|
|
4865
|
+
}
|
|
4866
|
+
let parsed;
|
|
4867
|
+
try {
|
|
4868
|
+
parsed = JSON.parse(raw);
|
|
4869
|
+
} catch {
|
|
4870
|
+
return /* @__PURE__ */ new Set();
|
|
4871
|
+
}
|
|
4872
|
+
if (!parsed || typeof parsed !== "object") return /* @__PURE__ */ new Set();
|
|
4873
|
+
const plugins = parsed.plugins;
|
|
4874
|
+
if (!plugins || typeof plugins !== "object") return /* @__PURE__ */ new Set();
|
|
4875
|
+
const out = /* @__PURE__ */ new Set();
|
|
4876
|
+
for (const key of Object.keys(plugins)) {
|
|
4877
|
+
const at = key.indexOf("@");
|
|
4878
|
+
if (at <= 0) continue;
|
|
4879
|
+
out.add(key.slice(0, at));
|
|
4880
|
+
}
|
|
4881
|
+
return out;
|
|
4882
|
+
}
|
|
4883
|
+
function readInstalledUserSkills(homedirOverride) {
|
|
4884
|
+
const home = homedir();
|
|
4885
|
+
const skillsRoot = join(home, ".claude", "skills");
|
|
4886
|
+
try {
|
|
4887
|
+
const entries = readdirSync(skillsRoot, { withFileTypes: true });
|
|
4888
|
+
const out = /* @__PURE__ */ new Set();
|
|
4889
|
+
for (const e of entries) if (e.isDirectory()) out.add(e.name);
|
|
4890
|
+
return out;
|
|
4891
|
+
} catch {
|
|
4892
|
+
return /* @__PURE__ */ new Set();
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
function resolveCapabilityCmd(capability, installedPlugins, installedUserSkills) {
|
|
4896
|
+
const { cmd, install_type, plugin_id, skill_dir } = capability;
|
|
4897
|
+
if (!install_type) return { renderedCmd: cmd };
|
|
4898
|
+
const types = Array.isArray(install_type) ? install_type : [install_type];
|
|
4899
|
+
const uniqueTypes = [...new Set(types)];
|
|
4900
|
+
const missingHints = [];
|
|
4901
|
+
let anyDetected = false;
|
|
4902
|
+
for (const t2 of uniqueTypes) {
|
|
4903
|
+
if (t2 === "plugin") {
|
|
4904
|
+
if (!plugin_id) {
|
|
4905
|
+
missingHints.push(
|
|
4906
|
+
`install_type=plugin declared but no plugin_id (capabilities.yaml schema bug)`
|
|
4907
|
+
);
|
|
4908
|
+
continue;
|
|
4909
|
+
}
|
|
4910
|
+
if (installedPlugins.has(plugin_id)) {
|
|
4911
|
+
anyDetected = true;
|
|
4912
|
+
break;
|
|
4913
|
+
}
|
|
4914
|
+
missingHints.push(`plugin '${plugin_id}' (\`claude plugin install ${plugin_id}\`)`);
|
|
4915
|
+
} else {
|
|
4916
|
+
if (!skill_dir) {
|
|
4917
|
+
missingHints.push(
|
|
4918
|
+
`install_type=user-skill declared but no skill_dir (capabilities.yaml schema bug)`
|
|
4919
|
+
);
|
|
4920
|
+
continue;
|
|
4921
|
+
}
|
|
4922
|
+
if (installedUserSkills.has(skill_dir)) {
|
|
4923
|
+
anyDetected = true;
|
|
4924
|
+
break;
|
|
4925
|
+
}
|
|
4926
|
+
missingHints.push(
|
|
4927
|
+
`user-skill '${skill_dir}' under ~/.claude/skills/ (git clone the official repo; e.g. gstack: \`git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup\`)`
|
|
4928
|
+
);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
if (anyDetected) return { renderedCmd: cmd };
|
|
4932
|
+
const prefix = uniqueTypes.length > 1 ? "[multi]" : `[${uniqueTypes[0]}]`;
|
|
4933
|
+
const joined = missingHints.join(" OR ");
|
|
4934
|
+
return {
|
|
4935
|
+
renderedCmd: cmd,
|
|
4936
|
+
warning: `${prefix} '${cmd}' backing missing \u2014 install either: ${joined}.`
|
|
4937
|
+
};
|
|
4938
|
+
}
|
|
4939
|
+
var CAPABILITY_CMD_TEMPLATE = /\{\{\s*capabilities\.([a-zA-Z0-9_-]+)\.cmd\s*\}\}/g;
|
|
4940
|
+
function renderSkillBody(body, capabilities, installedPlugins, installedUserSkills) {
|
|
4941
|
+
const warningsSet = /* @__PURE__ */ new Set();
|
|
4942
|
+
const out = body.replace(CAPABILITY_CMD_TEMPLATE, (match2, name) => {
|
|
4943
|
+
const cap = capabilities[name];
|
|
4944
|
+
if (!cap) {
|
|
4945
|
+
warningsSet.add(
|
|
4946
|
+
`capability '${name}' referenced in SKILL.md but not defined in capabilities.yaml`
|
|
4947
|
+
);
|
|
4948
|
+
return match2;
|
|
4949
|
+
}
|
|
4950
|
+
const { renderedCmd, warning } = resolveCapabilityCmd(
|
|
4951
|
+
cap,
|
|
4952
|
+
installedPlugins,
|
|
4953
|
+
installedUserSkills
|
|
4954
|
+
);
|
|
4955
|
+
if (warning) warningsSet.add(warning);
|
|
4956
|
+
return renderedCmd;
|
|
4957
|
+
});
|
|
4958
|
+
return { body: out, warnings: [...warningsSet] };
|
|
4959
|
+
}
|
|
4857
4960
|
|
|
4858
4961
|
// src/cli/lib/enableAgentTeamsInSettings.ts
|
|
4859
4962
|
init_harnessedRoot();
|
|
@@ -5020,111 +5123,114 @@ async function atomicWrite2(path, content) {
|
|
|
5020
5123
|
return `write ${path} failed: ${err2.message}`;
|
|
5021
5124
|
}
|
|
5022
5125
|
}
|
|
5023
|
-
function
|
|
5024
|
-
const
|
|
5025
|
-
const path = join(home, ".claude", "plugins", "installed_plugins.json");
|
|
5126
|
+
async function loadRolePrompts(workflowsDir) {
|
|
5127
|
+
const path = join(workflowsDir, "role-prompts.yaml");
|
|
5026
5128
|
let raw;
|
|
5027
5129
|
try {
|
|
5028
|
-
raw =
|
|
5029
|
-
} catch {
|
|
5030
|
-
return /* @__PURE__ */ new Set();
|
|
5031
|
-
}
|
|
5032
|
-
let parsed;
|
|
5033
|
-
try {
|
|
5034
|
-
parsed = JSON.parse(raw);
|
|
5035
|
-
} catch {
|
|
5036
|
-
return /* @__PURE__ */ new Set();
|
|
5037
|
-
}
|
|
5038
|
-
if (!parsed || typeof parsed !== "object") return /* @__PURE__ */ new Set();
|
|
5039
|
-
const plugins = parsed.plugins;
|
|
5040
|
-
if (!plugins || typeof plugins !== "object") return /* @__PURE__ */ new Set();
|
|
5041
|
-
const out = /* @__PURE__ */ new Set();
|
|
5042
|
-
for (const key of Object.keys(plugins)) {
|
|
5043
|
-
const at = key.indexOf("@");
|
|
5044
|
-
if (at <= 0) continue;
|
|
5045
|
-
out.add(key.slice(0, at));
|
|
5046
|
-
}
|
|
5047
|
-
return out;
|
|
5048
|
-
}
|
|
5049
|
-
function readInstalledUserSkills(homedirOverride) {
|
|
5050
|
-
const home = homedir();
|
|
5051
|
-
const skillsRoot = join(home, ".claude", "skills");
|
|
5052
|
-
try {
|
|
5053
|
-
const entries = readdirSync(skillsRoot, { withFileTypes: true });
|
|
5054
|
-
const out = /* @__PURE__ */ new Set();
|
|
5055
|
-
for (const e of entries) if (e.isDirectory()) out.add(e.name);
|
|
5056
|
-
return out;
|
|
5130
|
+
raw = await readFile(path, "utf8");
|
|
5057
5131
|
} catch {
|
|
5058
|
-
return
|
|
5132
|
+
return {};
|
|
5059
5133
|
}
|
|
5134
|
+
const doc = parse(raw);
|
|
5135
|
+
return doc?.prompts ?? {};
|
|
5136
|
+
}
|
|
5137
|
+
function generateCommandFile(name, prompt, capabilities, installedPlugins, installedUserSkills) {
|
|
5138
|
+
const isMaster = prompt.is_master === true;
|
|
5139
|
+
const primaryCmdLine = prompt.primary_cap && capabilities[prompt.primary_cap] ? `{{ capabilities.${prompt.primary_cap}.cmd }}` : "";
|
|
5140
|
+
const checklistBlock = prompt.checklist.length ? prompt.checklist.map((item, i) => `> ${i + 1}. ${item}`).join("\n>\n") : "> (Master orchestrator \u2014 dispatches to per-sub-workflow slash commands listed below.)";
|
|
5141
|
+
const fallbackPath = isMaster ? `**Fallback path** (when no slash command from the sub-list resolves): run each missing sub-workflow inline using its own role prompt (see \`~/.claude/skills/<sub-name>/SKILL.md\` for the per-sub fallback prompt). Do NOT skip stages silently \u2014 each sub either runs or is logged as "skipped: <reason>".` : [
|
|
5142
|
+
`**Fallback path** (when the upstream isn't installed or returns no result): use the Task tool to spawn a general-purpose subagent with this prompt:`,
|
|
5143
|
+
``,
|
|
5144
|
+
`> You are a **${prompt.specialist}**.`,
|
|
5145
|
+
`>`,
|
|
5146
|
+
`> **Mission**: ${prompt.responsibility.trim().replace(/\n/g, " ")}`,
|
|
5147
|
+
`>`,
|
|
5148
|
+
`> **Default-suspect mode**: assume the change is broken / risky / incomplete until proven otherwise. Cite \`file:line\` for every finding; do not generalize.`,
|
|
5149
|
+
`>`,
|
|
5150
|
+
`> **Review checklist**:`,
|
|
5151
|
+
checklistBlock,
|
|
5152
|
+
`>`,
|
|
5153
|
+
`> **Output format**: structured report with severity-classified findings (${prompt.severity}). One finding per line: \`[severity] file:line \u2014 problem (one sentence); fix: suggested change\`. If no findings, say so explicitly. No preamble, no end-of-report summary.`,
|
|
5154
|
+
``,
|
|
5155
|
+
`(The role prompt is self-contained \u2014 works even when the upstream \`${prompt.primary_cap || "specialist"}\` user-skill / plugin isn't installed.)`
|
|
5156
|
+
].join("\n");
|
|
5157
|
+
const preferredPath = primaryCmdLine ? `**Preferred path** (when the upstream specialist is installed): use the SlashCommand tool to run \`${primaryCmdLine}\` \u2014 the upstream specialist takes over.` : `**Preferred path** (master orchestrator): dispatch to the per-sub-workflow slash commands in the order this stage prescribes. Each sub command is its own \`~/.claude/commands/<sub-name>.md\` and has its own dual-path fallback.`;
|
|
5158
|
+
const rawBody = [
|
|
5159
|
+
`# /${name}`,
|
|
5160
|
+
``,
|
|
5161
|
+
prompt.description,
|
|
5162
|
+
``,
|
|
5163
|
+
`## How to invoke`,
|
|
5164
|
+
``,
|
|
5165
|
+
preferredPath,
|
|
5166
|
+
``,
|
|
5167
|
+
fallbackPath,
|
|
5168
|
+
``,
|
|
5169
|
+
`## Notes`,
|
|
5170
|
+
``,
|
|
5171
|
+
`- This file (\`~/.claude/commands/${name}.md\`) is generated by \`harnessed setup\` from \`workflows/role-prompts.yaml\` + \`workflows/<stage>/<sub>/SKILL.md\`. To regenerate after a harnessed upgrade, re-run \`harnessed setup\`.`,
|
|
5172
|
+
`- The companion \`~/.claude/skills/${name}/SKILL.md\` is the Skill-tool entry point (Claude loads it when triggers match \`trigger_phrases:\`). Both files carry the same dual-path instruction.`,
|
|
5173
|
+
`- If your shell shows a \`\u26A0\uFE0F ... not installed\` warning from \`harnessed setup\` for this command, the upstream is missing on disk \u2014 install per the warning, OR rely on the fallback Task-spawn role prompt above (it does not require the upstream).`,
|
|
5174
|
+
``
|
|
5175
|
+
].join("\n");
|
|
5176
|
+
const { body, warnings } = renderSkillBody(
|
|
5177
|
+
rawBody,
|
|
5178
|
+
capabilities,
|
|
5179
|
+
installedPlugins,
|
|
5180
|
+
installedUserSkills
|
|
5181
|
+
);
|
|
5182
|
+
const frontmatter = ["---", `description: ${JSON.stringify(prompt.description)}`, "---", ""].join(
|
|
5183
|
+
"\n"
|
|
5184
|
+
);
|
|
5185
|
+
return { content: frontmatter + body, warnings };
|
|
5060
5186
|
}
|
|
5061
|
-
function
|
|
5062
|
-
const
|
|
5063
|
-
|
|
5064
|
-
const
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
if (installedPlugins.has(plugin_id)) {
|
|
5077
|
-
anyDetected = true;
|
|
5078
|
-
break;
|
|
5079
|
-
}
|
|
5080
|
-
missingHints.push(`plugin '${plugin_id}' (\`claude plugin install ${plugin_id}\`)`);
|
|
5081
|
-
} else {
|
|
5082
|
-
if (!skill_dir) {
|
|
5083
|
-
missingHints.push(
|
|
5084
|
-
`install_type=user-skill declared but no skill_dir (capabilities.yaml schema bug)`
|
|
5085
|
-
);
|
|
5086
|
-
continue;
|
|
5087
|
-
}
|
|
5088
|
-
if (installedUserSkills.has(skill_dir)) {
|
|
5089
|
-
anyDetected = true;
|
|
5090
|
-
break;
|
|
5091
|
-
}
|
|
5092
|
-
missingHints.push(
|
|
5093
|
-
`user-skill '${skill_dir}' under ~/.claude/skills/ (git clone the official repo; e.g. gstack: \`git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setup\`)`
|
|
5094
|
-
);
|
|
5187
|
+
async function writeAllCommands(slashNames, commandsDir, rolePrompts, capabilities, installedPlugins, installedUserSkills, writer, fileExists = existsSync) {
|
|
5188
|
+
const results = [];
|
|
5189
|
+
const aggregatedWarnings = /* @__PURE__ */ new Set();
|
|
5190
|
+
for (const name of slashNames) {
|
|
5191
|
+
const path = join(commandsDir, `${name}.md`);
|
|
5192
|
+
const prompt = rolePrompts[name];
|
|
5193
|
+
if (!prompt) {
|
|
5194
|
+
results.push({
|
|
5195
|
+
name,
|
|
5196
|
+
path,
|
|
5197
|
+
written: false,
|
|
5198
|
+
warning: `no role-prompts.yaml entry for '${name}' \u2014 skipping commands/${name}.md generation`
|
|
5199
|
+
});
|
|
5200
|
+
aggregatedWarnings.add(`role-prompts.yaml missing entry for '${name}'`);
|
|
5201
|
+
continue;
|
|
5095
5202
|
}
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
}
|
|
5105
|
-
var CAPABILITY_CMD_TEMPLATE = /\{\{\s*capabilities\.([a-zA-Z0-9_-]+)\.cmd\s*\}\}/g;
|
|
5106
|
-
function renderSkillBody(body, capabilities, installedPlugins, installedUserSkills) {
|
|
5107
|
-
const warningsSet = /* @__PURE__ */ new Set();
|
|
5108
|
-
const out = body.replace(CAPABILITY_CMD_TEMPLATE, (match2, name) => {
|
|
5109
|
-
const cap = capabilities[name];
|
|
5110
|
-
if (!cap) {
|
|
5111
|
-
warningsSet.add(
|
|
5112
|
-
`capability '${name}' referenced in SKILL.md but not defined in capabilities.yaml`
|
|
5113
|
-
);
|
|
5114
|
-
return match2;
|
|
5203
|
+
if (fileExists(path)) {
|
|
5204
|
+
results.push({
|
|
5205
|
+
name,
|
|
5206
|
+
path,
|
|
5207
|
+
written: false,
|
|
5208
|
+
warning: `commands/${name}.md already exists \u2014 leaving user file unchanged`
|
|
5209
|
+
});
|
|
5210
|
+
continue;
|
|
5115
5211
|
}
|
|
5116
|
-
const {
|
|
5117
|
-
|
|
5212
|
+
const { content, warnings } = generateCommandFile(
|
|
5213
|
+
name,
|
|
5214
|
+
prompt,
|
|
5215
|
+
capabilities,
|
|
5118
5216
|
installedPlugins,
|
|
5119
5217
|
installedUserSkills
|
|
5120
5218
|
);
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5219
|
+
try {
|
|
5220
|
+
await writer(path, content);
|
|
5221
|
+
results.push({ name, path, written: true });
|
|
5222
|
+
} catch (e) {
|
|
5223
|
+
results.push({
|
|
5224
|
+
name,
|
|
5225
|
+
path,
|
|
5226
|
+
written: false,
|
|
5227
|
+
warning: `write failed for commands/${name}.md: ${e.message}`
|
|
5228
|
+
});
|
|
5229
|
+
}
|
|
5230
|
+
for (const w of warnings) aggregatedWarnings.add(w);
|
|
5231
|
+
}
|
|
5232
|
+
return { results, warnings: [...aggregatedWarnings] };
|
|
5125
5233
|
}
|
|
5126
|
-
|
|
5127
|
-
// src/cli/lib/renderSkillTemplates.ts
|
|
5128
5234
|
async function loadCapabilities(workflowsDir) {
|
|
5129
5235
|
const path = join(workflowsDir, "capabilities.yaml");
|
|
5130
5236
|
const raw = await readFile(path, "utf8");
|
|
@@ -5431,6 +5537,46 @@ function registerSetup(program2) {
|
|
|
5431
5537
|
console.warn(` - ${w}`);
|
|
5432
5538
|
}
|
|
5433
5539
|
}
|
|
5540
|
+
const commandsBase = resolve(homedir(), ".claude", "commands");
|
|
5541
|
+
try {
|
|
5542
|
+
await mkdir(commandsBase, { recursive: true });
|
|
5543
|
+
} catch (e) {
|
|
5544
|
+
console.warn(
|
|
5545
|
+
` [A.6] could not create ${commandsBase} \u2014 skipping commands/ generation (${e.message})`
|
|
5546
|
+
);
|
|
5547
|
+
}
|
|
5548
|
+
let capabilitiesMap = {};
|
|
5549
|
+
try {
|
|
5550
|
+
capabilitiesMap = await loadCapabilities(workflowsDir);
|
|
5551
|
+
} catch (e) {
|
|
5552
|
+
console.warn(
|
|
5553
|
+
` [A.6] capabilities.yaml unreadable \u2014 skipping commands/ generation (${e.message})`
|
|
5554
|
+
);
|
|
5555
|
+
}
|
|
5556
|
+
const rolePrompts = await loadRolePrompts(workflowsDir);
|
|
5557
|
+
const installedPlugins = readInstalledPlugins();
|
|
5558
|
+
const installedUserSkills = readInstalledUserSkills();
|
|
5559
|
+
const cmdResult = await writeAllCommands(
|
|
5560
|
+
skillNames,
|
|
5561
|
+
commandsBase,
|
|
5562
|
+
rolePrompts,
|
|
5563
|
+
capabilitiesMap,
|
|
5564
|
+
installedPlugins,
|
|
5565
|
+
installedUserSkills,
|
|
5566
|
+
async (p4, c) => writeFile(p4, c, "utf8")
|
|
5567
|
+
);
|
|
5568
|
+
const writtenCount = cmdResult.results.filter((r) => r.written).length;
|
|
5569
|
+
const skippedCount = cmdResult.results.filter((r) => !r.written && r.warning).length;
|
|
5570
|
+
console.log(
|
|
5571
|
+
` [A.6] generated ${writtenCount} commands/<x>.md file(s) (${skippedCount} skipped \u2014 existing user file or schema warn)`
|
|
5572
|
+
);
|
|
5573
|
+
for (const r of cmdResult.results) {
|
|
5574
|
+
if (r.written) {
|
|
5575
|
+
console.log(` [A.6] wrote /${r.name} \u2192 ${r.path}`);
|
|
5576
|
+
} else if (r.warning) {
|
|
5577
|
+
console.warn(` [A.6] skipped /${r.name}: ${r.warning}`);
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5434
5580
|
const cResult = await enableAgentTeamsInSettings();
|
|
5435
5581
|
if (cResult.status === "created") {
|
|
5436
5582
|
console.log(t("setup.step_c.created", { path: cResult.path }));
|