@aperant/framework 0.8.7 → 0.10.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.
Files changed (111) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/agents/apt-pr-review-fixer.md +9 -4
  3. package/agents/apt-verifier.md +6 -3
  4. package/dist/cli/commands/init.d.mts.map +1 -1
  5. package/dist/cli/commands/init.mjs +157 -23
  6. package/dist/cli/commands/init.mjs.map +1 -1
  7. package/dist/cli/commands/toolchain-detect.d.mts.map +1 -1
  8. package/dist/cli/commands/toolchain-detect.mjs +44 -0
  9. package/dist/cli/commands/toolchain-detect.mjs.map +1 -1
  10. package/dist/cli/commands/triage.d.mts.map +1 -1
  11. package/dist/cli/commands/triage.mjs +346 -13
  12. package/dist/cli/commands/triage.mjs.map +1 -1
  13. package/dist/cli/commands/uninstall.d.mts.map +1 -1
  14. package/dist/cli/commands/uninstall.mjs +11 -8
  15. package/dist/cli/commands/uninstall.mjs.map +1 -1
  16. package/dist/cli/consistency/parse-review.mjs +5 -3
  17. package/dist/cli/consistency/parse-review.mjs.map +1 -1
  18. package/dist/cli/consistency/rules/r5-verdict-consistency.d.mts.map +1 -1
  19. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs +10 -8
  20. package/dist/cli/consistency/rules/r5-verdict-consistency.mjs.map +1 -1
  21. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  22. package/dist/cli/gate/gates/review-clean.mjs +4 -2
  23. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  24. package/dist/cli/install/mcp-provision.d.mts +26 -0
  25. package/dist/cli/install/mcp-provision.d.mts.map +1 -0
  26. package/dist/cli/install/mcp-provision.mjs +281 -0
  27. package/dist/cli/install/mcp-provision.mjs.map +1 -0
  28. package/dist/cli/install/mcp-server-specs.d.mts +80 -0
  29. package/dist/cli/install/mcp-server-specs.d.mts.map +1 -0
  30. package/dist/cli/install/mcp-server-specs.mjs +102 -0
  31. package/dist/cli/install/mcp-server-specs.mjs.map +1 -0
  32. package/dist/cli/install/runtime-detect.d.mts +27 -0
  33. package/dist/cli/install/runtime-detect.d.mts.map +1 -1
  34. package/dist/cli/install/runtime-detect.mjs +32 -0
  35. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  36. package/dist/cli/install/toml-merge.d.mts +40 -0
  37. package/dist/cli/install/toml-merge.d.mts.map +1 -0
  38. package/dist/cli/install/toml-merge.mjs +134 -0
  39. package/dist/cli/install/toml-merge.mjs.map +1 -0
  40. package/dist/cli/util/aperant-section.d.mts +12 -0
  41. package/dist/cli/util/aperant-section.d.mts.map +1 -1
  42. package/dist/cli/util/aperant-section.mjs +12 -0
  43. package/dist/cli/util/aperant-section.mjs.map +1 -1
  44. package/dist/cli/util/copy.d.mts +27 -0
  45. package/dist/cli/util/copy.d.mts.map +1 -1
  46. package/dist/cli/util/copy.mjs +49 -5
  47. package/dist/cli/util/copy.mjs.map +1 -1
  48. package/dist/cli/util/events-path.d.mts +8 -0
  49. package/dist/cli/util/events-path.d.mts.map +1 -0
  50. package/dist/cli/util/events-path.mjs +23 -0
  51. package/dist/cli/util/events-path.mjs.map +1 -0
  52. package/dist/cli/util/runtime-capabilities.d.mts +30 -0
  53. package/dist/cli/util/runtime-capabilities.d.mts.map +1 -0
  54. package/dist/cli/util/runtime-capabilities.mjs +214 -0
  55. package/dist/cli/util/runtime-capabilities.mjs.map +1 -0
  56. package/dist/cli/verify-proof/audit.d.mts +2 -7
  57. package/dist/cli/verify-proof/audit.d.mts.map +1 -1
  58. package/dist/cli/verify-proof/audit.mjs +11 -17
  59. package/dist/cli/verify-proof/audit.mjs.map +1 -1
  60. package/dist/cli/verify-proof/idl/index.d.mts +12 -1
  61. package/dist/cli/verify-proof/idl/index.d.mts.map +1 -1
  62. package/dist/cli/verify-proof/idl/index.mjs +50 -1
  63. package/dist/cli/verify-proof/idl/index.mjs.map +1 -1
  64. package/dist/cli/verify-proof/resolver.d.mts.map +1 -1
  65. package/dist/cli/verify-proof/resolver.mjs +51 -1
  66. package/dist/cli/verify-proof/resolver.mjs.map +1 -1
  67. package/dist/cli/verify-proof/runtime-detect.d.mts +2 -29
  68. package/dist/cli/verify-proof/runtime-detect.d.mts.map +1 -1
  69. package/dist/cli/verify-proof/runtime-detect.mjs +8 -203
  70. package/dist/cli/verify-proof/runtime-detect.mjs.map +1 -1
  71. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  72. package/dist/plugin/agents/apt-pr-review-fixer.md +9 -4
  73. package/dist/plugin/agents/apt-verifier.md +6 -3
  74. package/dist/plugin/skills/apt-pr-review/SKILL.md +106 -15
  75. package/dist/plugin/skills/apt-setup/SKILL.md +7 -6
  76. package/dist/plugin/skills/apt-triage/SKILL.md +8 -6
  77. package/dist/plugin/skills/apt-update/SKILL.md +1 -1
  78. package/dist/plugin/skills/apt-verify/SKILL.md +1 -1
  79. package/dist/plugin/skills/apt-verify-proof/SKILL.md +25 -1
  80. package/drivers/browser/skill/agent-browser/SKILL.md +51 -0
  81. package/drivers/tauri/README.md +107 -0
  82. package/drivers/tauri/driver.mjs +88 -0
  83. package/drivers/tauri/manifest.json +37 -0
  84. package/drivers/tauri/scripts/tauri-mcp.sh +41 -0
  85. package/package.json +1 -1
  86. package/skills/apt-pr-review/SKILL.md +106 -15
  87. package/skills/apt-setup/SKILL.md +7 -6
  88. package/skills/apt-triage/SKILL.md +8 -6
  89. package/skills/apt-update/SKILL.md +1 -1
  90. package/skills/apt-verify/SKILL.md +1 -1
  91. package/skills/apt-verify-proof/SKILL.md +25 -1
  92. package/src/cli/commands/init.mjs +163 -19
  93. package/src/cli/commands/toolchain-detect.mjs +44 -0
  94. package/src/cli/commands/triage.mjs +352 -11
  95. package/src/cli/commands/uninstall.mjs +11 -8
  96. package/src/cli/consistency/parse-review.mjs +5 -3
  97. package/src/cli/consistency/rules/r5-verdict-consistency.mjs +14 -9
  98. package/src/cli/gate/gates/review-clean.mjs +4 -2
  99. package/src/cli/install/mcp-provision.mjs +293 -0
  100. package/src/cli/install/mcp-server-specs.mjs +101 -0
  101. package/src/cli/install/runtime-detect.mjs +36 -0
  102. package/src/cli/install/toml-merge.mjs +139 -0
  103. package/src/cli/util/aperant-section.mjs +14 -0
  104. package/src/cli/util/copy.mjs +53 -8
  105. package/src/cli/util/events-path.mjs +24 -0
  106. package/src/cli/util/runtime-capabilities.mjs +216 -0
  107. package/src/cli/verify-proof/audit.mjs +11 -17
  108. package/src/cli/verify-proof/idl/index.mjs +49 -11
  109. package/src/cli/verify-proof/resolver.mjs +49 -2
  110. package/src/cli/verify-proof/runtime-detect.mjs +11 -204
  111. package/templates/config.json +2 -1
@@ -3,12 +3,13 @@
3
3
  * consistency/rules/r5-verdict-consistency.mjs — R5 (C15).
4
4
  *
5
5
  * Fails when:
6
- * - qa.verdict === 'approved' AND review has >=1 unresolved critical finding
6
+ * - qa.verdict === 'approved' or 'approved-with-notes' AND review has >=1
7
+ * unresolved critical or major finding
7
8
  * - qa.verdict === 'rejected' AND qa has no findings at all AND review has
8
9
  * zero unresolved findings (rejected-without-evidence)
9
10
  *
10
- * `approved-with-notes` is the escape hatch passes regardless of unresolved
11
- * criticals in review.json.
11
+ * `approved-with-notes` no longer escapes unresolved critical or major
12
+ * findings (G42 Phase 1). It still passes for lower-severity issues.
12
13
  *
13
14
  * Severity: error. Stages: verify, ship.
14
15
  */
@@ -24,21 +25,22 @@ const rule = {
24
25
  }
25
26
  const verdict = parsed.qa.verdict ?? 'unknown';
26
27
  const reviewFindings = parsed?.review?.findings ?? [];
27
- const unresolvedCritical = reviewFindings.filter((f) => f.severity === 'critical' && f.status !== 'fixed');
28
- if (verdict === 'approved' && unresolvedCritical.length > 0) {
28
+ const unresolvedBlocking = reviewFindings.filter((f) => (f.severity === 'critical' || f.severity === 'major') && f.status !== 'fixed');
29
+ if ((verdict === 'approved' || verdict === 'approved-with-notes') &&
30
+ unresolvedBlocking.length > 0) {
29
31
  return {
30
32
  status: 'fail',
31
33
  drift: [
32
34
  {
33
35
  verdict,
34
- blockers: unresolvedCritical.map((f) => ({
36
+ blockers: unresolvedBlocking.map((f) => ({
35
37
  id: f.id,
36
38
  title: f.title,
37
39
  })),
38
- reason: 'approved verdict with unresolved critical finding(s)',
40
+ reason: 'approved/approved-with-notes verdict with unresolved critical or major finding(s) (G42 Phase 1)',
39
41
  },
40
42
  ],
41
- reason: `approved verdict contradicts ${unresolvedCritical.length} unresolved critical finding(s)`,
43
+ reason: `approved/approved-with-notes verdict contradicts ${unresolvedBlocking.length} unresolved critical/major finding(s)`,
42
44
  };
43
45
  }
44
46
  if (verdict === 'rejected') {
@@ -1 +1 @@
1
- {"version":3,"file":"r5-verdict-consistency.mjs","sourceRoot":"","sources":["../../../../src/cli/consistency/rules/r5-verdict-consistency.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,IAAI,GAAG;IACZ,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,OAAO;IACjB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,wDAAwD;IACrE,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE;QACrB,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;YAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAA;QAC5E,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,SAAS,CAAA;QAC9C,MAAM,cAAc,GAAG,MAAM,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAA;QACrD,MAAM,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CACxD,CAAA;QACD,IAAI,OAAO,KAAK,UAAU,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,KAAK,EAAE;oBACN;wBACC,OAAO;wBACP,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACxC,EAAE,EAAE,CAAC,CAAC,EAAE;4BACR,KAAK,EAAE,CAAC,CAAC,KAAK;yBACd,CAAC,CAAC;wBACH,MAAM,EAAE,sDAAsD;qBAC9D;iBACD;gBACD,MAAM,EAAE,gCAAgC,kBAAkB,CAAC,MAAM,iCAAiC;aAClG,CAAA;QACF,CAAC;QACD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAA;YAC3C,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAA;YAC5E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACrD,OAAO;oBACN,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE;wBACN;4BACC,OAAO;4BACP,QAAQ,EAAE,EAAE;4BACZ,MAAM,EAAE,6CAA6C;yBACrD;qBACD;oBACD,MAAM,EAAE,6CAA6C;iBACrD,CAAA;YACF,CAAC;QACF,CAAC;QACD,OAAO;YACN,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,WAAW,OAAO,qCAAqC;SAC/D,CAAA;IACF,CAAC;CACD,CAAA;AAED,YAAY,CAAC,IAAI,CAAC,CAAA;AAClB,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"r5-verdict-consistency.mjs","sourceRoot":"","sources":["../../../../src/cli/consistency/rules/r5-verdict-consistency.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,IAAI,GAAG;IACZ,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,OAAO;IACjB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,wDAAwD;IACrE,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE;QACrB,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;YAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAA;QAC5E,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,SAAS,CAAA;QAC9C,MAAM,cAAc,GAAG,MAAM,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAA;QACrD,MAAM,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CACpF,CAAA;QACD,IACC,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,qBAAqB,CAAC;YAC7D,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAC5B,CAAC;YACF,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,KAAK,EAAE;oBACN;wBACC,OAAO;wBACP,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACxC,EAAE,EAAE,CAAC,CAAC,EAAE;4BACR,KAAK,EAAE,CAAC,CAAC,KAAK;yBACd,CAAC,CAAC;wBACH,MAAM,EACL,iGAAiG;qBAClG;iBACD;gBACD,MAAM,EAAE,oDAAoD,kBAAkB,CAAC,MAAM,uCAAuC;aAC5H,CAAA;QACF,CAAC;QACD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAA;YAC3C,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAA;YAC5E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACrD,OAAO;oBACN,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE;wBACN;4BACC,OAAO;4BACP,QAAQ,EAAE,EAAE;4BACZ,MAAM,EAAE,6CAA6C;yBACrD;qBACD;oBACD,MAAM,EAAE,6CAA6C;iBACrD,CAAA;YACF,CAAC;QACF,CAAC;QACD,OAAO;YACN,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,WAAW,OAAO,qCAAqC;SAC/D,CAAA;IACF,CAAC;CACD,CAAA;AAED,YAAY,CAAC,IAAI,CAAC,CAAA;AAClB,eAAe,IAAI,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"review-clean.d.mts","sourceRoot":"","sources":["../../../../src/cli/gate/gates/review-clean.mjs"],"names":[],"mappings":";;;;;;IA4BqB,+CAAwC;IAC5D;;;;;;;;;;;;;;;;OAiDC"}
1
+ {"version":3,"file":"review-clean.d.mts","sourceRoot":"","sources":["../../../../src/cli/gate/gates/review-clean.mjs"],"names":[],"mappings":";;;;;;IA8BqB,+CAAwC;IAC5D;;;;;;;;;;;;;;;;OAiDC"}
@@ -8,7 +8,9 @@
8
8
  * shapes the reviewer skill writes: `fixed: true`, `resolved: true`,
9
9
  * `status: "fixed"` (string), and `status: "deferred-*"` variants
10
10
  * (BUG-009). Fails if any post-normalization finding is severity
11
- * critical|major AND status is neither `fixed` nor `deferred`.
11
+ * critical|major AND status is not `fixed`. `deferred` no longer clears
12
+ * blocking findings (G42 Phase 1 — only `--force --reason` override may
13
+ * bypass blocking severity deferrals).
12
14
  */
13
15
  import { existsSync, readFileSync } from 'node:fs';
14
16
  import { join } from 'node:path';
@@ -52,7 +54,7 @@ const gate = {
52
54
  // shapes the reviewer skill writes; this delegation closes that
53
55
  // hole and picks up `deferred-*` variants for free.
54
56
  const { findings: normalized } = parseReview(doc);
55
- const unresolved = normalized.filter((f) => POST_NORM_BLOCKING.has(f.severity) && f.status !== 'fixed' && f.status !== 'deferred');
57
+ const unresolved = normalized.filter((f) => POST_NORM_BLOCKING.has(f.severity) && f.status !== 'fixed');
56
58
  if (unresolved.length > 0) {
57
59
  return {
58
60
  status: 'fail',
@@ -1 +1 @@
1
- {"version":3,"file":"review-clean.mjs","sourceRoot":"","sources":["../../../../src/cli/gate/gates/review-clean.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,uEAAuE;AACvE,oEAAoE;AACpE,aAAa;AACb,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAEzD,MAAM,IAAI,GAAG;IACZ,EAAE,EAAE,cAAc;IAClB,WAAW,EAAE,2EAA2E;IACxF,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,eAAe;IAC5D,KAAK,CAAC,KAAK,CAAC,GAAG;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAA;QACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,iDAAiD;gBACzD,MAAM;aACN,CAAA;QACF,CAAC;QACD,IAAI,GAAG,CAAA;QACP,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,+BAA+B,GAAG,CAAC,OAAO,EAAE;gBACpD,MAAM;aACN,CAAA;QACF,CAAC;QACD,8DAA8D;QAC9D,6DAA6D;QAC7D,mEAAmE;QACnE,8DAA8D;QAC9D,gEAAgE;QAChE,oDAAoD;QACpD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QACjD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,CAC5F,CAAA;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,sDAAsD;gBAClF,QAAQ,EAAE;oBACT,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAClC,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,IAAI;wBAChB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;qBACtB,CAAC,CAAC;iBACH;gBACD,MAAM;aACN,CAAA;QACF,CAAC;QACD,OAAO;YACN,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,0DAA0D,UAAU,CAAC,MAAM,SAAS;YAC5F,MAAM;SACN,CAAA;IACF,CAAC;CACD,CAAA;AAED,YAAY,CAAC,IAAI,CAAC,CAAA;AAClB,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"review-clean.mjs","sourceRoot":"","sources":["../../../../src/cli/gate/gates/review-clean.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,uEAAuE;AACvE,oEAAoE;AACpE,aAAa;AACb,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAEzD,MAAM,IAAI,GAAG;IACZ,EAAE,EAAE,cAAc;IAClB,WAAW,EAAE,2EAA2E;IACxF,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,eAAe;IAC5D,KAAK,CAAC,KAAK,CAAC,GAAG;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAA;QACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,iDAAiD;gBACzD,MAAM;aACN,CAAA;QACF,CAAC;QACD,IAAI,GAAG,CAAA;QACP,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,+BAA+B,GAAG,CAAC,OAAO,EAAE;gBACpD,MAAM;aACN,CAAA;QACF,CAAC;QACD,8DAA8D;QAC9D,6DAA6D;QAC7D,mEAAmE;QACnE,8DAA8D;QAC9D,gEAAgE;QAChE,oDAAoD;QACpD,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QACjD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CACjE,CAAA;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACN,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,sDAAsD;gBAClF,QAAQ,EAAE;oBACT,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAClC,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,IAAI;wBAChB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;qBACtB,CAAC,CAAC;iBACH;gBACD,MAAM;aACN,CAAA;QACF,CAAC;QACD,OAAO;YACN,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,0DAA0D,UAAU,CAAC,MAAM,SAAS;YAC5F,MAAM;SACN,CAAA;IACF,CAAC;CACD,CAAA;AAED,YAAY,CAAC,IAAI,CAAC,CAAA;AAClB,eAAe,IAAI,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Provision MCP servers + skills for the selected host CLIs.
3
+ *
4
+ * @param {Object} opts
5
+ * @param {string} opts.targetDir — project root being installed into
6
+ * @param {string[]} opts.selectedRuntimes — the runtimes the user selected
7
+ * @param {object} opts.config — the effective merged project config
8
+ * @param {string} opts.frameworkRoot — absolute path to packages/framework (for vendored skill resolution)
9
+ * @returns {{status: 'ok'|'disabled'|'error', writes?: Array<{host:string, spec_id:string, kind:string, action:string}>, reason?: string}}
10
+ */
11
+ export function provisionMcpConfig(opts: {
12
+ targetDir: string;
13
+ selectedRuntimes: string[];
14
+ config: object;
15
+ frameworkRoot: string;
16
+ }): {
17
+ status: "ok" | "disabled" | "error";
18
+ writes?: Array<{
19
+ host: string;
20
+ spec_id: string;
21
+ kind: string;
22
+ action: string;
23
+ }>;
24
+ reason?: string;
25
+ };
26
+ //# sourceMappingURL=mcp-provision.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-provision.d.mts","sourceRoot":"","sources":["../../../src/cli/install/mcp-provision.mjs"],"names":[],"mappings":"AAgJA;;;;;;;;;GASG;AACH,yCANG;IAAqB,SAAS,EAAtB,MAAM;IACS,gBAAgB,EAA/B,MAAM,EAAE;IACK,MAAM,EAAnB,MAAM;IACO,aAAa,EAA1B,MAAM;CACd,GAAU;IAAC,MAAM,EAAE,IAAI,GAAC,UAAU,GAAC,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAC,MAAM,EAAC,MAAM,CAAA;KAAC,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,CAmFzI"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * install/mcp-provision.mjs — TOFU install-time MCP-server + skill provisioner.
3
+ *
4
+ * Called from cmdInit (the only call site — the QUICK fast-path never invokes
5
+ * init, so the Fast Path Guarantee is structurally untouched). Detects the
6
+ * project's runtime, then for each selected host CLI that supports the action:
7
+ *
8
+ * - kind 'mcp-server' (electron/tauri) → write the server into the host's
9
+ * MCP config (claude → .mcp.json JSON merge; codex → .codex/config.toml
10
+ * TOML upsert).
11
+ * - kind 'skill' (agent-browser) → copy the vendored SKILL.md into the
12
+ * host's skill dir (claude → .claude/skills/; codex → .agents/skills/).
13
+ *
14
+ * Every write is TOFU/idempotent (ID-05): if the target server id / table /
15
+ * skill file already exists, SKIP (never diff/merge/overwrite) — this is the
16
+ * must-not-clobber invariant for a hand-authored electron
17
+ * SCREENSHOT_ENCRYPTION_KEY (US-3) and a user-edited agent-browser skill
18
+ * (US-6). Each action appends one audit line to .aperant/events/{date}.jsonl.
19
+ *
20
+ * Gated behind config.verification.provision_mcp (default true) so users can
21
+ * opt out. Never throws — wraps the body in try/catch → {status:'error'}.
22
+ */
23
+ import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
24
+ import { basename, dirname, join, resolve } from 'node:path';
25
+ import { appendJsonl, atomicWriteJson, atomicWriteText } from '../util/atomic-write.mjs';
26
+ import { dailyEventsPath } from '../util/events-path.mjs';
27
+ import { capabilityToProvisionIds, PROVISION_SPECS } from './mcp-server-specs.mjs';
28
+ import { loadRuntimeCapabilities } from './runtime-detect.mjs';
29
+ import { upsertMcpServerToml } from './toml-merge.mjs';
30
+ /**
31
+ * Per-host writer registry (ID-07, ID-08). v1 = claude + codex. The MCP
32
+ * config path AND skill dir are EXPLICIT per host — neither is derived from
33
+ * the runtime's installRoot (Codex's MCP path .codex/config.toml diverges
34
+ * from its skill dir .agents/skills/). Adding gemini/opencode later = one
35
+ * entry each.
36
+ *
37
+ * @type {Record<string, {mcpFormat: 'json'|'toml', mcpConfigPath: string, skillDir: string}>}
38
+ */
39
+ const HOST_PROVISION_WRITERS = {
40
+ claude: { mcpFormat: 'json', mcpConfigPath: '.mcp.json', skillDir: '.claude/skills' },
41
+ codex: { mcpFormat: 'toml', mcpConfigPath: '.codex/config.toml', skillDir: '.agents/skills' },
42
+ };
43
+ /**
44
+ * Substitute the per-project socket basename into the tauri launcher
45
+ * template, deriving uniqueness from the project dir basename.
46
+ *
47
+ * @param {string} template
48
+ * @param {string} targetDir
49
+ * @returns {string}
50
+ */
51
+ function renderTauriLauncher(template, targetDir) {
52
+ const slug = basename(resolve(targetDir))
53
+ .toLowerCase()
54
+ .replace(/[^a-z0-9]+/g, '-')
55
+ .replace(/^-+|-+$/g, '') || 'tauri';
56
+ return template.replaceAll('{{PROJECT_SOCKET}}', slug);
57
+ }
58
+ /**
59
+ * Write the electron/tauri MCP server into a Claude `.mcp.json`. JSON merge:
60
+ * read-or-{}, ensure mcpServers, SKIP if the server id already exists, else
61
+ * insert {type:'stdio', command, args, env?} preserving all sibling keys.
62
+ *
63
+ * TOFU non-clobber (ID-05): if the existing file fails to parse OR parses to
64
+ * a non-plain-object root (array / null / primitive), do NOT overwrite it —
65
+ * return `skipped_unsafe` with a reason so the caller can audit it and leave
66
+ * the file byte-identical. (`typeof [] === 'object'` is why arrays must be
67
+ * excluded explicitly: a `.mcp.json` containing `[]` would otherwise pass the
68
+ * object guard, drop the user's content on stringify, and report `written`.)
69
+ *
70
+ * @param {string} configPath — absolute path to .mcp.json
71
+ * @param {string} serverId
72
+ * @param {import('./mcp-server-specs.mjs').McpServerSpec} spec
73
+ * @returns {{action: 'written'|'skipped'|'skipped_unsafe', reason?: string}}
74
+ */
75
+ function writeClaudeMcpServer(configPath, serverId, spec) {
76
+ let config = {};
77
+ if (existsSync(configPath)) {
78
+ try {
79
+ config = JSON.parse(readFileSync(configPath, 'utf-8'));
80
+ }
81
+ catch {
82
+ // Malformed JSON: overwriting would erase every hand-authored MCP
83
+ // server. Leave the file untouched and surface it.
84
+ return { action: 'skipped_unsafe', reason: 'malformed_json' };
85
+ }
86
+ if (config === null || typeof config !== 'object' || Array.isArray(config)) {
87
+ // Non-plain-object root (array / null / primitive): same non-clobber
88
+ // rule — never overwrite content we cannot safely merge into.
89
+ return { action: 'skipped_unsafe', reason: 'non_object_root' };
90
+ }
91
+ }
92
+ if (config.mcpServers === null || typeof config.mcpServers !== 'object') {
93
+ config.mcpServers = {};
94
+ }
95
+ // TOFU: never clobber a hand-authored server id.
96
+ if (Object.hasOwn(config.mcpServers, serverId))
97
+ return { action: 'skipped' };
98
+ const entry = { type: 'stdio', command: spec.command, args: spec.args ?? [] };
99
+ if (spec.env && Object.keys(spec.env).length > 0)
100
+ entry.env = spec.env;
101
+ config.mcpServers[serverId] = entry;
102
+ atomicWriteJson(configPath, config);
103
+ return { action: 'written' };
104
+ }
105
+ /**
106
+ * Write the electron/tauri MCP server into a Codex `.codex/config.toml`.
107
+ *
108
+ * @param {string} configPath — absolute path to .codex/config.toml
109
+ * @param {string} serverId
110
+ * @param {import('./mcp-server-specs.mjs').McpServerSpec} spec
111
+ * @returns {{action: 'written'|'skipped'}}
112
+ */
113
+ function writeCodexMcpServer(configPath, serverId, spec) {
114
+ const existing = existsSync(configPath) ? readFileSync(configPath, 'utf-8') : '';
115
+ const { content, action } = upsertMcpServerToml(existing, serverId, {
116
+ command: spec.command,
117
+ args: spec.args ?? [],
118
+ ...(spec.env && Object.keys(spec.env).length > 0 ? { env: spec.env } : {}),
119
+ });
120
+ if (action === 'written')
121
+ atomicWriteText(configPath, content);
122
+ return { action };
123
+ }
124
+ /**
125
+ * Copy the vendored skill into a host skill dir. TOFU: never overwrite an
126
+ * existing agent-browser/SKILL.md (a user may have edited it).
127
+ *
128
+ * @param {string} skillDestPath — absolute <skillDir>/<skillId>/SKILL.md
129
+ * @param {string} vendoredSkillPath — absolute source path
130
+ * @returns {'written'|'skipped'}
131
+ */
132
+ function copySkill(skillDestPath, vendoredSkillPath) {
133
+ if (existsSync(skillDestPath))
134
+ return 'skipped';
135
+ mkdirSync(dirname(skillDestPath), { recursive: true });
136
+ // copyFileSync is fine here — atomicWriteText would re-read; the dest is
137
+ // guaranteed absent (TOFU check above) so there is no clobber risk.
138
+ copyFileSync(vendoredSkillPath, skillDestPath);
139
+ return 'written';
140
+ }
141
+ /**
142
+ * Provision MCP servers + skills for the selected host CLIs.
143
+ *
144
+ * @param {Object} opts
145
+ * @param {string} opts.targetDir — project root being installed into
146
+ * @param {string[]} opts.selectedRuntimes — the runtimes the user selected
147
+ * @param {object} opts.config — the effective merged project config
148
+ * @param {string} opts.frameworkRoot — absolute path to packages/framework (for vendored skill resolution)
149
+ * @returns {{status: 'ok'|'disabled'|'error', writes?: Array<{host:string, spec_id:string, kind:string, action:string}>, reason?: string}}
150
+ */
151
+ export function provisionMcpConfig(opts) {
152
+ const targetDir = resolve(opts.targetDir);
153
+ const config = opts.config ?? {};
154
+ const selected = Array.isArray(opts.selectedRuntimes) ? opts.selectedRuntimes : [];
155
+ const frameworkRoot = opts.frameworkRoot;
156
+ try {
157
+ // (1) Opt-out gate (default true).
158
+ if (config?.verification?.provision_mcp === false) {
159
+ appendEvent(targetDir, 'mcp-provision.disabled', {
160
+ reason: 'verification.provision_mcp=false',
161
+ });
162
+ return { status: 'disabled' };
163
+ }
164
+ // (2) Detect runtime → derive spec ids.
165
+ const runtimeCaps = loadRuntimeCapabilities(targetDir);
166
+ const specIds = capabilityToProvisionIds(runtimeCaps);
167
+ /** @type {Array<{host:string, spec_id:string, kind:string, action:string}>} */
168
+ const writes = [];
169
+ // Iterate every (selected host, spec) pair.
170
+ for (const host of selected) {
171
+ const writer = HOST_PROVISION_WRITERS[host];
172
+ if (!writer) {
173
+ // Selected host with no writer (gemini/opencode/... in v1) — record
174
+ // once as unsupported_host, no write.
175
+ writes.push({ host, spec_id: '*', kind: '*', action: 'unsupported_host' });
176
+ appendEvent(targetDir, 'mcp-provision.unsupported_host', { host });
177
+ continue;
178
+ }
179
+ for (const specId of specIds) {
180
+ const spec = PROVISION_SPECS[specId];
181
+ if (!spec)
182
+ continue;
183
+ if (spec.kind === 'mcp-server') {
184
+ const configPath = join(targetDir, writer.mcpConfigPath);
185
+ const { action, reason } = writer.mcpFormat === 'json'
186
+ ? writeClaudeMcpServer(configPath, specId, spec)
187
+ : writeCodexMcpServer(configPath, specId, spec);
188
+ writes.push({ host, spec_id: specId, kind: 'mcp-server', action });
189
+ appendEvent(targetDir, `mcp-provision.${action}`, {
190
+ host,
191
+ spec_id: specId,
192
+ config_path: writer.mcpConfigPath,
193
+ ...(reason ? { reason } : {}),
194
+ });
195
+ // (5) tauri needs its launcher script — only provision it once the
196
+ // MCP config entry is actually written, so a TOFU-skipped or
197
+ // skipped_unsafe config never leaves an orphan launcher + a
198
+ // misleading audit line.
199
+ if (spec.requiresLauncherScript && frameworkRoot && action === 'written') {
200
+ provisionTauriLauncher(targetDir, frameworkRoot, writes);
201
+ }
202
+ }
203
+ else if (spec.kind === 'skill') {
204
+ if (!frameworkRoot)
205
+ continue;
206
+ const vendoredSkillPath = resolve(frameworkRoot, spec.vendoredSkillRelPath);
207
+ const skillDestPath = join(targetDir, writer.skillDir, spec.skillId, 'SKILL.md');
208
+ const action = copySkill(skillDestPath, vendoredSkillPath);
209
+ writes.push({ host, spec_id: specId, kind: 'skill', action });
210
+ appendEvent(targetDir, `skill-provision.${action}`, {
211
+ host,
212
+ spec_id: specId,
213
+ skill_dir: writer.skillDir,
214
+ }, 'skill_provision');
215
+ }
216
+ }
217
+ }
218
+ return { status: 'ok', writes };
219
+ }
220
+ catch (e) {
221
+ return { status: 'error', reason: e instanceof Error ? e.message : String(e) };
222
+ }
223
+ }
224
+ /**
225
+ * Copy the tauri launcher template into the project's scripts/ dir (TOFU).
226
+ * Records its own audit line; appends to `writes` with a synthetic host.
227
+ *
228
+ * @param {string} targetDir
229
+ * @param {string} frameworkRoot
230
+ * @param {Array<{host:string, spec_id:string, kind:string, action:string}>} writes
231
+ */
232
+ function provisionTauriLauncher(targetDir, frameworkRoot, writes) {
233
+ const destPath = join(targetDir, 'scripts', 'tauri-mcp.sh');
234
+ // Already recorded a launcher write/skip for this run? Only provision once.
235
+ if (writes.some((w) => w.kind === 'launcher'))
236
+ return;
237
+ if (existsSync(destPath)) {
238
+ writes.push({ host: '-', spec_id: 'tauri', kind: 'launcher', action: 'skipped' });
239
+ appendEvent(targetDir, 'mcp-provision.skipped', {
240
+ host: '-',
241
+ spec_id: 'tauri',
242
+ launcher: 'scripts/tauri-mcp.sh',
243
+ });
244
+ return;
245
+ }
246
+ const templatePath = resolve(frameworkRoot, 'drivers/tauri/scripts/tauri-mcp.sh');
247
+ const template = readFileSync(templatePath, 'utf-8');
248
+ atomicWriteText(destPath, renderTauriLauncher(template, targetDir));
249
+ writes.push({ host: '-', spec_id: 'tauri', kind: 'launcher', action: 'written' });
250
+ appendEvent(targetDir, 'mcp-provision.written', {
251
+ host: '-',
252
+ spec_id: 'tauri',
253
+ launcher: 'scripts/tauri-mcp.sh',
254
+ });
255
+ }
256
+ /**
257
+ * Append one audit line to .aperant/events/{date}.jsonl, mirroring the
258
+ * daily-events shape. `kind` discriminates the provisioning channel:
259
+ * `mcp_provision` for MCP-server + launcher events, `skill_provision` for
260
+ * skill-copy events.
261
+ *
262
+ * @param {string} targetDir
263
+ * @param {string} op — e.g. mcp-provision.written, skill-provision.skipped
264
+ * @param {Record<string, unknown>} [extra]
265
+ * @param {string} [kind] — audit channel (default `mcp_provision`)
266
+ */
267
+ function appendEvent(targetDir, op, extra = {}, kind = 'mcp_provision') {
268
+ try {
269
+ const path = dailyEventsPath(targetDir);
270
+ appendJsonl(path, {
271
+ ts: new Date().toISOString(),
272
+ kind,
273
+ op,
274
+ ...extra,
275
+ });
276
+ }
277
+ catch {
278
+ // Audit is best-effort — never fail provisioning on a log write error.
279
+ }
280
+ }
281
+ //# sourceMappingURL=mcp-provision.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-provision.mjs","sourceRoot":"","sources":["../../../src/cli/install/mcp-provision.mjs"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Map a project's runtime capabilities to the provision spec ids it
3
+ * triggers. A multi-surface monorepo (e.g. electron + nextjs) returns
4
+ * multiple ids.
5
+ *
6
+ * is_electron → ['electron']
7
+ * is_tauri → ['tauri']
8
+ * is_web_frontend|is_nextjs|is_nuxt → ['agent-browser']
9
+ *
10
+ * Accepts a partial capability record — only the flags it reads need be
11
+ * present (the rest default to absent/false).
12
+ *
13
+ * @param {Partial<import('../util/runtime-capabilities.mjs').RuntimeCapabilities>} runtimeCaps
14
+ * @returns {string[]}
15
+ */
16
+ export function capabilityToProvisionIds(runtimeCaps: Partial<import("../util/runtime-capabilities.mjs").RuntimeCapabilities>): string[];
17
+ /**
18
+ * install/mcp-server-specs.mjs — single-sourced install-time provision specs.
19
+ *
20
+ * One registry, two kinds (ID-03):
21
+ * - kind 'mcp-server' (electron, tauri): the {command, args, env?} the
22
+ * installer writes into each host CLI's MCP config. Keyed by the SAME
23
+ * `transport.mcp_server_id` string the driver manifests carry.
24
+ * - kind 'skill' (agent-browser): the vendored SKILL.md the installer
25
+ * copies into each host CLI's skill dir. Keyed by the SAME
26
+ * `transport.skill_id` the browser driver manifest carries.
27
+ *
28
+ * We do NOT derive commands from the driver manifests — manifests are
29
+ * transport-agnostic by design (ID-01 keeps the verb→tool mapping in the
30
+ * driver; this is a separate install-only transport/skill concern). We do
31
+ * NOT add a per-driver mcp-server.json (over-engineering for 3 specs —
32
+ * CLAUDE.md Simplicity First).
33
+ *
34
+ * Pure module — no fs, no exec.
35
+ */
36
+ /**
37
+ * @typedef {Object} McpServerSpec
38
+ * @property {'mcp-server'} kind
39
+ * @property {string} command
40
+ * @property {string[]} args
41
+ * @property {Record<string, string>} [env]
42
+ * @property {boolean} [requiresLauncherScript] — tauri: copy scripts/tauri-mcp.sh first
43
+ *
44
+ * @typedef {Object} SkillSpec
45
+ * @property {'skill'} kind
46
+ * @property {string} skillId
47
+ * @property {string} vendoredSkillRelPath — relative to the framework root
48
+ *
49
+ * @typedef {McpServerSpec | SkillSpec} ProvisionSpec
50
+ */
51
+ /**
52
+ * The install-time provision specs, keyed by spec id.
53
+ *
54
+ * `electron` / `tauri` ids match each driver manifest's
55
+ * `transport.mcp_server_id`; `agent-browser` matches the browser driver
56
+ * manifest's `transport.skill_id`.
57
+ *
58
+ * @type {Record<string, ProvisionSpec>}
59
+ */
60
+ export const PROVISION_SPECS: Record<string, ProvisionSpec>;
61
+ export type McpServerSpec = {
62
+ kind: "mcp-server";
63
+ command: string;
64
+ args: string[];
65
+ env?: Record<string, string> | undefined;
66
+ /**
67
+ * — tauri: copy scripts/tauri-mcp.sh first
68
+ */
69
+ requiresLauncherScript?: boolean | undefined;
70
+ };
71
+ export type SkillSpec = {
72
+ kind: "skill";
73
+ skillId: string;
74
+ /**
75
+ * — relative to the framework root
76
+ */
77
+ vendoredSkillRelPath: string;
78
+ };
79
+ export type ProvisionSpec = McpServerSpec | SkillSpec;
80
+ //# sourceMappingURL=mcp-server-specs.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server-specs.d.mts","sourceRoot":"","sources":["../../../src/cli/install/mcp-server-specs.mjs"],"names":[],"mappings":"AA4EA;;;;;;;;;;;;;;GAcG;AACH,sDAHW,OAAO,CAAC,OAAO,kCAAkC,EAAE,mBAAmB,CAAC,GACrE,MAAM,EAAE,CAWpB;AApGD;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;GAQG;AACH,8BAFU,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CA+BtC;;UApDa,YAAY;aACZ,MAAM;UACN,MAAM,EAAE;;;;;;;;UAKR,OAAO;aACP,MAAM;;;;0BACN,MAAM;;4BAEP,aAAa,GAAG,SAAS"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * install/mcp-server-specs.mjs — single-sourced install-time provision specs.
3
+ *
4
+ * One registry, two kinds (ID-03):
5
+ * - kind 'mcp-server' (electron, tauri): the {command, args, env?} the
6
+ * installer writes into each host CLI's MCP config. Keyed by the SAME
7
+ * `transport.mcp_server_id` string the driver manifests carry.
8
+ * - kind 'skill' (agent-browser): the vendored SKILL.md the installer
9
+ * copies into each host CLI's skill dir. Keyed by the SAME
10
+ * `transport.skill_id` the browser driver manifest carries.
11
+ *
12
+ * We do NOT derive commands from the driver manifests — manifests are
13
+ * transport-agnostic by design (ID-01 keeps the verb→tool mapping in the
14
+ * driver; this is a separate install-only transport/skill concern). We do
15
+ * NOT add a per-driver mcp-server.json (over-engineering for 3 specs —
16
+ * CLAUDE.md Simplicity First).
17
+ *
18
+ * Pure module — no fs, no exec.
19
+ */
20
+ /**
21
+ * @typedef {Object} McpServerSpec
22
+ * @property {'mcp-server'} kind
23
+ * @property {string} command
24
+ * @property {string[]} args
25
+ * @property {Record<string, string>} [env]
26
+ * @property {boolean} [requiresLauncherScript] — tauri: copy scripts/tauri-mcp.sh first
27
+ *
28
+ * @typedef {Object} SkillSpec
29
+ * @property {'skill'} kind
30
+ * @property {string} skillId
31
+ * @property {string} vendoredSkillRelPath — relative to the framework root
32
+ *
33
+ * @typedef {McpServerSpec | SkillSpec} ProvisionSpec
34
+ */
35
+ /**
36
+ * The install-time provision specs, keyed by spec id.
37
+ *
38
+ * `electron` / `tauri` ids match each driver manifest's
39
+ * `transport.mcp_server_id`; `agent-browser` matches the browser driver
40
+ * manifest's `transport.skill_id`.
41
+ *
42
+ * @type {Record<string, ProvisionSpec>}
43
+ */
44
+ export const PROVISION_SPECS = {
45
+ // kind 'mcp-server'
46
+ electron: {
47
+ kind: 'mcp-server',
48
+ command: 'npx',
49
+ args: ['-y', 'electron-mcp-server'],
50
+ // No SCREENSHOT_ENCRYPTION_KEY — left for the user to add per ID-09.
51
+ env: {},
52
+ },
53
+ tauri: {
54
+ kind: 'mcp-server',
55
+ // The tauri-plugin-mcp-server npm bin ships without a shebang, so it
56
+ // cannot be invoked via `npx -y`. We launch it through a generated
57
+ // scripts/tauri-mcp.sh (ID-04) — the proven racing-ai shape.
58
+ command: 'bash',
59
+ args: ['./scripts/tauri-mcp.sh'],
60
+ requiresLauncherScript: true,
61
+ },
62
+ // kind 'skill'
63
+ 'agent-browser': {
64
+ kind: 'skill',
65
+ skillId: 'agent-browser',
66
+ // Vendored UNDER the browser driver (NOT skills/agent-browser/) so the
67
+ // install pipeline's discoverCanonicalFiles does not auto-install it
68
+ // into every project unconditionally — that would break the
69
+ // verification.provision_mcp opt-out (AC7) and the web-frontend runtime
70
+ // gate. The provisioner (mcp-provision.mjs) is the sole installer.
71
+ vendoredSkillRelPath: 'drivers/browser/skill/agent-browser/SKILL.md',
72
+ },
73
+ };
74
+ /**
75
+ * Map a project's runtime capabilities to the provision spec ids it
76
+ * triggers. A multi-surface monorepo (e.g. electron + nextjs) returns
77
+ * multiple ids.
78
+ *
79
+ * is_electron → ['electron']
80
+ * is_tauri → ['tauri']
81
+ * is_web_frontend|is_nextjs|is_nuxt → ['agent-browser']
82
+ *
83
+ * Accepts a partial capability record — only the flags it reads need be
84
+ * present (the rest default to absent/false).
85
+ *
86
+ * @param {Partial<import('../util/runtime-capabilities.mjs').RuntimeCapabilities>} runtimeCaps
87
+ * @returns {string[]}
88
+ */
89
+ export function capabilityToProvisionIds(runtimeCaps) {
90
+ const ids = [];
91
+ if (!runtimeCaps || typeof runtimeCaps !== 'object')
92
+ return ids;
93
+ if (runtimeCaps.is_electron)
94
+ ids.push('electron');
95
+ if (runtimeCaps.is_tauri)
96
+ ids.push('tauri');
97
+ if (runtimeCaps.is_web_frontend || runtimeCaps.is_nextjs || runtimeCaps.is_nuxt) {
98
+ ids.push('agent-browser');
99
+ }
100
+ return ids;
101
+ }
102
+ //# sourceMappingURL=mcp-server-specs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server-specs.mjs","sourceRoot":"","sources":["../../../src/cli/install/mcp-server-specs.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,oBAAoB;IACpB,QAAQ,EAAE;QACT,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,IAAI,EAAE,qBAAqB,CAAC;QACnC,qEAAqE;QACrE,GAAG,EAAE,EAAE;KACP;IACD,KAAK,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,qEAAqE;QACrE,mEAAmE;QACnE,6DAA6D;QAC7D,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,CAAC,wBAAwB,CAAC;QAChC,sBAAsB,EAAE,IAAI;KAC5B;IACD,eAAe;IACf,eAAe,EAAE;QAChB,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,eAAe;QACxB,uEAAuE;QACvE,qEAAqE;QACrE,4DAA4D;QAC5D,wEAAwE;QACxE,mEAAmE;QACnE,oBAAoB,EAAE,8CAA8C;KACpE;CACD,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAW;IACnD,MAAM,GAAG,GAAG,EAAE,CAAA;IACd,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IAC/D,IAAI,WAAW,CAAC,WAAW;QAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACjD,IAAI,WAAW,CAAC,QAAQ;QAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,WAAW,CAAC,eAAe,IAAI,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAC1B,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC"}