@codemcp/ade 0.2.6 → 0.4.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/.agentskills/skills/conventional-commits/SKILL.md +36 -0
- package/.beads/issues.jsonl +10 -0
- package/.beads/last-touched +1 -1
- package/.kiro/agents/ade.json +9 -2
- package/.opencode/agents/ade.md +9 -18
- package/.vibe/beads-state-ade-better-in-cli-explanation-b8jcv3.json +24 -0
- package/.vibe/beads-state-ade-fix-no-git-k396xs.json +34 -0
- package/.vibe/development-plan-better-in-cli-explanation.md +64 -0
- package/.vibe/development-plan-fix-no-git.md +76 -0
- package/AGENTS.md +27 -0
- package/config.lock.yaml +33 -9
- package/config.yaml +3 -0
- package/package.json +1 -1
- package/packages/cli/dist/index.js +190 -50
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/commands/conventions.integration.spec.ts +8 -1
- package/packages/cli/src/commands/install.integration.spec.ts +1 -0
- package/packages/cli/src/commands/install.ts +19 -1
- package/packages/cli/src/commands/knowledge.integration.spec.ts +1 -0
- package/packages/cli/src/commands/setup.integration.spec.ts +2 -0
- package/packages/cli/src/commands/setup.spec.ts +2 -1
- package/packages/cli/src/commands/setup.ts +61 -6
- package/packages/cli/src/index.ts +8 -1
- package/packages/core/package.json +1 -1
- package/packages/core/src/catalog/catalog.spec.ts +1 -1
- package/packages/core/src/catalog/facets/autonomy.ts +9 -9
- package/packages/core/src/catalog/facets/backpressure.ts +1 -1
- package/packages/core/src/catalog/facets/practices.ts +1 -2
- package/packages/core/src/catalog/facets/process.ts +1 -1
- package/packages/harnesses/package.json +2 -1
- package/packages/harnesses/src/util.spec.ts +97 -0
- package/packages/harnesses/src/util.ts +21 -4
- package/packages/harnesses/src/writers/opencode.spec.ts +4 -6
- package/packages/harnesses/src/writers/opencode.ts +23 -27
- package/skills-lock.json +6 -1
|
@@ -11222,6 +11222,23 @@ var B = class {
|
|
|
11222
11222
|
}
|
|
11223
11223
|
}
|
|
11224
11224
|
};
|
|
11225
|
+
var kt = class extends B {
|
|
11226
|
+
get cursor() {
|
|
11227
|
+
return this.value ? 0 : 1;
|
|
11228
|
+
}
|
|
11229
|
+
get _value() {
|
|
11230
|
+
return this.cursor === 0;
|
|
11231
|
+
}
|
|
11232
|
+
constructor(e) {
|
|
11233
|
+
super(e, false), this.value = !!e.initialValue, this.on("userInput", () => {
|
|
11234
|
+
this.value = this._value;
|
|
11235
|
+
}), this.on("confirm", (s) => {
|
|
11236
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
|
|
11237
|
+
}), this.on("cursor", () => {
|
|
11238
|
+
this.value = !this.value;
|
|
11239
|
+
});
|
|
11240
|
+
}
|
|
11241
|
+
};
|
|
11225
11242
|
var Lt = class extends B {
|
|
11226
11243
|
options;
|
|
11227
11244
|
cursor = 0;
|
|
@@ -11556,6 +11573,33 @@ var X2 = ({ cursor: e, options: r2, style: s, output: i = process.stdout, maxIte
|
|
|
11556
11573
|
for (const A3 of d3) for (const b of A3) C2.push(b);
|
|
11557
11574
|
return $2 && C2.push(c), C2;
|
|
11558
11575
|
};
|
|
11576
|
+
var Rt = (e) => {
|
|
11577
|
+
const r2 = e.active ?? "Yes", s = e.inactive ?? "No";
|
|
11578
|
+
return new kt({ active: r2, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
|
|
11579
|
+
const i = e.withGuide ?? _.withGuide, a = `${i ? `${t("gray", h)}
|
|
11580
|
+
` : ""}${W2(this.state)} ${e.message}
|
|
11581
|
+
`, o2 = this.value ? r2 : s;
|
|
11582
|
+
switch (this.state) {
|
|
11583
|
+
case "submit": {
|
|
11584
|
+
const u2 = i ? `${t("gray", h)} ` : "";
|
|
11585
|
+
return `${a}${u2}${t("dim", o2)}`;
|
|
11586
|
+
}
|
|
11587
|
+
case "cancel": {
|
|
11588
|
+
const u2 = i ? `${t("gray", h)} ` : "";
|
|
11589
|
+
return `${a}${u2}${t(["strikethrough", "dim"], o2)}${i ? `
|
|
11590
|
+
${t("gray", h)}` : ""}`;
|
|
11591
|
+
}
|
|
11592
|
+
default: {
|
|
11593
|
+
const u2 = i ? `${t("cyan", h)} ` : "", l = i ? t("cyan", x2) : "";
|
|
11594
|
+
return `${a}${u2}${this.value ? `${t("green", z2)} ${r2}` : `${t("dim", H2)} ${t("dim", r2)}`}${e.vertical ? i ? `
|
|
11595
|
+
${t("cyan", h)} ` : `
|
|
11596
|
+
` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
|
|
11597
|
+
${l}
|
|
11598
|
+
`;
|
|
11599
|
+
}
|
|
11600
|
+
}
|
|
11601
|
+
} }).prompt();
|
|
11602
|
+
};
|
|
11559
11603
|
var R2 = { message: (e = [], { symbol: r2 = t("gray", h), secondarySymbol: s = t("gray", h), output: i = process.stdout, spacing: a = 1, withGuide: o2 } = {}) => {
|
|
11560
11604
|
const u2 = [], l = o2 ?? _.withGuide, n = l ? s : "", c = l ? `${r2} ` : "", p2 = l ? `${s} ` : "";
|
|
11561
11605
|
for (let g2 = 0; g2 < a; g2++) u2.push(n);
|
|
@@ -11653,6 +11697,25 @@ ${t("cyan", x2)}
|
|
|
11653
11697
|
}
|
|
11654
11698
|
} }).prompt();
|
|
11655
11699
|
};
|
|
11700
|
+
var jt = (e) => t("dim", e);
|
|
11701
|
+
var kt2 = (e, r2, s) => {
|
|
11702
|
+
const i = { hard: true, trim: false }, a = J2(e, r2, i).split(`
|
|
11703
|
+
`), o2 = a.reduce((n, c) => Math.max(D2(c), n), 0), u2 = a.map(s).reduce((n, c) => Math.max(D2(c), n), 0), l = r2 - (u2 - o2);
|
|
11704
|
+
return J2(e, l, i);
|
|
11705
|
+
};
|
|
11706
|
+
var Vt2 = (e = "", r2 = "", s) => {
|
|
11707
|
+
const i = s?.output ?? N2.stdout, a = s?.withGuide ?? _.withGuide, o2 = s?.format ?? jt, u2 = ["", ...kt2(e, rt(i) - 6, o2).split(`
|
|
11708
|
+
`).map(o2), ""], l = D2(r2), n = Math.max(u2.reduce((g2, E) => {
|
|
11709
|
+
const $2 = D2(E);
|
|
11710
|
+
return $2 > g2 ? $2 : g2;
|
|
11711
|
+
}, 0), l) + 2, c = u2.map((g2) => `${t("gray", h)} ${g2}${" ".repeat(n - D2(g2))}${t("gray", h)}`).join(`
|
|
11712
|
+
`), p2 = a ? `${t("gray", h)}
|
|
11713
|
+
` : "", f = a ? We : ge;
|
|
11714
|
+
i.write(`${p2}${t("green", V)} ${t("reset", r2)} ${t("gray", se.repeat(Math.max(n - l - 1, 1)) + pe)}
|
|
11715
|
+
${c}
|
|
11716
|
+
${t("gray", f + se.repeat(n + 2) + me)}
|
|
11717
|
+
`);
|
|
11718
|
+
};
|
|
11656
11719
|
var ze = { light: I2("\u2500", "-"), heavy: I2("\u2501", "="), block: I2("\u2588", "#") };
|
|
11657
11720
|
var oe = (e, r2) => e.includes(`
|
|
11658
11721
|
`) ? e.split(`
|
|
@@ -11837,7 +11900,7 @@ function createDefaultRegistry() {
|
|
|
11837
11900
|
var processFacet = {
|
|
11838
11901
|
id: "process",
|
|
11839
11902
|
label: "Process",
|
|
11840
|
-
description: "How
|
|
11903
|
+
description: "How will you guide your agent",
|
|
11841
11904
|
required: true,
|
|
11842
11905
|
options: [
|
|
11843
11906
|
{
|
|
@@ -12312,7 +12375,7 @@ var architectureFacet = {
|
|
|
12312
12375
|
var practicesFacet = {
|
|
12313
12376
|
id: "practices",
|
|
12314
12377
|
label: "Practices",
|
|
12315
|
-
description: "
|
|
12378
|
+
description: "Development practices \u2014 mix and match regardless of stack",
|
|
12316
12379
|
required: false,
|
|
12317
12380
|
multiSelect: true,
|
|
12318
12381
|
options: [
|
|
@@ -12544,7 +12607,7 @@ var JAVA_UNIT_TEST_RECIPE = [
|
|
|
12544
12607
|
var backpressureFacet = {
|
|
12545
12608
|
id: "backpressure",
|
|
12546
12609
|
label: "Backpressure",
|
|
12547
|
-
description: "
|
|
12610
|
+
description: "Which automated quality gates to put in place. Translates to git hooks",
|
|
12548
12611
|
required: false,
|
|
12549
12612
|
multiSelect: true,
|
|
12550
12613
|
dependsOn: ["architecture"],
|
|
@@ -12603,31 +12666,31 @@ var autonomyFacet = {
|
|
|
12603
12666
|
multiSelect: false,
|
|
12604
12667
|
options: [
|
|
12605
12668
|
{
|
|
12606
|
-
id: "
|
|
12607
|
-
label: "
|
|
12608
|
-
description: "
|
|
12669
|
+
id: "sensible-defaults",
|
|
12670
|
+
label: "Sensible defaults",
|
|
12671
|
+
description: "Allow a curated built-in capabilities set while keeping potentially risky actions approval-gated",
|
|
12609
12672
|
recipe: [
|
|
12610
12673
|
{
|
|
12611
12674
|
writer: "permission-policy",
|
|
12612
|
-
config: { profile: "
|
|
12675
|
+
config: { profile: "sensible-defaults" }
|
|
12613
12676
|
}
|
|
12614
12677
|
]
|
|
12615
12678
|
},
|
|
12616
12679
|
{
|
|
12617
|
-
id: "
|
|
12618
|
-
label: "
|
|
12619
|
-
description: "
|
|
12680
|
+
id: "rigid",
|
|
12681
|
+
label: "Rigid",
|
|
12682
|
+
description: "Keep built-in capabilities approval-gated and require confirmation before acting",
|
|
12620
12683
|
recipe: [
|
|
12621
12684
|
{
|
|
12622
12685
|
writer: "permission-policy",
|
|
12623
|
-
config: { profile: "
|
|
12686
|
+
config: { profile: "rigid" }
|
|
12624
12687
|
}
|
|
12625
12688
|
]
|
|
12626
12689
|
},
|
|
12627
12690
|
{
|
|
12628
12691
|
id: "max-autonomy",
|
|
12629
12692
|
label: "Max autonomy",
|
|
12630
|
-
description: "Allow broad local built-in autonomy
|
|
12693
|
+
description: "Allow broad local built-in autonomy. Recommended for sandboxed environments only",
|
|
12631
12694
|
recipe: [
|
|
12632
12695
|
{
|
|
12633
12696
|
writer: "permission-policy",
|
|
@@ -21824,7 +21887,7 @@ async function installSkills(skills, projectRoot) {
|
|
|
21824
21887
|
}
|
|
21825
21888
|
|
|
21826
21889
|
// ../harnesses/dist/util.js
|
|
21827
|
-
import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
21890
|
+
import { access as access2, mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
21828
21891
|
import { dirname as dirname5, join as join9 } from "path";
|
|
21829
21892
|
async function readJsonOrEmpty(path2) {
|
|
21830
21893
|
try {
|
|
@@ -21891,10 +21954,19 @@ async function writeAgentMd(config, opts) {
|
|
|
21891
21954
|
await writeFile4(opts.path, content, "utf-8");
|
|
21892
21955
|
}
|
|
21893
21956
|
async function writeGitHooks(hooks, projectRoot) {
|
|
21894
|
-
if (!hooks)
|
|
21957
|
+
if (!hooks || hooks.length === 0)
|
|
21958
|
+
return;
|
|
21959
|
+
const gitDir = join9(projectRoot, ".git");
|
|
21960
|
+
try {
|
|
21961
|
+
await access2(gitDir);
|
|
21962
|
+
} catch {
|
|
21963
|
+
R2.warn("Git hooks were configured but could not be installed: the project is not a git repository.\nRun `git init` and re-run setup to install the hooks.");
|
|
21895
21964
|
return;
|
|
21965
|
+
}
|
|
21966
|
+
const hooksDir = join9(gitDir, "hooks");
|
|
21967
|
+
await mkdir3(hooksDir, { recursive: true });
|
|
21896
21968
|
for (const hook of hooks) {
|
|
21897
|
-
const hookPath = join9(
|
|
21969
|
+
const hookPath = join9(hooksDir, hook.phase);
|
|
21898
21970
|
await writeFile4(hookPath, hook.script, { mode: 493 });
|
|
21899
21971
|
}
|
|
21900
21972
|
}
|
|
@@ -22434,7 +22506,27 @@ function getKiroAgentMcpServers(servers) {
|
|
|
22434
22506
|
|
|
22435
22507
|
// ../harnesses/dist/writers/opencode.js
|
|
22436
22508
|
import { join as join18 } from "path";
|
|
22509
|
+
var APPLICABLE_TO_ALL = {
|
|
22510
|
+
read: {
|
|
22511
|
+
"*": "allow",
|
|
22512
|
+
"*.env": "deny",
|
|
22513
|
+
"*.env.*": "deny",
|
|
22514
|
+
"*.env.example": "allow"
|
|
22515
|
+
},
|
|
22516
|
+
skill: "deny",
|
|
22517
|
+
//we're using an own skills-mcp
|
|
22518
|
+
todoread: "deny",
|
|
22519
|
+
//no agent-proprieatry todo tools
|
|
22520
|
+
todowrite: "deny",
|
|
22521
|
+
task: "deny",
|
|
22522
|
+
lsp: "allow",
|
|
22523
|
+
glob: "allow",
|
|
22524
|
+
grep: "allow",
|
|
22525
|
+
list: "allow",
|
|
22526
|
+
external_directory: "ask"
|
|
22527
|
+
};
|
|
22437
22528
|
var RIGID_RULES = {
|
|
22529
|
+
...APPLICABLE_TO_ALL,
|
|
22438
22530
|
"*": "ask",
|
|
22439
22531
|
webfetch: "ask",
|
|
22440
22532
|
websearch: "ask",
|
|
@@ -22443,31 +22535,17 @@ var RIGID_RULES = {
|
|
|
22443
22535
|
doom_loop: "deny"
|
|
22444
22536
|
};
|
|
22445
22537
|
var SENSIBLE_DEFAULTS_RULES = {
|
|
22446
|
-
|
|
22447
|
-
"*": "allow",
|
|
22448
|
-
"*.env": "deny",
|
|
22449
|
-
"*.env.*": "deny",
|
|
22450
|
-
"*.env.example": "allow"
|
|
22451
|
-
},
|
|
22538
|
+
...APPLICABLE_TO_ALL,
|
|
22452
22539
|
edit: "allow",
|
|
22453
|
-
glob: "allow",
|
|
22454
|
-
grep: "allow",
|
|
22455
|
-
list: "allow",
|
|
22456
|
-
lsp: "allow",
|
|
22457
|
-
task: "allow",
|
|
22458
|
-
todoread: "deny",
|
|
22459
|
-
todowrite: "deny",
|
|
22460
|
-
skill: "deny",
|
|
22461
22540
|
webfetch: "ask",
|
|
22462
22541
|
websearch: "ask",
|
|
22463
22542
|
codesearch: "ask",
|
|
22464
22543
|
bash: {
|
|
22465
|
-
"*": "
|
|
22544
|
+
"*": "ask",
|
|
22466
22545
|
"grep *": "allow",
|
|
22467
22546
|
"rg *": "allow",
|
|
22468
22547
|
"find *": "allow",
|
|
22469
22548
|
"fd *": "allow",
|
|
22470
|
-
ls: "allow",
|
|
22471
22549
|
"ls *": "allow",
|
|
22472
22550
|
"cat *": "allow",
|
|
22473
22551
|
"head *": "allow",
|
|
@@ -22502,14 +22580,7 @@ var SENSIBLE_DEFAULTS_RULES = {
|
|
|
22502
22580
|
"yq *": "allow",
|
|
22503
22581
|
"mkdir *": "allow",
|
|
22504
22582
|
"touch *": "allow",
|
|
22505
|
-
"
|
|
22506
|
-
"mv *": "ask",
|
|
22507
|
-
"ln *": "ask",
|
|
22508
|
-
"npm *": "ask",
|
|
22509
|
-
"node *": "ask",
|
|
22510
|
-
"pip *": "ask",
|
|
22511
|
-
"python *": "ask",
|
|
22512
|
-
"python3 *": "ask",
|
|
22583
|
+
"kill *": "ask",
|
|
22513
22584
|
"rm *": "deny",
|
|
22514
22585
|
"rmdir *": "deny",
|
|
22515
22586
|
"curl *": "deny",
|
|
@@ -22530,7 +22601,6 @@ var SENSIBLE_DEFAULTS_RULES = {
|
|
|
22530
22601
|
"mkfs *": "deny",
|
|
22531
22602
|
"mount *": "deny",
|
|
22532
22603
|
"umount *": "deny",
|
|
22533
|
-
"kill *": "deny",
|
|
22534
22604
|
"killall *": "deny",
|
|
22535
22605
|
"pkill *": "deny",
|
|
22536
22606
|
"nc *": "deny",
|
|
@@ -22550,15 +22620,14 @@ var SENSIBLE_DEFAULTS_RULES = {
|
|
|
22550
22620
|
"userdel *": "deny",
|
|
22551
22621
|
"iptables *": "deny"
|
|
22552
22622
|
},
|
|
22553
|
-
external_directory: "deny",
|
|
22554
22623
|
doom_loop: "deny"
|
|
22555
22624
|
};
|
|
22556
22625
|
var MAX_AUTONOMY_RULES = {
|
|
22626
|
+
...APPLICABLE_TO_ALL,
|
|
22557
22627
|
"*": "allow",
|
|
22558
22628
|
webfetch: "ask",
|
|
22559
22629
|
websearch: "ask",
|
|
22560
22630
|
codesearch: "ask",
|
|
22561
|
-
external_directory: "deny",
|
|
22562
22631
|
doom_loop: "deny"
|
|
22563
22632
|
};
|
|
22564
22633
|
function getPermissionRules(profile) {
|
|
@@ -22631,7 +22700,35 @@ function getHarnessIds() {
|
|
|
22631
22700
|
|
|
22632
22701
|
// src/commands/setup.ts
|
|
22633
22702
|
async function runSetup(projectRoot, catalog) {
|
|
22634
|
-
|
|
22703
|
+
let lineIndex = 0;
|
|
22704
|
+
const LOGO_LINES = [
|
|
22705
|
+
"\n",
|
|
22706
|
+
" \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
22707
|
+
"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557",
|
|
22708
|
+
"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D",
|
|
22709
|
+
"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D ",
|
|
22710
|
+
"\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 ",
|
|
22711
|
+
"\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D ",
|
|
22712
|
+
"\n"
|
|
22713
|
+
];
|
|
22714
|
+
for (const line of LOGO_LINES) {
|
|
22715
|
+
lineIndex++;
|
|
22716
|
+
if (lineIndex === 1) {
|
|
22717
|
+
Wt2(line);
|
|
22718
|
+
} else {
|
|
22719
|
+
console.log(`\u2502 ${line}`);
|
|
22720
|
+
}
|
|
22721
|
+
}
|
|
22722
|
+
Vt2(
|
|
22723
|
+
[
|
|
22724
|
+
"You're about to define how your team works with coding agents.",
|
|
22725
|
+
"",
|
|
22726
|
+
"Pick your facets \u2014 architecture, practices, process \u2014 and ADE",
|
|
22727
|
+
"translates them into a shared information hierarchy your agents",
|
|
22728
|
+
"read from the repo. One setup, consistent across the whole team."
|
|
22729
|
+
].join("\n"),
|
|
22730
|
+
"ADE \u2014 Agentic Development Environment"
|
|
22731
|
+
);
|
|
22635
22732
|
const existingConfig = await readUserConfig(projectRoot);
|
|
22636
22733
|
const existingChoices = existingConfig?.choices ?? {};
|
|
22637
22734
|
for (const [facetId, value] of Object.entries(existingChoices)) {
|
|
@@ -22676,7 +22773,7 @@ async function runSetup(projectRoot, catalog) {
|
|
|
22676
22773
|
let excludedDocsets;
|
|
22677
22774
|
if (impliedDocsets.length > 0) {
|
|
22678
22775
|
const selected = await Lt2({
|
|
22679
|
-
message: "Documentation \u2014
|
|
22776
|
+
message: "Documentation sources \u2014 Those will be pulled to your local disk for browsing on demand",
|
|
22680
22777
|
options: impliedDocsets.map((d3) => ({
|
|
22681
22778
|
value: d3.id,
|
|
22682
22779
|
label: d3.label,
|
|
@@ -22705,7 +22802,7 @@ async function runSetup(projectRoot, catalog) {
|
|
|
22705
22802
|
(h3) => allHarnessWriters.some((w2) => w2.id === h3)
|
|
22706
22803
|
);
|
|
22707
22804
|
const selectedHarnesses = await Lt2({
|
|
22708
|
-
message: "
|
|
22805
|
+
message: "Which coding agents should receive config?\nADE generates config files for each agent you select.\n",
|
|
22709
22806
|
options: harnessOptions,
|
|
22710
22807
|
initialValues: validExistingHarnesses && validExistingHarnesses.length > 0 ? validExistingHarnesses : ["universal"],
|
|
22711
22808
|
required: false
|
|
@@ -22746,7 +22843,27 @@ async function runSetup(projectRoot, catalog) {
|
|
|
22746
22843
|
To use the latest defaults, remove .ade/skills/ and re-run setup.`
|
|
22747
22844
|
);
|
|
22748
22845
|
}
|
|
22749
|
-
|
|
22846
|
+
if (logicalConfig.skills.length > 0) {
|
|
22847
|
+
const skillNames = logicalConfig.skills.map((s) => ` \u2022 ${s.name}`).join("\n");
|
|
22848
|
+
const confirmInstall = await Rt({
|
|
22849
|
+
message: `Install ${logicalConfig.skills.length} skill(s) now?
|
|
22850
|
+
` + skillNames + `
|
|
22851
|
+
You can also install them later with:
|
|
22852
|
+
npx @codemcp/skills experimental_install`,
|
|
22853
|
+
initialValue: true
|
|
22854
|
+
});
|
|
22855
|
+
if (typeof confirmInstall === "symbol") {
|
|
22856
|
+
Nt("Setup cancelled.");
|
|
22857
|
+
return;
|
|
22858
|
+
}
|
|
22859
|
+
if (confirmInstall) {
|
|
22860
|
+
await installSkills(logicalConfig.skills, projectRoot);
|
|
22861
|
+
} else {
|
|
22862
|
+
R2.info(
|
|
22863
|
+
"Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
|
|
22864
|
+
);
|
|
22865
|
+
}
|
|
22866
|
+
}
|
|
22750
22867
|
if (logicalConfig.knowledge_sources.length > 0) {
|
|
22751
22868
|
R2.info(
|
|
22752
22869
|
"Knowledge sources selected. Initialize them separately:\n npx @codemcp/knowledge init"
|
|
@@ -22779,7 +22896,7 @@ function promptSelect(facet, existingChoices) {
|
|
|
22779
22896
|
}
|
|
22780
22897
|
const initialValue = getValidInitialValue(facet, existingChoices);
|
|
22781
22898
|
return Jt({
|
|
22782
|
-
message: facet.label
|
|
22899
|
+
message: `${facet.label} \u2014 ${facet.description}`,
|
|
22783
22900
|
options: options2,
|
|
22784
22901
|
...initialValue !== void 0 && { initialValue }
|
|
22785
22902
|
});
|
|
@@ -22792,7 +22909,7 @@ function promptMultiSelect(facet, existingChoices) {
|
|
|
22792
22909
|
}));
|
|
22793
22910
|
const initialValues = getValidInitialValues(facet, existingChoices);
|
|
22794
22911
|
return Lt2({
|
|
22795
|
-
message: facet.label
|
|
22912
|
+
message: `${facet.label} \u2014 ${facet.description}`,
|
|
22796
22913
|
options: options2,
|
|
22797
22914
|
required: false,
|
|
22798
22915
|
...initialValues !== void 0 && { initialValues }
|
|
@@ -22831,7 +22948,23 @@ async function runInstall(projectRoot, harnessIds) {
|
|
|
22831
22948
|
To use the latest defaults, remove .ade/skills/ and re-run install.`
|
|
22832
22949
|
);
|
|
22833
22950
|
}
|
|
22834
|
-
|
|
22951
|
+
if (logicalConfig.skills.length > 0) {
|
|
22952
|
+
const confirmInstall = await Rt({
|
|
22953
|
+
message: `Install ${logicalConfig.skills.length} skill(s) now?`,
|
|
22954
|
+
initialValue: true
|
|
22955
|
+
});
|
|
22956
|
+
if (typeof confirmInstall === "symbol") {
|
|
22957
|
+
Nt("Install cancelled.");
|
|
22958
|
+
return;
|
|
22959
|
+
}
|
|
22960
|
+
if (confirmInstall) {
|
|
22961
|
+
await installSkills(logicalConfig.skills, projectRoot);
|
|
22962
|
+
} else {
|
|
22963
|
+
R2.info(
|
|
22964
|
+
"Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
|
|
22965
|
+
);
|
|
22966
|
+
}
|
|
22967
|
+
}
|
|
22835
22968
|
if (logicalConfig.knowledge_sources.length > 0) {
|
|
22836
22969
|
R2.info(
|
|
22837
22970
|
"Knowledge sources configured. Initialize them separately:\n npx @codemcp/knowledge init"
|
|
@@ -22861,7 +22994,14 @@ if (command === "setup") {
|
|
|
22861
22994
|
console.log(version);
|
|
22862
22995
|
} else {
|
|
22863
22996
|
const allIds = getHarnessIds();
|
|
22864
|
-
console.log(`ade v${version}`);
|
|
22997
|
+
console.log(`ade v${version} \u2014 Agentic Development Environment`);
|
|
22998
|
+
console.log();
|
|
22999
|
+
console.log(
|
|
23000
|
+
"Define how your team works with coding agents \u2014 pick your facets,"
|
|
23001
|
+
);
|
|
23002
|
+
console.log(
|
|
23003
|
+
"ADE translates them into a shared information hierarchy in your repo."
|
|
23004
|
+
);
|
|
22865
23005
|
console.log();
|
|
22866
23006
|
console.log("Usage: ade <command> [options]");
|
|
22867
23007
|
console.log();
|
|
@@ -6,11 +6,18 @@ import { join } from "node:path";
|
|
|
6
6
|
vi.mock("@clack/prompts", () => ({
|
|
7
7
|
intro: vi.fn(),
|
|
8
8
|
outro: vi.fn(),
|
|
9
|
+
note: vi.fn(),
|
|
9
10
|
select: vi.fn(),
|
|
10
11
|
multiselect: vi.fn(),
|
|
11
|
-
confirm: vi.fn(),
|
|
12
|
+
confirm: vi.fn().mockResolvedValue(true),
|
|
12
13
|
isCancel: vi.fn().mockReturnValue(false),
|
|
13
14
|
cancel: vi.fn(),
|
|
15
|
+
log: {
|
|
16
|
+
info: vi.fn(),
|
|
17
|
+
warn: vi.fn(),
|
|
18
|
+
error: vi.fn(),
|
|
19
|
+
success: vi.fn()
|
|
20
|
+
},
|
|
14
21
|
spinner: vi.fn().mockReturnValue({ start: vi.fn(), stop: vi.fn() })
|
|
15
22
|
}));
|
|
16
23
|
|
|
@@ -51,7 +51,25 @@ export async function runInstall(
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
if (logicalConfig.skills.length > 0) {
|
|
55
|
+
const confirmInstall = await clack.confirm({
|
|
56
|
+
message: `Install ${logicalConfig.skills.length} skill(s) now?`,
|
|
57
|
+
initialValue: true
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (typeof confirmInstall === "symbol") {
|
|
61
|
+
clack.cancel("Install cancelled.");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (confirmInstall) {
|
|
66
|
+
await installSkills(logicalConfig.skills, projectRoot);
|
|
67
|
+
} else {
|
|
68
|
+
clack.log.info(
|
|
69
|
+
"Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
55
73
|
|
|
56
74
|
if (logicalConfig.knowledge_sources.length > 0) {
|
|
57
75
|
clack.log.info(
|
|
@@ -7,11 +7,13 @@ import { join } from "node:path";
|
|
|
7
7
|
vi.mock("@clack/prompts", () => ({
|
|
8
8
|
intro: vi.fn(),
|
|
9
9
|
outro: vi.fn(),
|
|
10
|
+
note: vi.fn(),
|
|
10
11
|
select: vi.fn(),
|
|
11
12
|
multiselect: vi.fn(),
|
|
12
13
|
confirm: vi.fn(),
|
|
13
14
|
isCancel: vi.fn().mockReturnValue(false),
|
|
14
15
|
cancel: vi.fn(),
|
|
16
|
+
log: { info: vi.fn(), warn: vi.fn() },
|
|
15
17
|
spinner: vi.fn().mockReturnValue({ start: vi.fn(), stop: vi.fn() })
|
|
16
18
|
}));
|
|
17
19
|
|
|
@@ -6,6 +6,7 @@ import type { Catalog, LogicalConfig } from "@codemcp/ade-core";
|
|
|
6
6
|
vi.mock("@clack/prompts", () => ({
|
|
7
7
|
intro: vi.fn(),
|
|
8
8
|
outro: vi.fn(),
|
|
9
|
+
note: vi.fn(),
|
|
9
10
|
select: vi.fn(),
|
|
10
11
|
multiselect: vi.fn(),
|
|
11
12
|
confirm: vi.fn(),
|
|
@@ -298,7 +299,7 @@ describe("runSetup", () => {
|
|
|
298
299
|
expect(clack.multiselect).toHaveBeenCalledTimes(1);
|
|
299
300
|
expect(clack.multiselect).toHaveBeenCalledWith(
|
|
300
301
|
expect.objectContaining({
|
|
301
|
-
message: expect.stringContaining("
|
|
302
|
+
message: expect.stringContaining("coding agents")
|
|
302
303
|
})
|
|
303
304
|
);
|
|
304
305
|
});
|
|
@@ -26,7 +26,35 @@ export async function runSetup(
|
|
|
26
26
|
projectRoot: string,
|
|
27
27
|
catalog: Catalog
|
|
28
28
|
): Promise<void> {
|
|
29
|
-
|
|
29
|
+
let lineIndex = 0;
|
|
30
|
+
const LOGO_LINES = [
|
|
31
|
+
"\n",
|
|
32
|
+
" █████╗ ██████╗ ███████╗ ███████╗███████╗████████╗██╗ ██╗██████╗ ",
|
|
33
|
+
"██╔══██╗██╔══██╗██╔════╝ ██╔════╝██╔════╝╚══██╔══╝██║ ██║██╔══██╗",
|
|
34
|
+
"███████║██║ ██║█████╗ ███████╗█████╗ ██║ ██║ ██║██████╔╝",
|
|
35
|
+
"██╔══██║██║ ██║██╔══╝ ╚════██║██╔══╝ ██║ ██║ ██║██╔═══╝ ",
|
|
36
|
+
"██║ ██║██████╔╝███████╗ ███████║███████╗ ██║ ╚██████╔╝██║ ",
|
|
37
|
+
"╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ",
|
|
38
|
+
"\n"
|
|
39
|
+
];
|
|
40
|
+
for (const line of LOGO_LINES) {
|
|
41
|
+
lineIndex++;
|
|
42
|
+
if (lineIndex === 1) {
|
|
43
|
+
clack.intro(line);
|
|
44
|
+
} else {
|
|
45
|
+
console.log(`│ ${line}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
clack.note(
|
|
49
|
+
[
|
|
50
|
+
"You're about to define how your team works with coding agents.",
|
|
51
|
+
"",
|
|
52
|
+
"Pick your facets — architecture, practices, process — and ADE",
|
|
53
|
+
"translates them into a shared information hierarchy your agents",
|
|
54
|
+
"read from the repo. One setup, consistent across the whole team."
|
|
55
|
+
].join("\n"),
|
|
56
|
+
"ADE — Agentic Development Environment"
|
|
57
|
+
);
|
|
30
58
|
|
|
31
59
|
const existingConfig = await readUserConfig(projectRoot);
|
|
32
60
|
const existingChoices = existingConfig?.choices ?? {};
|
|
@@ -83,7 +111,8 @@ export async function runSetup(
|
|
|
83
111
|
|
|
84
112
|
if (impliedDocsets.length > 0) {
|
|
85
113
|
const selected = await clack.multiselect({
|
|
86
|
-
message:
|
|
114
|
+
message:
|
|
115
|
+
"Documentation sources — Those will be pulled to your local disk for browsing on demand",
|
|
87
116
|
options: impliedDocsets.map((d) => ({
|
|
88
117
|
value: d.id,
|
|
89
118
|
label: d.label,
|
|
@@ -120,7 +149,9 @@ export async function runSetup(
|
|
|
120
149
|
);
|
|
121
150
|
|
|
122
151
|
const selectedHarnesses = await clack.multiselect({
|
|
123
|
-
message:
|
|
152
|
+
message:
|
|
153
|
+
"Which coding agents should receive config?\n" +
|
|
154
|
+
"ADE generates config files for each agent you select.\n",
|
|
124
155
|
options: harnessOptions,
|
|
125
156
|
initialValues:
|
|
126
157
|
validExistingHarnesses && validExistingHarnesses.length > 0
|
|
@@ -172,7 +203,31 @@ export async function runSetup(
|
|
|
172
203
|
);
|
|
173
204
|
}
|
|
174
205
|
|
|
175
|
-
|
|
206
|
+
if (logicalConfig.skills.length > 0) {
|
|
207
|
+
const skillNames = logicalConfig.skills
|
|
208
|
+
.map((s) => ` • ${s.name}`)
|
|
209
|
+
.join("\n");
|
|
210
|
+
const confirmInstall = await clack.confirm({
|
|
211
|
+
message:
|
|
212
|
+
`Install ${logicalConfig.skills.length} skill(s) now?\n` +
|
|
213
|
+
skillNames +
|
|
214
|
+
`\nYou can also install them later with:\n npx @codemcp/skills experimental_install`,
|
|
215
|
+
initialValue: true
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
if (typeof confirmInstall === "symbol") {
|
|
219
|
+
clack.cancel("Setup cancelled.");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (confirmInstall) {
|
|
224
|
+
await installSkills(logicalConfig.skills, projectRoot);
|
|
225
|
+
} else {
|
|
226
|
+
clack.log.info(
|
|
227
|
+
"Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
176
231
|
|
|
177
232
|
if (logicalConfig.knowledge_sources.length > 0) {
|
|
178
233
|
clack.log.info(
|
|
@@ -225,7 +280,7 @@ function promptSelect(
|
|
|
225
280
|
const initialValue = getValidInitialValue(facet, existingChoices);
|
|
226
281
|
|
|
227
282
|
return clack.select({
|
|
228
|
-
message: facet.label
|
|
283
|
+
message: `${facet.label} — ${facet.description}`,
|
|
229
284
|
options,
|
|
230
285
|
...(initialValue !== undefined && { initialValue })
|
|
231
286
|
});
|
|
@@ -244,7 +299,7 @@ function promptMultiSelect(
|
|
|
244
299
|
const initialValues = getValidInitialValues(facet, existingChoices);
|
|
245
300
|
|
|
246
301
|
return clack.multiselect({
|
|
247
|
-
message: facet.label
|
|
302
|
+
message: `${facet.label} — ${facet.description}`,
|
|
248
303
|
options,
|
|
249
304
|
required: false,
|
|
250
305
|
...(initialValues !== undefined && { initialValues })
|
|
@@ -31,7 +31,14 @@ if (command === "setup") {
|
|
|
31
31
|
console.log(version);
|
|
32
32
|
} else {
|
|
33
33
|
const allIds = getHarnessIds();
|
|
34
|
-
console.log(`ade v${version}`);
|
|
34
|
+
console.log(`ade v${version} — Agentic Development Environment`);
|
|
35
|
+
console.log();
|
|
36
|
+
console.log(
|
|
37
|
+
"Define how your team works with coding agents — pick your facets,"
|
|
38
|
+
);
|
|
39
|
+
console.log(
|
|
40
|
+
"ADE translates them into a shared information hierarchy in your repo."
|
|
41
|
+
);
|
|
35
42
|
console.log();
|
|
36
43
|
console.log("Usage: ade <command> [options]");
|
|
37
44
|
console.log();
|
|
@@ -470,8 +470,8 @@ describe("catalog", () => {
|
|
|
470
470
|
expect(autonomy!.required).toBe(false);
|
|
471
471
|
expect(autonomy!.multiSelect).toBe(false);
|
|
472
472
|
expect(autonomy!.options.map((option) => option.id)).toEqual([
|
|
473
|
-
"rigid",
|
|
474
473
|
"sensible-defaults",
|
|
474
|
+
"rigid",
|
|
475
475
|
"max-autonomy"
|
|
476
476
|
]);
|
|
477
477
|
});
|