harnessed 2.0.1 → 3.0.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/README.md +263 -28
- package/dist/cli.mjs +367 -76
- 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/capabilities.yaml +468 -0
- package/workflows/defaults.yaml +71 -4
- package/workflows/disciplines/karpathy.yaml +47 -0
- package/workflows/disciplines/language.yaml +38 -0
- package/workflows/disciplines/operational.yaml +61 -0
- package/workflows/disciplines/output-style.yaml +62 -0
- package/workflows/disciplines/priority.yaml +28 -0
- package/workflows/disciplines/protocols.yaml +70 -0
- package/workflows/discuss/auto/.gitkeep +0 -0
- package/workflows/discuss/auto/SKILL.md +63 -0
- package/workflows/discuss/auto/workflow.yaml +40 -0
- package/workflows/discuss/phase/SKILL.md +61 -0
- package/workflows/discuss/phase/workflow.yaml +35 -0
- package/workflows/discuss/strategic/SKILL.md +66 -0
- package/workflows/discuss/strategic/workflow.yaml +47 -0
- package/workflows/discuss/subtask/SKILL.md +67 -0
- package/workflows/discuss/subtask/workflow.yaml +33 -0
- package/workflows/judgments/stage-routing.yaml +93 -0
- package/workflows/judgments/web-design-routing.yaml +37 -0
- package/workflows/judgments/web-search-routing.yaml +52 -0
- package/workflows/judgments/web-testing-routing.yaml +50 -0
- package/workflows/plan/architecture/SKILL.md +62 -0
- package/workflows/plan/architecture/workflow.yaml +33 -0
- package/workflows/plan/auto/.gitkeep +0 -0
- package/workflows/plan/auto/SKILL.md +63 -0
- package/workflows/plan/auto/workflow.yaml +41 -0
- package/workflows/plan/phase/SKILL.md +64 -0
- package/workflows/plan/phase/workflow.yaml +37 -0
- package/workflows/research/SKILL.md +6 -2
- package/workflows/research/workflow.yaml +34 -3
- package/workflows/retro/SKILL.md +68 -0
- package/workflows/retro/workflow.yaml +40 -0
- package/workflows/task/auto/.gitkeep +0 -0
- package/workflows/task/auto/SKILL.md +68 -0
- package/workflows/task/auto/workflow.yaml +57 -0
- package/workflows/task/clarify/SKILL.md +83 -0
- package/workflows/task/clarify/workflow.yaml +39 -0
- package/workflows/task/code/SKILL.md +89 -0
- package/workflows/task/code/workflow.yaml +55 -0
- package/workflows/task/deliver/SKILL.md +118 -0
- package/workflows/task/deliver/workflow.yaml +77 -0
- package/workflows/task/test/SKILL.md +93 -0
- package/workflows/task/test/workflow.yaml +44 -0
- package/workflows/verify/auto/.gitkeep +0 -0
- package/workflows/verify/auto/SKILL.md +77 -0
- package/workflows/verify/auto/workflow.yaml +74 -0
- package/workflows/verify/code-review/SKILL.md +69 -0
- package/workflows/verify/code-review/workflow.yaml +32 -0
- package/workflows/verify/design/SKILL.md +72 -0
- package/workflows/verify/design/workflow.yaml +33 -0
- package/workflows/verify/multispec/SKILL.md +86 -0
- package/workflows/verify/multispec/workflow.yaml +58 -0
- package/workflows/verify/paranoid/SKILL.md +71 -0
- package/workflows/verify/paranoid/workflow.yaml +30 -0
- package/workflows/verify/progress/SKILL.md +67 -0
- package/workflows/verify/progress/workflow.yaml +44 -0
- package/workflows/verify/qa/SKILL.md +73 -0
- package/workflows/verify/qa/workflow.yaml +31 -0
- package/workflows/verify/security/SKILL.md +67 -0
- package/workflows/verify/security/workflow.yaml +31 -0
- package/workflows/verify/simplify/SKILL.md +67 -0
- package/workflows/verify/simplify/workflow.yaml +31 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync, spawn } from 'child_process';
|
|
2
|
+
import { execSync, spawnSync, spawn } from 'child_process';
|
|
3
3
|
import { writeFileSync, existsSync, readFileSync, mkdirSync, appendFileSync, readdirSync } from 'fs';
|
|
4
4
|
import { resolve, join, dirname, relative } from 'path';
|
|
5
5
|
import { Type } from '@sinclair/typebox';
|
|
@@ -169,17 +169,21 @@ var init_schemaVersion = __esm({
|
|
|
169
169
|
governance: "harnessed.governance.v1",
|
|
170
170
|
// ← Phase 3.2 W1 T1.1 ADD 10th surface (D-04 PUSH veto status)
|
|
171
171
|
planFeature: "harnessed.plan-feature.v1",
|
|
172
|
-
// ← Phase 3.3 W0 T0.5 BACKFILL 11th surface
|
|
172
|
+
// ← Phase 3.3 W0 T0.5 BACKFILL 11th surface
|
|
173
173
|
aliases: "harnessed.aliases.v1",
|
|
174
|
-
// ← Phase 3.3 W1 T1.1 ADD 12th surface (D-01 RICH
|
|
174
|
+
// ← Phase 3.3 W1 T1.1 ADD 12th surface (D-01 RICH)
|
|
175
175
|
knownGood: "harnessed.known-good.v1",
|
|
176
|
-
// ← Phase 3.3 W1 T1.1 ADD 13th surface (D-03 YAML
|
|
176
|
+
// ← Phase 3.3 W1 T1.1 ADD 13th surface (D-03 YAML manifest)
|
|
177
177
|
capabilities: "harnessed.capabilities.v1",
|
|
178
|
-
// ← Phase v2.0-2.3 W0
|
|
178
|
+
// ← Phase v2.0-2.3 W0 ADD 14th surface (R20.2 flat yaml capabilities manifest validate)
|
|
179
179
|
judgment: "harnessed.judgment.v1",
|
|
180
|
-
// ← Phase v2.0-2.3 W0
|
|
181
|
-
workflow: "harnessed.workflow.v2"
|
|
182
|
-
// ← Phase v2.0-2.4 W0 T2.4.W0.1 ADD 16th surface (R20.1
|
|
180
|
+
// ← Phase v2.0-2.3 W0 ADD 15th surface (R20.4 multi-file judgments validate)
|
|
181
|
+
workflow: "harnessed.workflow.v2",
|
|
182
|
+
// ← Phase v2.0-2.4 W0 T2.4.W0.1 ADD 16th surface (R20.1+R20.2+R20.9 workflow.yaml v2)
|
|
183
|
+
workflow_v3: "harnessed.workflow.v3",
|
|
184
|
+
// ← Phase v3.0-3.3 W0 T3.3.W0.11 ADD 17th surface (D-09 disciplines_applied + D-05 tools_available + master delegates_to per Pattern A B.1 LOCK)
|
|
185
|
+
discipline: "harnessed.discipline.v1"
|
|
186
|
+
// ← Phase v3.0-3.3 W0 T3.3.W0.11 ADD 18th surface (D-09 L0 Discipline Substrate, sister judgment.v1 multi-file pattern)
|
|
183
187
|
};
|
|
184
188
|
Type.Union([
|
|
185
189
|
Type.Literal(SCHEMA_VERSIONS.routingSnapshot),
|
|
@@ -202,11 +206,15 @@ var init_schemaVersion = __esm({
|
|
|
202
206
|
Type.Literal(SCHEMA_VERSIONS.knownGood),
|
|
203
207
|
// ← Phase 3.3 W1 T1.1 ADD 13th surface
|
|
204
208
|
Type.Literal(SCHEMA_VERSIONS.capabilities),
|
|
205
|
-
// ← Phase v2.0-2.3 W0
|
|
209
|
+
// ← Phase v2.0-2.3 W0 ADD 14th surface
|
|
206
210
|
Type.Literal(SCHEMA_VERSIONS.judgment),
|
|
207
|
-
// ← Phase v2.0-2.3 W0
|
|
208
|
-
Type.Literal(SCHEMA_VERSIONS.workflow)
|
|
209
|
-
// ← Phase v2.0-2.4 W0 T2.4.W0.1 ADD 16th surface (
|
|
211
|
+
// ← Phase v2.0-2.3 W0 ADD 15th surface
|
|
212
|
+
Type.Literal(SCHEMA_VERSIONS.workflow),
|
|
213
|
+
// ← Phase v2.0-2.4 W0 T2.4.W0.1 ADD 16th surface (first .v2 in union)
|
|
214
|
+
Type.Literal(SCHEMA_VERSIONS.workflow_v3),
|
|
215
|
+
// ← Phase v3.0-3.3 W0 T3.3.W0.11 ADD 17th surface (first .v3 in union)
|
|
216
|
+
Type.Literal(SCHEMA_VERSIONS.discipline)
|
|
217
|
+
// ← Phase v3.0-3.3 W0 T3.3.W0.11 ADD 18th surface
|
|
210
218
|
]);
|
|
211
219
|
}
|
|
212
220
|
});
|
|
@@ -692,10 +700,10 @@ __export(knownGood_exports, {
|
|
|
692
700
|
loadKnownGood: () => loadKnownGood
|
|
693
701
|
});
|
|
694
702
|
function loadKnownGood(harnessedVer) {
|
|
695
|
-
if (
|
|
703
|
+
if (_cache2.has(harnessedVer)) return _cache2.get(harnessedVer) ?? null;
|
|
696
704
|
const path = join(versionsDir(), `${harnessedVer}-known-good.yaml`);
|
|
697
705
|
if (!existsSync(path)) {
|
|
698
|
-
|
|
706
|
+
_cache2.set(harnessedVer, null);
|
|
699
707
|
return null;
|
|
700
708
|
}
|
|
701
709
|
const raw = readFileSync(path, "utf8");
|
|
@@ -706,7 +714,7 @@ function loadKnownGood(harnessedVer) {
|
|
|
706
714
|
`${path} schema invalid: ${errs.map((e) => `${e.path} ${e.message}`).join("; ")}`
|
|
707
715
|
);
|
|
708
716
|
}
|
|
709
|
-
|
|
717
|
+
_cache2.set(harnessedVer, parsed);
|
|
710
718
|
return parsed;
|
|
711
719
|
}
|
|
712
720
|
function getPinnedVersion(upstreamName, harnessedVer) {
|
|
@@ -715,12 +723,12 @@ function getPinnedVersion(upstreamName, harnessedVer) {
|
|
|
715
723
|
const entry = kg.upstreams.find((u) => u.name === upstreamName);
|
|
716
724
|
return entry?.version ?? null;
|
|
717
725
|
}
|
|
718
|
-
var versionsDir,
|
|
726
|
+
var versionsDir, _cache2;
|
|
719
727
|
var init_knownGood = __esm({
|
|
720
728
|
"src/manifest/knownGood.ts"() {
|
|
721
729
|
init_known_good_v1();
|
|
722
730
|
versionsDir = () => join(process.cwd(), "versions");
|
|
723
|
-
|
|
731
|
+
_cache2 = /* @__PURE__ */ new Map();
|
|
724
732
|
}
|
|
725
733
|
});
|
|
726
734
|
|
|
@@ -785,7 +793,7 @@ var init_resume = __esm({
|
|
|
785
793
|
|
|
786
794
|
// package.json
|
|
787
795
|
var package_default = {
|
|
788
|
-
version: "
|
|
796
|
+
version: "3.0.0"};
|
|
789
797
|
|
|
790
798
|
// src/manifest/errors.ts
|
|
791
799
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -1566,7 +1574,7 @@ function renderHumanTable(records) {
|
|
|
1566
1574
|
}
|
|
1567
1575
|
}
|
|
1568
1576
|
function pipeToJq(filterExpr, lines) {
|
|
1569
|
-
return new Promise((
|
|
1577
|
+
return new Promise((resolve9, reject) => {
|
|
1570
1578
|
const child = spawn("jq", [filterExpr], {
|
|
1571
1579
|
stdio: ["pipe", "inherit", "inherit"],
|
|
1572
1580
|
windowsHide: true
|
|
@@ -1575,12 +1583,12 @@ function pipeToJq(filterExpr, lines) {
|
|
|
1575
1583
|
const e = err2;
|
|
1576
1584
|
if (e.code === "ENOENT") {
|
|
1577
1585
|
console.error("\u2717 jq not found in PATH \u2014 run: harnessed doctor");
|
|
1578
|
-
|
|
1586
|
+
resolve9(1);
|
|
1579
1587
|
} else {
|
|
1580
1588
|
reject(err2);
|
|
1581
1589
|
}
|
|
1582
1590
|
});
|
|
1583
|
-
child.on("close", (code) =>
|
|
1591
|
+
child.on("close", (code) => resolve9(code ?? 0));
|
|
1584
1592
|
child.stdin.write(lines.join("\n"));
|
|
1585
1593
|
child.stdin.end();
|
|
1586
1594
|
});
|
|
@@ -1932,6 +1940,107 @@ function registerDoctor(program2) {
|
|
|
1932
1940
|
});
|
|
1933
1941
|
}
|
|
1934
1942
|
|
|
1943
|
+
// src/workflow/schema/discipline.ts
|
|
1944
|
+
init_schemaVersion();
|
|
1945
|
+
var EnforcementLayer = Type.Union([
|
|
1946
|
+
Type.Literal("code-writing"),
|
|
1947
|
+
// karpathy 心法 — write code phase
|
|
1948
|
+
Type.Literal("output"),
|
|
1949
|
+
// BLUF / language / no-emoji — emit response phase
|
|
1950
|
+
Type.Literal("commit"),
|
|
1951
|
+
// biome / A7 / commit safety — pre-commit phase
|
|
1952
|
+
Type.Literal("workflow"),
|
|
1953
|
+
// priority hierarchy / protocols — workflow-level arbitration
|
|
1954
|
+
Type.Literal("tool")
|
|
1955
|
+
// tool invoke discipline (reserved for v3.x extension)
|
|
1956
|
+
]);
|
|
1957
|
+
var Enforcement = Type.Union([
|
|
1958
|
+
Type.Literal("halt"),
|
|
1959
|
+
// process.exit non-zero, sister fallbackHandlers
|
|
1960
|
+
Type.Literal("warn"),
|
|
1961
|
+
// console.warn emit, continue
|
|
1962
|
+
Type.Literal("auto-fix"),
|
|
1963
|
+
// run auto_fix_cmd then continue (biome --write pattern)
|
|
1964
|
+
Type.Literal("info")
|
|
1965
|
+
// log only, no action
|
|
1966
|
+
]);
|
|
1967
|
+
var DisciplineRule = Type.Object(
|
|
1968
|
+
{
|
|
1969
|
+
id: Type.String({ minLength: 1 }),
|
|
1970
|
+
// kebab-case
|
|
1971
|
+
description: Type.String(),
|
|
1972
|
+
// human-readable
|
|
1973
|
+
enforcement: Enforcement,
|
|
1974
|
+
trigger: Type.Union([Type.String(), Type.Array(Type.String())]),
|
|
1975
|
+
// expr OR always-on list
|
|
1976
|
+
check_method: Type.String(),
|
|
1977
|
+
// heuristic / regex / external-cmd / llm-judge / file-content-match
|
|
1978
|
+
auto_fix_cmd: Type.Optional(Type.String())
|
|
1979
|
+
// only enforcement=auto-fix
|
|
1980
|
+
},
|
|
1981
|
+
{ additionalProperties: false }
|
|
1982
|
+
);
|
|
1983
|
+
var PriorityHierarchy = Type.Array(Type.String(), { minItems: 1 });
|
|
1984
|
+
var ProtocolShape = Type.Object(
|
|
1985
|
+
{
|
|
1986
|
+
description: Type.String(),
|
|
1987
|
+
required_fields: Type.Optional(Type.Array(Type.String())),
|
|
1988
|
+
forbidden_phrases: Type.Optional(Type.Array(Type.String())),
|
|
1989
|
+
file_ownership: Type.Optional(Type.Record(Type.String(), Type.Array(Type.String()))),
|
|
1990
|
+
rules: Type.Optional(Type.Array(DisciplineRule))
|
|
1991
|
+
},
|
|
1992
|
+
{ additionalProperties: false }
|
|
1993
|
+
);
|
|
1994
|
+
var Discipline = Type.Object(
|
|
1995
|
+
{
|
|
1996
|
+
schema_version: Type.Literal(SCHEMA_VERSIONS.discipline),
|
|
1997
|
+
discipline: Type.String({ minLength: 1 }),
|
|
1998
|
+
// basename (karpathy / output-style / ...)
|
|
1999
|
+
enforcement_layer: EnforcementLayer,
|
|
2000
|
+
auto_enforce: Type.Boolean(),
|
|
2001
|
+
rules: Type.Array(DisciplineRule),
|
|
2002
|
+
priority_hierarchy: Type.Optional(PriorityHierarchy),
|
|
2003
|
+
// priority.yaml only
|
|
2004
|
+
protocols: Type.Optional(Type.Record(Type.String(), ProtocolShape))
|
|
2005
|
+
// protocols.yaml only
|
|
2006
|
+
},
|
|
2007
|
+
{ additionalProperties: false }
|
|
2008
|
+
);
|
|
2009
|
+
|
|
2010
|
+
// src/workflow/disciplineLoader.ts
|
|
2011
|
+
var _cache = /* @__PURE__ */ new Map();
|
|
2012
|
+
async function loadDiscipline(basename2, packageRoot) {
|
|
2013
|
+
const cached = _cache.get(basename2);
|
|
2014
|
+
if (cached) return cached;
|
|
2015
|
+
const yamlPath = resolve(packageRoot, "workflows", "disciplines", `${basename2}.yaml`);
|
|
2016
|
+
const raw = await readFile(yamlPath, "utf8");
|
|
2017
|
+
const parsedRaw = parse(raw);
|
|
2018
|
+
if (!Value.Check(Discipline, parsedRaw)) {
|
|
2019
|
+
const errors = [...Value.Errors(Discipline, parsedRaw)].slice(0, 3).map((e) => `${e.path} ${e.message}`).join("; ");
|
|
2020
|
+
throw new Error(`Invalid discipline file ${basename2}.yaml: ${errors}`);
|
|
2021
|
+
}
|
|
2022
|
+
const parsed = parsedRaw;
|
|
2023
|
+
_cache.set(basename2, parsed);
|
|
2024
|
+
return parsed;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
// src/discipline/enforcement/before-commit.ts
|
|
2028
|
+
var TS_JS_RE = /\.(ts|tsx|js|mjs)$/;
|
|
2029
|
+
async function runBeforeCommitHook(ctx) {
|
|
2030
|
+
const d = await loadDiscipline("operational", ctx.packageRoot);
|
|
2031
|
+
if (ctx.changedFiles.some((f) => TS_JS_RE.test(f))) {
|
|
2032
|
+
const rule = d.rules.find((r) => r.id === "biome-preempt");
|
|
2033
|
+
if (rule?.auto_fix_cmd) {
|
|
2034
|
+
console.warn("\u26A0\uFE0F biome preempt \u2014 running auto-fix before commit");
|
|
2035
|
+
execSync(rule.auto_fix_cmd, { cwd: ctx.packageRoot, stdio: "inherit" });
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
if (ctx.cmdArgs.includes("--no-verify")) {
|
|
2039
|
+
console.error("\u274C no-skip-hooks violated: --no-verify forbidden");
|
|
2040
|
+
process.exit(2);
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
|
|
1935
2044
|
// src/routing/completionSchema.ts
|
|
1936
2045
|
var COMPLETION_SCHEMA = {
|
|
1937
2046
|
type: "object",
|
|
@@ -2636,15 +2745,100 @@ var PhasesSchema = Type.Object(
|
|
|
2636
2745
|
|
|
2637
2746
|
// src/workflow/schema/workflow.ts
|
|
2638
2747
|
init_schemaVersion();
|
|
2748
|
+
|
|
2749
|
+
// src/workflow/schema/workflow.v2.ts
|
|
2750
|
+
init_schemaVersion();
|
|
2639
2751
|
var ModelTier2 = Type.Union([Type.Literal("haiku"), Type.Literal("sonnet"), Type.Literal("opus")]);
|
|
2640
2752
|
var OnAction = Type.Union([Type.Literal("skip"), Type.Literal("invoke")]);
|
|
2753
|
+
var OnClauseV2 = Type.Object(
|
|
2754
|
+
{
|
|
2755
|
+
if: Type.String(),
|
|
2756
|
+
invoke: Type.Optional(Type.String()),
|
|
2757
|
+
action: Type.Optional(OnAction)
|
|
2758
|
+
},
|
|
2759
|
+
{ additionalProperties: false }
|
|
2760
|
+
);
|
|
2761
|
+
var FallbackMaxIterationsExceededV2 = Type.Object(
|
|
2762
|
+
{
|
|
2763
|
+
action: Type.Literal("emit_warning_and_halt"),
|
|
2764
|
+
message: Type.String(),
|
|
2765
|
+
exit_code: Type.Number()
|
|
2766
|
+
},
|
|
2767
|
+
{ additionalProperties: false }
|
|
2768
|
+
);
|
|
2769
|
+
var PhaseFallbackV2 = Type.Object(
|
|
2770
|
+
{
|
|
2771
|
+
max_iterations_exceeded: Type.Optional(FallbackMaxIterationsExceededV2)
|
|
2772
|
+
},
|
|
2773
|
+
{ additionalProperties: false }
|
|
2774
|
+
);
|
|
2775
|
+
var WorkflowPhaseV2 = Type.Object(
|
|
2776
|
+
{
|
|
2777
|
+
id: Type.String({ minLength: 1 }),
|
|
2778
|
+
name: Type.Optional(Type.String()),
|
|
2779
|
+
upstream: Type.Optional(Type.String()),
|
|
2780
|
+
capability: Type.Optional(Type.String()),
|
|
2781
|
+
model: Type.Optional(ModelTier2),
|
|
2782
|
+
invokes: Type.Optional(Type.String()),
|
|
2783
|
+
args: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
2784
|
+
gate: Type.Optional(Type.String()),
|
|
2785
|
+
on: Type.Optional(Type.Array(OnClauseV2)),
|
|
2786
|
+
parallelism: Type.Optional(Type.String()),
|
|
2787
|
+
fallback: Type.Optional(PhaseFallbackV2),
|
|
2788
|
+
max_iterations: Type.Optional(Type.Union([Type.Number(), Type.String()])),
|
|
2789
|
+
artifacts_expected: Type.Optional(Type.Array(Type.String()))
|
|
2790
|
+
},
|
|
2791
|
+
{ additionalProperties: false }
|
|
2792
|
+
);
|
|
2793
|
+
var WorkflowSchemaV2 = Type.Object(
|
|
2794
|
+
{
|
|
2795
|
+
schema_version: Type.Literal(SCHEMA_VERSIONS.workflow),
|
|
2796
|
+
workflow: Type.String({ minLength: 1 }),
|
|
2797
|
+
description: Type.Optional(Type.String()),
|
|
2798
|
+
phases: Type.Array(WorkflowPhaseV2, { minItems: 1 })
|
|
2799
|
+
},
|
|
2800
|
+
{ additionalProperties: false }
|
|
2801
|
+
);
|
|
2802
|
+
|
|
2803
|
+
// src/workflow/schema/workflow.ts
|
|
2804
|
+
var ModelTier3 = Type.Union([Type.Literal("haiku"), Type.Literal("sonnet"), Type.Literal("opus")]);
|
|
2805
|
+
var OnAction2 = Type.Union([Type.Literal("skip"), Type.Literal("invoke")]);
|
|
2806
|
+
var DisciplineName = Type.Union([
|
|
2807
|
+
Type.Literal("karpathy"),
|
|
2808
|
+
Type.Literal("output-style"),
|
|
2809
|
+
Type.Literal("language"),
|
|
2810
|
+
Type.Literal("operational"),
|
|
2811
|
+
Type.Literal("priority"),
|
|
2812
|
+
Type.Literal("protocols")
|
|
2813
|
+
]);
|
|
2641
2814
|
var OnClause = Type.Object(
|
|
2642
2815
|
{
|
|
2643
2816
|
if: Type.String(),
|
|
2644
2817
|
// expr-eval expression OR judgments.<file>.<gate>.fires ref
|
|
2645
2818
|
invoke: Type.Optional(Type.String()),
|
|
2646
2819
|
// '{{ capabilities.<name>.cmd }}' OR literal
|
|
2647
|
-
action: Type.Optional(
|
|
2820
|
+
action: Type.Optional(OnAction2)
|
|
2821
|
+
},
|
|
2822
|
+
{ additionalProperties: false }
|
|
2823
|
+
);
|
|
2824
|
+
var InvokeToolClause = Type.Object(
|
|
2825
|
+
{
|
|
2826
|
+
if: Type.Optional(Type.String()),
|
|
2827
|
+
// optional — 无 if = unconditional fire
|
|
2828
|
+
tool: Type.String({ minLength: 1 })
|
|
2829
|
+
// capabilities.yaml entry name (cross-validate T3.3.W0.10)
|
|
2830
|
+
},
|
|
2831
|
+
{ additionalProperties: false }
|
|
2832
|
+
);
|
|
2833
|
+
var DelegationClause = Type.Object(
|
|
2834
|
+
{
|
|
2835
|
+
sub: Type.String({ minLength: 1 }),
|
|
2836
|
+
// sub-stage workflow name e.g. 'strategic' / 'phase' / 'subtask'
|
|
2837
|
+
gate: Type.Optional(Type.String()),
|
|
2838
|
+
// judgments.<file>.<trigger>.fires 4-level ref
|
|
2839
|
+
mode: Type.Optional(Type.Union([Type.Literal("parallel"), Type.Literal("serial")])),
|
|
2840
|
+
order: Type.Optional(Type.Number())
|
|
2841
|
+
// serial-only: explicit ordering (K9 mitigation enforced in check-workflow-schema)
|
|
2648
2842
|
},
|
|
2649
2843
|
{ additionalProperties: false }
|
|
2650
2844
|
);
|
|
@@ -2663,14 +2857,14 @@ var PhaseFallback = Type.Object(
|
|
|
2663
2857
|
},
|
|
2664
2858
|
{ additionalProperties: false }
|
|
2665
2859
|
);
|
|
2666
|
-
var
|
|
2860
|
+
var WorkflowPhaseV3 = Type.Object(
|
|
2667
2861
|
{
|
|
2668
2862
|
id: Type.String({ minLength: 1 }),
|
|
2669
2863
|
name: Type.Optional(Type.String()),
|
|
2670
2864
|
upstream: Type.Optional(Type.String()),
|
|
2671
2865
|
capability: Type.Optional(Type.String()),
|
|
2672
2866
|
// '{{ capabilities.ralph-loop.cmd }}'
|
|
2673
|
-
model: Type.Optional(
|
|
2867
|
+
model: Type.Optional(ModelTier3),
|
|
2674
2868
|
invokes: Type.Optional(Type.String()),
|
|
2675
2869
|
// legacy slash-cmd OR JINJA template
|
|
2676
2870
|
args: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
@@ -2684,16 +2878,25 @@ var WorkflowPhaseV2 = Type.Object(
|
|
|
2684
2878
|
Type.Union([Type.Number(), Type.String()])
|
|
2685
2879
|
// numeric literal OR jinja '{{ defaults.x.y }}'
|
|
2686
2880
|
),
|
|
2687
|
-
artifacts_expected: Type.Optional(Type.Array(Type.String()))
|
|
2881
|
+
artifacts_expected: Type.Optional(Type.Array(Type.String())),
|
|
2882
|
+
invokes_tools: Type.Optional(Type.Array(InvokeToolClause))
|
|
2883
|
+
// NEW v3 D-05 phase-level conditional fire
|
|
2688
2884
|
},
|
|
2689
2885
|
{ additionalProperties: false }
|
|
2690
2886
|
);
|
|
2691
|
-
|
|
2887
|
+
Type.Object(
|
|
2692
2888
|
{
|
|
2693
|
-
schema_version: Type.Literal(SCHEMA_VERSIONS.
|
|
2889
|
+
schema_version: Type.Literal(SCHEMA_VERSIONS.workflow_v3),
|
|
2694
2890
|
workflow: Type.String({ minLength: 1 }),
|
|
2695
2891
|
description: Type.Optional(Type.String()),
|
|
2696
|
-
|
|
2892
|
+
disciplines_applied: Type.Optional(Type.Array(DisciplineName)),
|
|
2893
|
+
// NEW v3 D-09 (Pattern A A.1 strict Literal Union)
|
|
2894
|
+
tools_available: Type.Optional(Type.Array(Type.String())),
|
|
2895
|
+
// NEW v3 D-05 (cross-validate T3.3.W0.10)
|
|
2896
|
+
delegates_to: Type.Optional(Type.Array(DelegationClause)),
|
|
2897
|
+
// NEW v3 D-01 (master orchestrator only)
|
|
2898
|
+
phases: Type.Optional(Type.Array(WorkflowPhaseV3, { minItems: 1 }))
|
|
2899
|
+
// 改 Optional — master 无 phases, sub/standalone 必有
|
|
2697
2900
|
},
|
|
2698
2901
|
{ additionalProperties: false }
|
|
2699
2902
|
);
|
|
@@ -2776,6 +2979,22 @@ function registerExecuteTask(program2) {
|
|
|
2776
2979
|
break;
|
|
2777
2980
|
}
|
|
2778
2981
|
}
|
|
2982
|
+
try {
|
|
2983
|
+
const stagedOut = execSync("git status --porcelain", { encoding: "utf8" });
|
|
2984
|
+
const changedFiles = stagedOut.split("\n").filter((l) => l.trim().length > 0).map((l) => l.slice(3).trim());
|
|
2985
|
+
await runBeforeCommitHook({
|
|
2986
|
+
changedFiles,
|
|
2987
|
+
cmdArgs: [],
|
|
2988
|
+
packageRoot: process.cwd(),
|
|
2989
|
+
cmdType: "git-commit",
|
|
2990
|
+
hasUserApproval: true
|
|
2991
|
+
// --apply explicit
|
|
2992
|
+
});
|
|
2993
|
+
} catch (err2) {
|
|
2994
|
+
console.warn(
|
|
2995
|
+
`\u26A0\uFE0F before-commit pre-flight skipped (${err2.message}); subagent will biome-check at commit time.`
|
|
2996
|
+
);
|
|
2997
|
+
}
|
|
2779
2998
|
const result = await runRouting(taskCtx, {
|
|
2780
2999
|
maxIterations: raw.maxIterations ?? 20,
|
|
2781
3000
|
...raw.model ? { agentOpts: { modelOverride: raw.model } } : {},
|
|
@@ -3157,7 +3376,7 @@ var installCcHookAdd = async (ctx) => {
|
|
|
3157
3376
|
return { ok: true, backupId: bk.backupId, appliedFiles: [settingsPath] };
|
|
3158
3377
|
};
|
|
3159
3378
|
function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
3160
|
-
return new Promise((
|
|
3379
|
+
return new Promise((resolve9) => {
|
|
3161
3380
|
const isWin = process.platform === "win32";
|
|
3162
3381
|
const child = isWin ? spawn("cmd.exe", ["/c", "claude", ...claudeArgs], { cwd, windowsHide: true }) : spawn("claude", claudeArgs, { cwd, shell: false });
|
|
3163
3382
|
let stderr = "";
|
|
@@ -3166,15 +3385,15 @@ function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
|
3166
3385
|
});
|
|
3167
3386
|
const timer = setTimeout(() => {
|
|
3168
3387
|
child.kill("SIGKILL");
|
|
3169
|
-
|
|
3388
|
+
resolve9({ exitCode: -1, stderr: `${stderr}[timeout after ${timeoutMs}ms]` });
|
|
3170
3389
|
}, timeoutMs);
|
|
3171
3390
|
child.on("error", (e) => {
|
|
3172
3391
|
clearTimeout(timer);
|
|
3173
|
-
|
|
3392
|
+
resolve9({ exitCode: -1, stderr: `${stderr}${e.message}` });
|
|
3174
3393
|
});
|
|
3175
3394
|
child.on("close", (code) => {
|
|
3176
3395
|
clearTimeout(timer);
|
|
3177
|
-
|
|
3396
|
+
resolve9({ exitCode: code ?? -1, stderr });
|
|
3178
3397
|
});
|
|
3179
3398
|
});
|
|
3180
3399
|
}
|
|
@@ -3315,7 +3534,7 @@ ${newEntry}
|
|
|
3315
3534
|
)
|
|
3316
3535
|
};
|
|
3317
3536
|
}
|
|
3318
|
-
const vr = await new Promise((
|
|
3537
|
+
const vr = await new Promise((resolve9) => {
|
|
3319
3538
|
const child = spawn(verifyShell, [verifyFlag, verifyLine], { cwd: ctx.cwd, windowsHide: true });
|
|
3320
3539
|
let stderr = "";
|
|
3321
3540
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -3323,15 +3542,15 @@ ${newEntry}
|
|
|
3323
3542
|
});
|
|
3324
3543
|
const timer = setTimeout(() => {
|
|
3325
3544
|
child.kill("SIGKILL");
|
|
3326
|
-
|
|
3545
|
+
resolve9({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
3327
3546
|
}, 15e3);
|
|
3328
3547
|
child.on("error", (e) => {
|
|
3329
3548
|
clearTimeout(timer);
|
|
3330
|
-
|
|
3549
|
+
resolve9({ exitCode: -1, stderr: e.message });
|
|
3331
3550
|
});
|
|
3332
3551
|
child.on("close", (code) => {
|
|
3333
3552
|
clearTimeout(timer);
|
|
3334
|
-
|
|
3553
|
+
resolve9({ exitCode: code ?? -1, stderr });
|
|
3335
3554
|
});
|
|
3336
3555
|
});
|
|
3337
3556
|
if (vr.exitCode !== 0) {
|
|
@@ -3387,10 +3606,10 @@ async function spawnCmd(ctx, cmd, args) {
|
|
|
3387
3606
|
child.stderr?.setEncoding("utf8").on("data", (chunk) => {
|
|
3388
3607
|
stderr += chunk;
|
|
3389
3608
|
});
|
|
3390
|
-
return await new Promise((
|
|
3609
|
+
return await new Promise((resolve9) => {
|
|
3391
3610
|
const timer = setTimeout(() => {
|
|
3392
3611
|
child.kill("SIGKILL");
|
|
3393
|
-
|
|
3612
|
+
resolve9({
|
|
3394
3613
|
ok: false,
|
|
3395
3614
|
phase: "spawn",
|
|
3396
3615
|
error: {
|
|
@@ -3405,7 +3624,7 @@ async function spawnCmd(ctx, cmd, args) {
|
|
|
3405
3624
|
}, timeoutMs);
|
|
3406
3625
|
child.on("error", (err2) => {
|
|
3407
3626
|
clearTimeout(timer);
|
|
3408
|
-
|
|
3627
|
+
resolve9({
|
|
3409
3628
|
ok: false,
|
|
3410
3629
|
phase: "spawn",
|
|
3411
3630
|
error: {
|
|
@@ -3420,14 +3639,14 @@ async function spawnCmd(ctx, cmd, args) {
|
|
|
3420
3639
|
});
|
|
3421
3640
|
child.on("close", (code) => {
|
|
3422
3641
|
clearTimeout(timer);
|
|
3423
|
-
|
|
3642
|
+
resolve9({ ok: true, exitCode: code ?? -1, stdout: stdout2, stderr });
|
|
3424
3643
|
});
|
|
3425
3644
|
});
|
|
3426
3645
|
}
|
|
3427
3646
|
|
|
3428
3647
|
// src/installers/gitCloneWithSetup.ts
|
|
3429
3648
|
function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
3430
|
-
return new Promise((
|
|
3649
|
+
return new Promise((resolve9) => {
|
|
3431
3650
|
const isWin = process.platform === "win32";
|
|
3432
3651
|
const child = isWin ? spawn("cmd.exe", ["/c", "git", "rev-parse", "HEAD"], { cwd, windowsHide: true }) : spawn("git", ["rev-parse", "HEAD"], { cwd, shell: false });
|
|
3433
3652
|
let stdout2 = "";
|
|
@@ -3436,15 +3655,15 @@ function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
|
3436
3655
|
});
|
|
3437
3656
|
const timer = setTimeout(() => {
|
|
3438
3657
|
child.kill("SIGKILL");
|
|
3439
|
-
|
|
3658
|
+
resolve9({ sha: "", exit: -1 });
|
|
3440
3659
|
}, timeoutMs);
|
|
3441
3660
|
child.on("error", () => {
|
|
3442
3661
|
clearTimeout(timer);
|
|
3443
|
-
|
|
3662
|
+
resolve9({ sha: "", exit: -1 });
|
|
3444
3663
|
});
|
|
3445
3664
|
child.on("close", (code) => {
|
|
3446
3665
|
clearTimeout(timer);
|
|
3447
|
-
|
|
3666
|
+
resolve9({ sha: stdout2.trim(), exit: code ?? -1 });
|
|
3448
3667
|
});
|
|
3449
3668
|
});
|
|
3450
3669
|
}
|
|
@@ -3784,7 +4003,7 @@ ${newEntry}
|
|
|
3784
4003
|
)
|
|
3785
4004
|
};
|
|
3786
4005
|
}
|
|
3787
|
-
const vr = await new Promise((
|
|
4006
|
+
const vr = await new Promise((resolve9) => {
|
|
3788
4007
|
const child = spawn(verifyShell, [verifyFlag, verifyLine], { cwd: ctx.cwd, windowsHide: true });
|
|
3789
4008
|
let stderr = "";
|
|
3790
4009
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -3792,15 +4011,15 @@ ${newEntry}
|
|
|
3792
4011
|
});
|
|
3793
4012
|
const timer = setTimeout(() => {
|
|
3794
4013
|
child.kill("SIGKILL");
|
|
3795
|
-
|
|
4014
|
+
resolve9({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
3796
4015
|
}, 15e3);
|
|
3797
4016
|
child.on("error", (e) => {
|
|
3798
4017
|
clearTimeout(timer);
|
|
3799
|
-
|
|
4018
|
+
resolve9({ exitCode: -1, stderr: e.message });
|
|
3800
4019
|
});
|
|
3801
4020
|
child.on("close", (code) => {
|
|
3802
4021
|
clearTimeout(timer);
|
|
3803
|
-
|
|
4022
|
+
resolve9({ exitCode: code ?? -1, stderr });
|
|
3804
4023
|
});
|
|
3805
4024
|
});
|
|
3806
4025
|
if (vr.exitCode !== 0) {
|
|
@@ -3932,7 +4151,7 @@ ${newEntry}
|
|
|
3932
4151
|
)
|
|
3933
4152
|
};
|
|
3934
4153
|
}
|
|
3935
|
-
const vr = await new Promise((
|
|
4154
|
+
const vr = await new Promise((resolve9) => {
|
|
3936
4155
|
const child = spawn(verifyShell, [verifyFlag, verifyLine], { cwd: ctx.cwd, windowsHide: true });
|
|
3937
4156
|
let stderr = "";
|
|
3938
4157
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -3940,15 +4159,15 @@ ${newEntry}
|
|
|
3940
4159
|
});
|
|
3941
4160
|
const timer = setTimeout(() => {
|
|
3942
4161
|
child.kill("SIGKILL");
|
|
3943
|
-
|
|
4162
|
+
resolve9({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
3944
4163
|
}, 15e3);
|
|
3945
4164
|
child.on("error", (e) => {
|
|
3946
4165
|
clearTimeout(timer);
|
|
3947
|
-
|
|
4166
|
+
resolve9({ exitCode: -1, stderr: e.message });
|
|
3948
4167
|
});
|
|
3949
4168
|
child.on("close", (code) => {
|
|
3950
4169
|
clearTimeout(timer);
|
|
3951
|
-
|
|
4170
|
+
resolve9({ exitCode: code ?? -1, stderr });
|
|
3952
4171
|
});
|
|
3953
4172
|
});
|
|
3954
4173
|
if (vr.exitCode !== 0) {
|
|
@@ -4562,6 +4781,82 @@ function registerRollback(program2) {
|
|
|
4562
4781
|
});
|
|
4563
4782
|
}
|
|
4564
4783
|
init_checkAgentTeams();
|
|
4784
|
+
var FLAT_LEGACY_DEPRECATED = /* @__PURE__ */ new Set(["plan-feature", "execute-task", "verify-work"]);
|
|
4785
|
+
var FLAT_LEGACY_KEEP = /* @__PURE__ */ new Set(["research", "retro"]);
|
|
4786
|
+
var NON_WORKFLOW_DIRS = /* @__PURE__ */ new Set(["disciplines", "judgments"]);
|
|
4787
|
+
async function scanWorkflowsNested(workflowsDir, entries) {
|
|
4788
|
+
const workflows = [];
|
|
4789
|
+
const deprecated = [];
|
|
4790
|
+
for (const entry of entries.sort()) {
|
|
4791
|
+
if (NON_WORKFLOW_DIRS.has(entry)) continue;
|
|
4792
|
+
const src = join(workflowsDir, entry);
|
|
4793
|
+
let s;
|
|
4794
|
+
try {
|
|
4795
|
+
s = await stat(src);
|
|
4796
|
+
} catch {
|
|
4797
|
+
continue;
|
|
4798
|
+
}
|
|
4799
|
+
if (!s.isDirectory()) continue;
|
|
4800
|
+
let hasFlatSkill = false;
|
|
4801
|
+
try {
|
|
4802
|
+
await stat(join(src, "SKILL.md"));
|
|
4803
|
+
hasFlatSkill = true;
|
|
4804
|
+
} catch {
|
|
4805
|
+
hasFlatSkill = false;
|
|
4806
|
+
}
|
|
4807
|
+
if (hasFlatSkill) {
|
|
4808
|
+
if (FLAT_LEGACY_DEPRECATED.has(entry)) {
|
|
4809
|
+
deprecated.push(entry);
|
|
4810
|
+
continue;
|
|
4811
|
+
}
|
|
4812
|
+
if (FLAT_LEGACY_KEEP.has(entry)) {
|
|
4813
|
+
workflows.push({ name: entry, relPath: entry, isMaster: false });
|
|
4814
|
+
continue;
|
|
4815
|
+
}
|
|
4816
|
+
workflows.push({ name: entry, relPath: entry, isMaster: false });
|
|
4817
|
+
continue;
|
|
4818
|
+
}
|
|
4819
|
+
let subEntries;
|
|
4820
|
+
try {
|
|
4821
|
+
subEntries = await readdir(src);
|
|
4822
|
+
} catch {
|
|
4823
|
+
continue;
|
|
4824
|
+
}
|
|
4825
|
+
for (const sub of subEntries.sort()) {
|
|
4826
|
+
const subDir = join(src, sub);
|
|
4827
|
+
let ss;
|
|
4828
|
+
try {
|
|
4829
|
+
ss = await stat(subDir);
|
|
4830
|
+
} catch {
|
|
4831
|
+
continue;
|
|
4832
|
+
}
|
|
4833
|
+
if (!ss.isDirectory()) continue;
|
|
4834
|
+
try {
|
|
4835
|
+
await stat(join(subDir, "SKILL.md"));
|
|
4836
|
+
} catch {
|
|
4837
|
+
continue;
|
|
4838
|
+
}
|
|
4839
|
+
const name = sub === "auto" ? entry : `${entry}-${sub}`;
|
|
4840
|
+
workflows.push({ name, relPath: `${entry}/${sub}`, isMaster: sub === "auto" });
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
return { workflows, deprecated };
|
|
4844
|
+
}
|
|
4845
|
+
function renderDeprecationBlock(deprecated) {
|
|
4846
|
+
if (deprecated.length === 0) return "";
|
|
4847
|
+
return [
|
|
4848
|
+
"\u26A0\uFE0F v3.0 BREAKING \u2014 v2 legacy slash cmd deprecated:",
|
|
4849
|
+
" /plan-feature \u2192 /plan (master) | /plan-phase (sub)",
|
|
4850
|
+
" /execute-task \u2192 /task (master) | /task-{clarify,code,test,deliver} (sub)",
|
|
4851
|
+
" /verify-work \u2192 /verify (master) | /verify-{progress,paranoid,qa,security,design,simplify,multispec} (sub)",
|
|
4852
|
+
" /research, /retro \u4E0D\u53D8",
|
|
4853
|
+
" \u8BE6\u89C1 CHANGELOG [3.0.0]",
|
|
4854
|
+
` skipped install: ${deprecated.sort().join(", ")}`,
|
|
4855
|
+
""
|
|
4856
|
+
].join("\n");
|
|
4857
|
+
}
|
|
4858
|
+
|
|
4859
|
+
// src/cli/lib/setup-helpers.ts
|
|
4565
4860
|
var PHASE_212 = /* @__PURE__ */ new Set([
|
|
4566
4861
|
"cc-plugin-marketplace",
|
|
4567
4862
|
"git-clone-with-setup",
|
|
@@ -4581,18 +4876,7 @@ async function warnIfAgentTeamsMissing() {
|
|
|
4581
4876
|
);
|
|
4582
4877
|
}
|
|
4583
4878
|
async function scanWorkflowsWithSkill(workflowsDir, entries) {
|
|
4584
|
-
|
|
4585
|
-
for (const entry of entries.sort()) {
|
|
4586
|
-
const src = join(workflowsDir, entry);
|
|
4587
|
-
try {
|
|
4588
|
-
const s = await stat(src);
|
|
4589
|
-
if (!s.isDirectory()) continue;
|
|
4590
|
-
await stat(join(src, "SKILL.md"));
|
|
4591
|
-
out.push(entry);
|
|
4592
|
-
} catch {
|
|
4593
|
-
}
|
|
4594
|
-
}
|
|
4595
|
-
return out;
|
|
4879
|
+
return scanWorkflowsNested(workflowsDir, entries);
|
|
4596
4880
|
}
|
|
4597
4881
|
async function runStepBInstall(manifestPaths) {
|
|
4598
4882
|
const opts = {
|
|
@@ -4678,7 +4962,12 @@ function registerSetup(program2) {
|
|
|
4678
4962
|
console.error(`error: workflows directory not found at ${workflowsDir}`);
|
|
4679
4963
|
process.exit(1);
|
|
4680
4964
|
}
|
|
4681
|
-
const toInstall = await scanWorkflowsWithSkill(
|
|
4965
|
+
const { workflows: toInstall, deprecated } = await scanWorkflowsWithSkill(
|
|
4966
|
+
workflowsDir,
|
|
4967
|
+
entries
|
|
4968
|
+
);
|
|
4969
|
+
const depBlock = renderDeprecationBlock(deprecated);
|
|
4970
|
+
if (depBlock) console.log(depBlock);
|
|
4682
4971
|
if (toInstall.length === 0) {
|
|
4683
4972
|
console.log("setup: no workflow directories with SKILL.md found \u2014 nothing to install");
|
|
4684
4973
|
process.exit(2);
|
|
@@ -4687,22 +4976,24 @@ function registerSetup(program2) {
|
|
|
4687
4976
|
console.log(
|
|
4688
4977
|
`[dry-run] setup would install ${toInstall.length} workflow(s) to ${skillsBase}:`
|
|
4689
4978
|
);
|
|
4690
|
-
for (const
|
|
4691
|
-
|
|
4979
|
+
for (const wf of toInstall) {
|
|
4980
|
+
const masterTag = wf.isMaster ? " (master)" : "";
|
|
4981
|
+
console.log(` ${wf.name} \u2192 ${join(skillsBase, wf.name)}${masterTag}`);
|
|
4692
4982
|
}
|
|
4693
4983
|
console.log(` run without --dry-run to execute`);
|
|
4694
4984
|
process.exit(0);
|
|
4695
4985
|
}
|
|
4696
4986
|
let skillsInstalled = 0;
|
|
4697
|
-
for (const
|
|
4698
|
-
const src = join(workflowsDir,
|
|
4699
|
-
const dst = join(skillsBase, name);
|
|
4987
|
+
for (const wf of toInstall) {
|
|
4988
|
+
const src = join(workflowsDir, wf.relPath);
|
|
4989
|
+
const dst = join(skillsBase, wf.name);
|
|
4700
4990
|
try {
|
|
4701
4991
|
await cp(src, dst, { recursive: true, force: true });
|
|
4702
|
-
|
|
4992
|
+
const masterTag = wf.isMaster ? " (master)" : "";
|
|
4993
|
+
console.log(` [A] installed ${wf.name} \u2192 ${dst}${masterTag}`);
|
|
4703
4994
|
skillsInstalled++;
|
|
4704
4995
|
} catch (e) {
|
|
4705
|
-
console.error(` error: failed to copy ${name}: ${e.message}`);
|
|
4996
|
+
console.error(` error: failed to copy ${wf.name}: ${e.message}`);
|
|
4706
4997
|
process.exit(1);
|
|
4707
4998
|
}
|
|
4708
4999
|
}
|
|
@@ -4963,7 +5254,7 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
4963
5254
|
const m = install.cmd.match(/npm\s+(?:install|i)\s+(?:-g\s+)?(\S+)/);
|
|
4964
5255
|
const pkg = m?.[1] ?? ctx.manifest.metadata.upstream.source;
|
|
4965
5256
|
const isWin = process.platform === "win32";
|
|
4966
|
-
const result = await new Promise((
|
|
5257
|
+
const result = await new Promise((resolve9) => {
|
|
4967
5258
|
const child = isWin ? spawn("cmd.exe", ["/c", "npm", "uninstall", "-g", pkg], { windowsHide: true }) : spawn("npm", ["uninstall", "-g", pkg], { shell: false });
|
|
4968
5259
|
let stderr = "";
|
|
4969
5260
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -4971,15 +5262,15 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
4971
5262
|
});
|
|
4972
5263
|
const timer = setTimeout(() => {
|
|
4973
5264
|
child.kill("SIGKILL");
|
|
4974
|
-
|
|
5265
|
+
resolve9({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
4975
5266
|
}, 3e4);
|
|
4976
5267
|
child.on("error", (e) => {
|
|
4977
5268
|
clearTimeout(timer);
|
|
4978
|
-
|
|
5269
|
+
resolve9({ exitCode: -1, stderr: e.message });
|
|
4979
5270
|
});
|
|
4980
5271
|
child.on("close", (code) => {
|
|
4981
5272
|
clearTimeout(timer);
|
|
4982
|
-
|
|
5273
|
+
resolve9({ exitCode: code ?? -1, stderr });
|
|
4983
5274
|
});
|
|
4984
5275
|
});
|
|
4985
5276
|
if (result.exitCode !== 0) {
|