harnessed 4.7.0 → 4.8.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/dist/cli.mjs +174 -81
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/messages/zh-Hans.json +16 -2
- package/package.json +1 -1
- package/workflows/auto/SKILL.zh-Hans.md +129 -0
- package/workflows/disciplines/doc-discipline.zh-Hans.yaml +49 -0
- package/workflows/disciplines/karpathy.yaml +5 -5
- package/workflows/disciplines/karpathy.zh-Hans.yaml +47 -0
- package/workflows/disciplines/operational.yaml +6 -6
- package/workflows/disciplines/operational.zh-Hans.yaml +79 -0
- package/workflows/disciplines/output-style.yaml +7 -7
- package/workflows/disciplines/output-style.zh-Hans.yaml +62 -0
- package/workflows/disciplines/priority.yaml +2 -2
- package/workflows/disciplines/priority.zh-Hans.yaml +28 -0
- package/workflows/discuss/auto/SKILL.zh-Hans.md +75 -0
- package/workflows/discuss/phase/SKILL.zh-Hans.md +73 -0
- package/workflows/discuss/strategic/SKILL.zh-Hans.md +78 -0
- package/workflows/discuss/subtask/SKILL.zh-Hans.md +79 -0
- package/workflows/plan/architecture/SKILL.zh-Hans.md +74 -0
- package/workflows/plan/auto/SKILL.zh-Hans.md +75 -0
- package/workflows/plan/phase/SKILL.zh-Hans.md +76 -0
- package/workflows/research/SKILL.zh-Hans.md +81 -0
- package/workflows/retro/SKILL.zh-Hans.md +71 -0
- package/workflows/role-prompts.zh-Hans.yaml +501 -0
- package/workflows/ship/auto/SKILL.zh-Hans.md +46 -0
- package/workflows/ship/preflight/SKILL.zh-Hans.md +38 -0
- package/workflows/task/auto/SKILL.zh-Hans.md +80 -0
- package/workflows/task/clarify/SKILL.zh-Hans.md +79 -0
- package/workflows/task/code/SKILL.zh-Hans.md +85 -0
- package/workflows/task/deliver/SKILL.zh-Hans.md +113 -0
- package/workflows/task/test/SKILL.zh-Hans.md +90 -0
- package/workflows/verify/auto/SKILL.zh-Hans.md +89 -0
- package/workflows/verify/code-review/SKILL.zh-Hans.md +71 -0
- package/workflows/verify/design/SKILL.zh-Hans.md +74 -0
- package/workflows/verify/multispec/SKILL.zh-Hans.md +88 -0
- package/workflows/verify/paranoid/SKILL.zh-Hans.md +74 -0
- package/workflows/verify/progress/SKILL.zh-Hans.md +69 -0
- package/workflows/verify/qa/SKILL.zh-Hans.md +76 -0
- package/workflows/verify/security/SKILL.zh-Hans.md +70 -0
- package/workflows/verify/simplify/SKILL.zh-Hans.md +70 -0
package/dist/cli.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import * as ajvFormatsNs from 'ajv-formats';
|
|
|
6
6
|
import { execFileSync, spawnSync, spawn, exec, execFile, execSync } from 'child_process';
|
|
7
7
|
import { existsSync, mkdirSync, renameSync, writeFileSync, readFileSync, readdirSync } from 'fs';
|
|
8
8
|
import { join, dirname, resolve, sep, relative } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
9
10
|
import { homedir } from 'os';
|
|
10
11
|
import { createHash } from 'crypto';
|
|
11
12
|
import { readFile, readdir, unlink, writeFile, stat, rm, cp, mkdir, rename, appendFile, access } from 'fs/promises';
|
|
@@ -13,7 +14,6 @@ import { Value } from '@sinclair/typebox/value';
|
|
|
13
14
|
import lockfile from 'proper-lockfile';
|
|
14
15
|
import { Parser } from 'expr-eval';
|
|
15
16
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
16
|
-
import { fileURLToPath } from 'url';
|
|
17
17
|
import { promisify } from 'util';
|
|
18
18
|
import * as p from '@clack/prompts';
|
|
19
19
|
import { createPatch } from 'diff';
|
|
@@ -38,7 +38,7 @@ var init_package = __esm({
|
|
|
38
38
|
"package.json"() {
|
|
39
39
|
package_default = {
|
|
40
40
|
name: "harnessed",
|
|
41
|
-
version: "4.
|
|
41
|
+
version: "4.8.0",
|
|
42
42
|
description: "AI coding harness package manager + composition orchestrator",
|
|
43
43
|
type: "module",
|
|
44
44
|
license: "Apache-2.0",
|
|
@@ -852,6 +852,76 @@ var init_origin_check = __esm({
|
|
|
852
852
|
"src/cli/lib/origin-check.ts"() {
|
|
853
853
|
}
|
|
854
854
|
});
|
|
855
|
+
function mapToSupported(raw) {
|
|
856
|
+
if (!raw) return "en";
|
|
857
|
+
if (/^zh([^a-z]|$)/i.test(raw)) return "zh-Hans";
|
|
858
|
+
return "en";
|
|
859
|
+
}
|
|
860
|
+
function detectLocale() {
|
|
861
|
+
const raw = process.env.HARNESSED_LANG || process.env.LC_ALL || process.env.LANG || process.env.LANGUAGE || safeIntlLocale();
|
|
862
|
+
return mapToSupported(raw);
|
|
863
|
+
}
|
|
864
|
+
function safeIntlLocale() {
|
|
865
|
+
try {
|
|
866
|
+
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
867
|
+
} catch {
|
|
868
|
+
return void 0;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
function messagesDir() {
|
|
872
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
873
|
+
const candidates = [resolve(here, "..", "..", "messages"), resolve(here, "..", "messages")];
|
|
874
|
+
for (const c of candidates) {
|
|
875
|
+
try {
|
|
876
|
+
readFileSync(join(c, "en.json"), "utf8");
|
|
877
|
+
return c;
|
|
878
|
+
} catch {
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return resolve(process.cwd(), "messages");
|
|
882
|
+
}
|
|
883
|
+
function loadLocale(locale) {
|
|
884
|
+
if (cache[locale]) return cache[locale];
|
|
885
|
+
const path = join(messagesDir(), `${locale}.json`);
|
|
886
|
+
try {
|
|
887
|
+
const raw = readFileSync(path, "utf8");
|
|
888
|
+
cache[locale] = JSON.parse(raw);
|
|
889
|
+
} catch {
|
|
890
|
+
cache[locale] = {};
|
|
891
|
+
}
|
|
892
|
+
return cache[locale];
|
|
893
|
+
}
|
|
894
|
+
function setLocale(locale) {
|
|
895
|
+
if (!locale) return;
|
|
896
|
+
const mapped = mapToSupported(locale);
|
|
897
|
+
if (SUPPORTED.has(mapped)) currentLocale = mapped;
|
|
898
|
+
}
|
|
899
|
+
function getLocale() {
|
|
900
|
+
if (currentLocale === null) currentLocale = detectLocale();
|
|
901
|
+
return currentLocale;
|
|
902
|
+
}
|
|
903
|
+
function t(key, params) {
|
|
904
|
+
const locale = getLocale();
|
|
905
|
+
const primary = loadLocale(locale);
|
|
906
|
+
let template = primary[key];
|
|
907
|
+
if (template === void 0 && locale !== "en") {
|
|
908
|
+
template = loadLocale("en")[key];
|
|
909
|
+
}
|
|
910
|
+
if (template === void 0) template = key;
|
|
911
|
+
if (!params) return template;
|
|
912
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_match, name) => {
|
|
913
|
+
const v = params[name];
|
|
914
|
+
return v === void 0 ? `{{${name}}}` : String(v);
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
var SUPPORTED, currentLocale, cache;
|
|
918
|
+
var init_i18n = __esm({
|
|
919
|
+
"src/i18n/index.ts"() {
|
|
920
|
+
SUPPORTED = /* @__PURE__ */ new Set(["en", "zh-Hans"]);
|
|
921
|
+
currentLocale = null;
|
|
922
|
+
cache = {};
|
|
923
|
+
}
|
|
924
|
+
});
|
|
855
925
|
function claudeDescriptor(home = homedir()) {
|
|
856
926
|
const claudeHome = join(home, ".claude");
|
|
857
927
|
return {
|
|
@@ -1978,8 +2048,20 @@ var init_loadPhases = __esm({
|
|
|
1978
2048
|
};
|
|
1979
2049
|
}
|
|
1980
2050
|
});
|
|
1981
|
-
|
|
1982
|
-
|
|
2051
|
+
function resolveLocaleYaml(dir, baseName, locale = getLocale()) {
|
|
2052
|
+
if (locale !== "en") {
|
|
2053
|
+
const sibling = join(dir, `${baseName}.${locale}.yaml`);
|
|
2054
|
+
if (existsSync(sibling)) return sibling;
|
|
2055
|
+
}
|
|
2056
|
+
return join(dir, `${baseName}.yaml`);
|
|
2057
|
+
}
|
|
2058
|
+
var init_localeYaml = __esm({
|
|
2059
|
+
"src/i18n/localeYaml.ts"() {
|
|
2060
|
+
init_i18n();
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
async function loadRolePrompts(workflowsDir, locale = getLocale()) {
|
|
2064
|
+
const path = resolveLocaleYaml(workflowsDir, "role-prompts", locale);
|
|
1983
2065
|
let raw;
|
|
1984
2066
|
try {
|
|
1985
2067
|
raw = await readFile(path, "utf8");
|
|
@@ -2193,6 +2275,8 @@ async function writeAllCommands(slashNames, commandsDir, rolePrompts, capabiliti
|
|
|
2193
2275
|
var INTERACTIVE_COMMANDS, ORCHESTRATOR_COMMANDS, MARKER, LANG_DIRECTIVE, HARNESSED_MARKER_RX, V3_4_3_SIGNATURE_SUB_RX, V3_4_3_SIGNATURE_MASTER_RX;
|
|
2194
2276
|
var init_generateCommands = __esm({
|
|
2195
2277
|
"src/cli/lib/generateCommands.ts"() {
|
|
2278
|
+
init_i18n();
|
|
2279
|
+
init_localeYaml();
|
|
2196
2280
|
INTERACTIVE_COMMANDS = /* @__PURE__ */ new Set([
|
|
2197
2281
|
"discuss",
|
|
2198
2282
|
"discuss-strategic",
|
|
@@ -6875,73 +6959,9 @@ audited ${yamls.length} manifest${yamls.length === 1 ? "" : "s"} \u2014 ${findin
|
|
|
6875
6959
|
process.exit(errorCount > 0 ? 1 : 0);
|
|
6876
6960
|
});
|
|
6877
6961
|
}
|
|
6878
|
-
var SUPPORTED = /* @__PURE__ */ new Set(["en", "zh-Hans"]);
|
|
6879
|
-
var currentLocale = null;
|
|
6880
|
-
var cache = {};
|
|
6881
|
-
function mapToSupported(raw) {
|
|
6882
|
-
if (!raw) return "en";
|
|
6883
|
-
if (/^zh([^a-z]|$)/i.test(raw)) return "zh-Hans";
|
|
6884
|
-
return "en";
|
|
6885
|
-
}
|
|
6886
|
-
function detectLocale() {
|
|
6887
|
-
const raw = process.env.HARNESSED_LANG || process.env.LC_ALL || process.env.LANG || process.env.LANGUAGE || safeIntlLocale();
|
|
6888
|
-
return mapToSupported(raw);
|
|
6889
|
-
}
|
|
6890
|
-
function safeIntlLocale() {
|
|
6891
|
-
try {
|
|
6892
|
-
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
6893
|
-
} catch {
|
|
6894
|
-
return void 0;
|
|
6895
|
-
}
|
|
6896
|
-
}
|
|
6897
|
-
function messagesDir() {
|
|
6898
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
6899
|
-
const candidates = [resolve(here, "..", "..", "messages"), resolve(here, "..", "messages")];
|
|
6900
|
-
for (const c of candidates) {
|
|
6901
|
-
try {
|
|
6902
|
-
readFileSync(join(c, "en.json"), "utf8");
|
|
6903
|
-
return c;
|
|
6904
|
-
} catch {
|
|
6905
|
-
}
|
|
6906
|
-
}
|
|
6907
|
-
return resolve(process.cwd(), "messages");
|
|
6908
|
-
}
|
|
6909
|
-
function loadLocale(locale) {
|
|
6910
|
-
if (cache[locale]) return cache[locale];
|
|
6911
|
-
const path = join(messagesDir(), `${locale}.json`);
|
|
6912
|
-
try {
|
|
6913
|
-
const raw = readFileSync(path, "utf8");
|
|
6914
|
-
cache[locale] = JSON.parse(raw);
|
|
6915
|
-
} catch {
|
|
6916
|
-
cache[locale] = {};
|
|
6917
|
-
}
|
|
6918
|
-
return cache[locale];
|
|
6919
|
-
}
|
|
6920
|
-
function setLocale(locale) {
|
|
6921
|
-
if (!locale) return;
|
|
6922
|
-
const mapped = mapToSupported(locale);
|
|
6923
|
-
if (SUPPORTED.has(mapped)) currentLocale = mapped;
|
|
6924
|
-
}
|
|
6925
|
-
function getLocale() {
|
|
6926
|
-
if (currentLocale === null) currentLocale = detectLocale();
|
|
6927
|
-
return currentLocale;
|
|
6928
|
-
}
|
|
6929
|
-
function t(key, params) {
|
|
6930
|
-
const locale = getLocale();
|
|
6931
|
-
const primary = loadLocale(locale);
|
|
6932
|
-
let template = primary[key];
|
|
6933
|
-
if (template === void 0 && locale !== "en") {
|
|
6934
|
-
template = loadLocale("en")[key];
|
|
6935
|
-
}
|
|
6936
|
-
if (template === void 0) template = key;
|
|
6937
|
-
if (!params) return template;
|
|
6938
|
-
return template.replace(/\{\{(\w+)\}\}/g, (_match, name) => {
|
|
6939
|
-
const v = params[name];
|
|
6940
|
-
return v === void 0 ? `{{${name}}}` : String(v);
|
|
6941
|
-
});
|
|
6942
|
-
}
|
|
6943
6962
|
|
|
6944
6963
|
// src/cli/audit-log.ts
|
|
6964
|
+
init_i18n();
|
|
6945
6965
|
init_harnessedRoot();
|
|
6946
6966
|
function auditPath() {
|
|
6947
6967
|
return harnessedFile("audit.log");
|
|
@@ -7048,6 +7068,9 @@ function registerAuditLog(program2) {
|
|
|
7048
7068
|
}
|
|
7049
7069
|
);
|
|
7050
7070
|
}
|
|
7071
|
+
|
|
7072
|
+
// src/cli/backup-list.ts
|
|
7073
|
+
init_i18n();
|
|
7051
7074
|
init_backup();
|
|
7052
7075
|
function registerBackupList(program2) {
|
|
7053
7076
|
const backup2 = program2.command("backup").description("Backup snapshot operations");
|
|
@@ -7283,6 +7306,7 @@ function registerCompact(program2) {
|
|
|
7283
7306
|
}
|
|
7284
7307
|
|
|
7285
7308
|
// src/cli/doctor.ts
|
|
7309
|
+
init_i18n();
|
|
7286
7310
|
init_doctor_registry();
|
|
7287
7311
|
function registerDoctor(program2) {
|
|
7288
7312
|
program2.command("doctor").description(
|
|
@@ -7439,6 +7463,9 @@ function fireEntry(clause, master) {
|
|
|
7439
7463
|
if (isMaster) entry.is_master = true;
|
|
7440
7464
|
return entry;
|
|
7441
7465
|
}
|
|
7466
|
+
|
|
7467
|
+
// src/cli/gc.ts
|
|
7468
|
+
init_i18n();
|
|
7442
7469
|
init_backup();
|
|
7443
7470
|
var DURATION_RE = /^(\d+)([dhmw])$/;
|
|
7444
7471
|
function parseDuration(s) {
|
|
@@ -7529,6 +7556,7 @@ ${t("gc.invalid_duration.fix")}`
|
|
|
7529
7556
|
|
|
7530
7557
|
// src/cli/install.ts
|
|
7531
7558
|
init_package();
|
|
7559
|
+
init_i18n();
|
|
7532
7560
|
init_installers();
|
|
7533
7561
|
init_path_guard();
|
|
7534
7562
|
init_validate();
|
|
@@ -7631,12 +7659,14 @@ function registerLearn(program2) {
|
|
|
7631
7659
|
|
|
7632
7660
|
// src/cli/lib/here.ts
|
|
7633
7661
|
init_nextStep();
|
|
7662
|
+
init_i18n();
|
|
7634
7663
|
init_harnessedRoot();
|
|
7635
7664
|
|
|
7636
7665
|
// src/cli/status.ts
|
|
7637
7666
|
init_evidence();
|
|
7638
7667
|
init_ledger();
|
|
7639
7668
|
init_state();
|
|
7669
|
+
init_i18n();
|
|
7640
7670
|
init_harnessedRoot();
|
|
7641
7671
|
init_state2();
|
|
7642
7672
|
function statusMarker(status) {
|
|
@@ -7803,6 +7833,9 @@ async function runHere(opts) {
|
|
|
7803
7833
|
}
|
|
7804
7834
|
process.exit(0);
|
|
7805
7835
|
}
|
|
7836
|
+
|
|
7837
|
+
// src/cli/manifest-add.ts
|
|
7838
|
+
init_i18n();
|
|
7806
7839
|
var QA = [
|
|
7807
7840
|
{ q: "\u2460 \u662F\u771F reusable surface \u8FD8\u662F\u4E34\u65F6 wrapper?", f: "q1_reusable_surface" },
|
|
7808
7841
|
{ q: "\u2461 \u4E0A\u6E38\u540D\u5B57 fit \u9879\u76EE shape \u5417? \u6709\u73B0\u6709\u547D\u540D\u51B2\u7A81\u5417?", f: "q2_name_fit" },
|
|
@@ -7874,6 +7907,8 @@ function registerNext(program2) {
|
|
|
7874
7907
|
}
|
|
7875
7908
|
|
|
7876
7909
|
// src/cli/prompt.ts
|
|
7910
|
+
init_i18n();
|
|
7911
|
+
init_localeYaml();
|
|
7877
7912
|
init_run();
|
|
7878
7913
|
init_generateCommands();
|
|
7879
7914
|
init_packagePath();
|
|
@@ -7919,16 +7954,17 @@ ${lines.join("\n")}
|
|
|
7919
7954
|
return "";
|
|
7920
7955
|
}
|
|
7921
7956
|
}
|
|
7922
|
-
async function buildDisciplinesSection(sub, packageRoot) {
|
|
7957
|
+
async function buildDisciplinesSection(sub, packageRoot, locale = getLocale()) {
|
|
7923
7958
|
try {
|
|
7924
7959
|
const workflowsDir = resolve(packageRoot, "workflows");
|
|
7960
|
+
const disciplinesDir = resolve(workflowsDir, "disciplines");
|
|
7925
7961
|
const applied = await loadSubArrayField(sub, packageRoot, "disciplines_applied");
|
|
7926
7962
|
const names = applied.filter((d) => d !== "language");
|
|
7927
7963
|
if (names.length === 0) return "";
|
|
7928
7964
|
const blocks = [];
|
|
7929
7965
|
for (const name of names) {
|
|
7930
7966
|
try {
|
|
7931
|
-
const dRaw = await readFile(
|
|
7967
|
+
const dRaw = await readFile(resolveLocaleYaml(disciplinesDir, name, locale), "utf8");
|
|
7932
7968
|
const dDoc = parse(dRaw);
|
|
7933
7969
|
const rules = Array.isArray(dDoc?.rules) ? dDoc.rules : [];
|
|
7934
7970
|
const descs = rules.map((r) => typeof r.description === "string" ? r.description.trim() : "").filter((s) => s.length > 0).map((s) => ` - ${s.replace(/\s+/g, " ")}`);
|
|
@@ -8074,6 +8110,9 @@ function registerReleasePreflight(program2) {
|
|
|
8074
8110
|
process.exit(failed ? 1 : 0);
|
|
8075
8111
|
});
|
|
8076
8112
|
}
|
|
8113
|
+
|
|
8114
|
+
// src/cli/research.ts
|
|
8115
|
+
init_i18n();
|
|
8077
8116
|
init_run();
|
|
8078
8117
|
init_packagePath();
|
|
8079
8118
|
init_run2();
|
|
@@ -8115,6 +8154,7 @@ function registerResearch(program2) {
|
|
|
8115
8154
|
}
|
|
8116
8155
|
|
|
8117
8156
|
// src/cli/resume.ts
|
|
8157
|
+
init_i18n();
|
|
8118
8158
|
function registerResume(program2) {
|
|
8119
8159
|
program2.command("resume").description(
|
|
8120
8160
|
"Reload checkpoint from paused workflow + print resume hint (D-03 \u2014 user invokes phase command manually)"
|
|
@@ -8179,6 +8219,9 @@ function registerRetro(program2) {
|
|
|
8179
8219
|
process.exit(0);
|
|
8180
8220
|
});
|
|
8181
8221
|
}
|
|
8222
|
+
|
|
8223
|
+
// src/cli/rollback.ts
|
|
8224
|
+
init_i18n();
|
|
8182
8225
|
init_backup();
|
|
8183
8226
|
function normalizeEol(buf, eol) {
|
|
8184
8227
|
const lf = buf.toString("utf8").replace(/\r\n/g, "\n");
|
|
@@ -8250,6 +8293,9 @@ ${t("rollback.metadata_unreadable.fix")}`
|
|
|
8250
8293
|
|
|
8251
8294
|
// src/cli.ts
|
|
8252
8295
|
init_run2();
|
|
8296
|
+
|
|
8297
|
+
// src/cli/setup.ts
|
|
8298
|
+
init_i18n();
|
|
8253
8299
|
init_platform();
|
|
8254
8300
|
|
|
8255
8301
|
// src/cli/lib/capabilityResolver.ts
|
|
@@ -8504,42 +8550,78 @@ async function enableUserLangInSettings(override) {
|
|
|
8504
8550
|
// src/cli/setup.ts
|
|
8505
8551
|
init_generateCommands();
|
|
8506
8552
|
init_packagePath();
|
|
8553
|
+
|
|
8554
|
+
// src/cli/lib/renderSkillTemplates.ts
|
|
8555
|
+
init_i18n();
|
|
8556
|
+
|
|
8557
|
+
// src/cli/lib/resolveSkillBody.ts
|
|
8558
|
+
init_i18n();
|
|
8559
|
+
function skillBodyFilename(locale) {
|
|
8560
|
+
return locale === "en" ? "SKILL.md" : `SKILL.${locale}.md`;
|
|
8561
|
+
}
|
|
8562
|
+
function resolveSkillBodyFilename(skillDir, locale) {
|
|
8563
|
+
const resolved = locale ?? getLocale();
|
|
8564
|
+
const candidate = skillBodyFilename(resolved);
|
|
8565
|
+
if (candidate === "SKILL.md") return "SKILL.md";
|
|
8566
|
+
return existsSync(join(skillDir, candidate)) ? candidate : "SKILL.md";
|
|
8567
|
+
}
|
|
8568
|
+
|
|
8569
|
+
// src/cli/lib/renderSkillTemplates.ts
|
|
8570
|
+
var LOCALE_SIBLINGS = ["zh-Hans"];
|
|
8507
8571
|
async function loadCapabilities(workflowsDir) {
|
|
8508
8572
|
const path = join(workflowsDir, "capabilities.yaml");
|
|
8509
8573
|
const raw = await readFile(path, "utf8");
|
|
8510
8574
|
const doc = parse(raw);
|
|
8511
8575
|
return doc?.capabilities ?? {};
|
|
8512
8576
|
}
|
|
8513
|
-
async function renderSkillFile(skillName, skillsBase, capabilities, installedPlugins, installedUserSkills) {
|
|
8514
|
-
const
|
|
8577
|
+
async function renderSkillFile(skillName, skillsBase, capabilities, installedPlugins, installedUserSkills, locale) {
|
|
8578
|
+
const dir = join(skillsBase, skillName);
|
|
8579
|
+
const resolved = locale ?? getLocale();
|
|
8580
|
+
const srcName = resolveSkillBodyFilename(dir, resolved);
|
|
8581
|
+
const srcPath = join(dir, srcName);
|
|
8582
|
+
const destPath = join(dir, "SKILL.md");
|
|
8515
8583
|
const result = {
|
|
8516
8584
|
name: skillName,
|
|
8517
|
-
skillPath,
|
|
8585
|
+
skillPath: destPath,
|
|
8518
8586
|
rendered: false,
|
|
8519
8587
|
warnings: []
|
|
8520
8588
|
};
|
|
8521
8589
|
let body;
|
|
8522
8590
|
try {
|
|
8523
|
-
body = await readFile(
|
|
8591
|
+
body = await readFile(srcPath, "utf8");
|
|
8524
8592
|
} catch (e) {
|
|
8525
8593
|
result.error = `read failed: ${e.message}`;
|
|
8526
8594
|
return result;
|
|
8527
8595
|
}
|
|
8528
8596
|
const rendered = renderSkillBody(body, capabilities, installedPlugins, installedUserSkills);
|
|
8529
|
-
|
|
8597
|
+
const localeBodySelected = srcName !== "SKILL.md";
|
|
8598
|
+
const needsWrite = localeBodySelected || rendered.body !== body;
|
|
8599
|
+
if (!needsWrite) {
|
|
8530
8600
|
result.warnings = rendered.warnings;
|
|
8531
8601
|
return result;
|
|
8532
8602
|
}
|
|
8533
8603
|
try {
|
|
8534
|
-
await writeFile(
|
|
8535
|
-
result.rendered =
|
|
8604
|
+
await writeFile(destPath, rendered.body, "utf8");
|
|
8605
|
+
result.rendered = rendered.body !== body;
|
|
8536
8606
|
result.warnings = rendered.warnings;
|
|
8537
8607
|
} catch (e) {
|
|
8538
8608
|
result.error = `write failed: ${e.message}`;
|
|
8609
|
+
return result;
|
|
8610
|
+
}
|
|
8611
|
+
if (localeBodySelected) {
|
|
8612
|
+
for (const loc of LOCALE_SIBLINGS) {
|
|
8613
|
+
const sibling = skillBodyFilename(loc);
|
|
8614
|
+
if (sibling === "SKILL.md") continue;
|
|
8615
|
+
try {
|
|
8616
|
+
await rm(join(dir, sibling), { force: true });
|
|
8617
|
+
} catch {
|
|
8618
|
+
}
|
|
8619
|
+
}
|
|
8539
8620
|
}
|
|
8540
8621
|
return result;
|
|
8541
8622
|
}
|
|
8542
|
-
async function renderAllSkills(skillNames, skillsBase, workflowsDir, homedirOverride) {
|
|
8623
|
+
async function renderAllSkills(skillNames, skillsBase, workflowsDir, homedirOverride, locale) {
|
|
8624
|
+
const resolvedLocale = locale ?? getLocale();
|
|
8543
8625
|
let capabilities = {};
|
|
8544
8626
|
try {
|
|
8545
8627
|
capabilities = await loadCapabilities(workflowsDir);
|
|
@@ -8567,7 +8649,8 @@ async function renderAllSkills(skillNames, skillsBase, workflowsDir, homedirOver
|
|
|
8567
8649
|
skillsBase,
|
|
8568
8650
|
capabilities,
|
|
8569
8651
|
installedPlugins,
|
|
8570
|
-
installedUserSkills
|
|
8652
|
+
installedUserSkills,
|
|
8653
|
+
resolvedLocale
|
|
8571
8654
|
);
|
|
8572
8655
|
results.push(r);
|
|
8573
8656
|
for (const w of r.warnings) warningSet.add(w);
|
|
@@ -8835,7 +8918,13 @@ function registerSetup(program2) {
|
|
|
8835
8918
|
}
|
|
8836
8919
|
console.log(t("setup.step_a_complete", { count: skillsInstalled, path: skillsBase }));
|
|
8837
8920
|
const skillNames = toInstall.map((wf) => wf.name);
|
|
8838
|
-
const rendered = await renderAllSkills(
|
|
8921
|
+
const rendered = await renderAllSkills(
|
|
8922
|
+
skillNames,
|
|
8923
|
+
skillsBase,
|
|
8924
|
+
workflowsDir,
|
|
8925
|
+
void 0,
|
|
8926
|
+
getLocale()
|
|
8927
|
+
);
|
|
8839
8928
|
if (rendered.aggregatedWarnings.length > 0) {
|
|
8840
8929
|
console.warn(t("setup.step_a_render.warnings_header"));
|
|
8841
8930
|
for (const w of rendered.aggregatedWarnings) {
|
|
@@ -8937,6 +9026,9 @@ Force-update pass complete: ${b2.installed.length} installed / ${b2.alreadyInsta
|
|
|
8937
9026
|
process.exit(0);
|
|
8938
9027
|
});
|
|
8939
9028
|
}
|
|
9029
|
+
|
|
9030
|
+
// src/cli/uninstall.ts
|
|
9031
|
+
init_i18n();
|
|
8940
9032
|
init_harnessedRoot();
|
|
8941
9033
|
init_path_guard();
|
|
8942
9034
|
init_validate();
|
|
@@ -9513,6 +9605,7 @@ function registerWorkflows(program2) {
|
|
|
9513
9605
|
}
|
|
9514
9606
|
|
|
9515
9607
|
// src/cli.ts
|
|
9608
|
+
init_i18n();
|
|
9516
9609
|
init_harnessedRoot();
|
|
9517
9610
|
migrateLegacyHarnessedRoot();
|
|
9518
9611
|
var argv = process.argv;
|