@aporthq/aport-agent-guardrails 1.0.8

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 (237) hide show
  1. package/LICENSE +217 -0
  2. package/README.md +481 -0
  3. package/bin/agent-guardrails +133 -0
  4. package/bin/aport-create-passport.sh +444 -0
  5. package/bin/aport-cursor-hook.sh +90 -0
  6. package/bin/aport-guardrail-api.sh +108 -0
  7. package/bin/aport-guardrail-bash.sh +394 -0
  8. package/bin/aport-guardrail-v2.sh +5 -0
  9. package/bin/aport-guardrail.sh +5 -0
  10. package/bin/aport-resolve-paths.sh +71 -0
  11. package/bin/aport-status.sh +276 -0
  12. package/bin/frameworks/crewai.sh +49 -0
  13. package/bin/frameworks/cursor.sh +95 -0
  14. package/bin/frameworks/langchain.sh +48 -0
  15. package/bin/frameworks/n8n.sh +36 -0
  16. package/bin/frameworks/openclaw.sh +19 -0
  17. package/bin/lib/allowlist.sh +18 -0
  18. package/bin/lib/common.sh +28 -0
  19. package/bin/lib/config.sh +46 -0
  20. package/bin/lib/constants.sh +232 -0
  21. package/bin/lib/detect.sh +65 -0
  22. package/bin/lib/error.sh +269 -0
  23. package/bin/lib/passport.sh +19 -0
  24. package/bin/lib/templates/.gitkeep +1 -0
  25. package/bin/lib/templates/config.yaml +6 -0
  26. package/bin/lib/validation.sh +206 -0
  27. package/bin/openclaw +660 -0
  28. package/docs/ADDING_A_FRAMEWORK.md +87 -0
  29. package/docs/AGENTS.md.example +40 -0
  30. package/docs/CODE_REVIEW.md +192 -0
  31. package/docs/DEPLOYMENT_READINESS.md +81 -0
  32. package/docs/FAQ_SECURITY_SCANNERS.md +373 -0
  33. package/docs/FRAMEWORK_ROADMAP.md +41 -0
  34. package/docs/HOSTED_PASSPORT_SETUP.md +362 -0
  35. package/docs/IMPLEMENTING_YOUR_OWN_EVALUATOR.md +433 -0
  36. package/docs/OPENCLAW_COMPATIBILITY.md +73 -0
  37. package/docs/OPENCLAW_LOCAL_INTEGRATION.md +596 -0
  38. package/docs/OPENCLAW_TOOLS_AND_POLICIES.md +54 -0
  39. package/docs/QUICKSTART.md +470 -0
  40. package/docs/QUICKSTART_OPENCLAW_PLUGIN.md +470 -0
  41. package/docs/README.md +28 -0
  42. package/docs/RELEASE.md +87 -0
  43. package/docs/REPO_LAYOUT.md +47 -0
  44. package/docs/SKILLS_ECOSYSTEM_ANALYSIS_FEB17.md +1260 -0
  45. package/docs/TOOL_POLICY_MAPPING.md +46 -0
  46. package/docs/UPGRADE.md +46 -0
  47. package/docs/VERIFICATION_METHODS.md +97 -0
  48. package/docs/assets/README.md +8 -0
  49. package/docs/assets/porter.svg +54 -0
  50. package/docs/development/ERROR_CODES.md +616 -0
  51. package/docs/frameworks/GITHUB_ISSUE_PROPOSALS.md +1105 -0
  52. package/docs/frameworks/crewai.md +114 -0
  53. package/docs/frameworks/cursor.md +159 -0
  54. package/docs/frameworks/langchain.md +72 -0
  55. package/docs/frameworks/n8n.md +40 -0
  56. package/docs/frameworks/openclaw.md +40 -0
  57. package/docs/launch/ADD_APORT_AWESOME_LISTS_INSTRUCTIONS.md +146 -0
  58. package/docs/launch/ANNOUNCEMENT_GUIDE.md +266 -0
  59. package/docs/launch/AWESOME_REPOS.md +53 -0
  60. package/docs/launch/CURSOR_VSCODE_HOOKS_RESEARCH.md +77 -0
  61. package/docs/launch/DEMO_TERMINAL_OUTPUT.txt +48 -0
  62. package/docs/launch/DRY_AND_PLAN_CHECKLIST.md +47 -0
  63. package/docs/launch/EVIDENCE_README.md +61 -0
  64. package/docs/launch/EVIDENCE_TERMINAL_CAPTURE.txt +10 -0
  65. package/docs/launch/FRAMEWORK_SUPPORT_PLAN.md +1640 -0
  66. package/docs/launch/LAUNCH_READINESS_CHECKLIST.md +237 -0
  67. package/docs/launch/LAUNCH_STRATEGY_SUMMARY.md +464 -0
  68. package/docs/launch/OPENCLAW_FEEDBACK_AND_FIXES.md +85 -0
  69. package/docs/launch/POST_1_VALENTINE_IMPROVED.md +233 -0
  70. package/docs/launch/POST_2_GUARDRAIL_IMPROVED.md +369 -0
  71. package/docs/launch/PRE_LAUNCH_FIXES.md +766 -0
  72. package/docs/launch/QUICK_LAUNCH_CHECKLIST.md +400 -0
  73. package/docs/launch/READINESS_SUMMARY.md +262 -0
  74. package/docs/launch/README.md +68 -0
  75. package/docs/launch/USER_STORIES.md +327 -0
  76. package/docs/launch/scripts/add-aport-awesome-pr.sh +69 -0
  77. package/docs/operations/MONITORING.md +588 -0
  78. package/docs/reviews/2026-02-18-staff-review.md +268 -0
  79. package/extensions/openclaw-aport/README.md +415 -0
  80. package/extensions/openclaw-aport/index.js +625 -0
  81. package/extensions/openclaw-aport/openclaw-aport.js +7 -0
  82. package/extensions/openclaw-aport/openclaw.plugin.json +46 -0
  83. package/extensions/openclaw-aport/package.json +36 -0
  84. package/extensions/openclaw-aport/test.js +307 -0
  85. package/external/aport-policies/README.md +363 -0
  86. package/external/aport-policies/agent.session.create.v1/README.md +345 -0
  87. package/external/aport-policies/agent.session.create.v1/policy.json +162 -0
  88. package/external/aport-policies/agent.tool.register.v1/README.md +361 -0
  89. package/external/aport-policies/agent.tool.register.v1/policy.json +172 -0
  90. package/external/aport-policies/code.release.publish.v1/README.md +51 -0
  91. package/external/aport-policies/code.release.publish.v1/policy.json +121 -0
  92. package/external/aport-policies/code.repository.merge.v1/README.md +287 -0
  93. package/external/aport-policies/code.repository.merge.v1/express.example.js +332 -0
  94. package/external/aport-policies/code.repository.merge.v1/fastapi.example.py +370 -0
  95. package/external/aport-policies/code.repository.merge.v1/policy.json +162 -0
  96. package/external/aport-policies/data.export.create.v1/README.md +226 -0
  97. package/external/aport-policies/data.export.create.v1/express.example.js +172 -0
  98. package/external/aport-policies/data.export.create.v1/fastapi.example.py +165 -0
  99. package/external/aport-policies/data.export.create.v1/policy.json +133 -0
  100. package/external/aport-policies/data.report.ingest.v1/README.md +134 -0
  101. package/external/aport-policies/data.report.ingest.v1/express.example.js +105 -0
  102. package/external/aport-policies/data.report.ingest.v1/minimal-example.js +68 -0
  103. package/external/aport-policies/data.report.ingest.v1/policy.json +174 -0
  104. package/external/aport-policies/finance.crypto.trade.v1/README.md +146 -0
  105. package/external/aport-policies/finance.crypto.trade.v1/express.example.js +109 -0
  106. package/external/aport-policies/finance.crypto.trade.v1/minimal-example.js +65 -0
  107. package/external/aport-policies/finance.crypto.trade.v1/policy.json +176 -0
  108. package/external/aport-policies/finance.payment.charge.v1/README.md +326 -0
  109. package/external/aport-policies/finance.payment.charge.v1/express.example.js +250 -0
  110. package/external/aport-policies/finance.payment.charge.v1/fastapi.example.py +227 -0
  111. package/external/aport-policies/finance.payment.charge.v1/minimal-example.js +64 -0
  112. package/external/aport-policies/finance.payment.charge.v1/policy.json +224 -0
  113. package/external/aport-policies/finance.payment.charge.v1/tests/contexts.jsonl +12 -0
  114. package/external/aport-policies/finance.payment.charge.v1/tests/expected.jsonl +12 -0
  115. package/external/aport-policies/finance.payment.charge.v1/tests/passport.instance.json +42 -0
  116. package/external/aport-policies/finance.payment.charge.v1/tests/passport.template.json +40 -0
  117. package/external/aport-policies/finance.payment.charge.v1/tests/payments-charge-policy.test.js +817 -0
  118. package/external/aport-policies/finance.payment.charge.v1/tests/test_payments_charge_policy.py +486 -0
  119. package/external/aport-policies/finance.payment.payout.v1/README.md +78 -0
  120. package/external/aport-policies/finance.payment.payout.v1/policy.json +181 -0
  121. package/external/aport-policies/finance.payment.refund.v1/README.md +275 -0
  122. package/external/aport-policies/finance.payment.refund.v1/express.example.js +167 -0
  123. package/external/aport-policies/finance.payment.refund.v1/fastapi.example.py +136 -0
  124. package/external/aport-policies/finance.payment.refund.v1/minimal-example.js +183 -0
  125. package/external/aport-policies/finance.payment.refund.v1/policy.json +216 -0
  126. package/external/aport-policies/finance.payment.refund.v1/tests/refunds-policy.test.js +924 -0
  127. package/external/aport-policies/finance.payment.refund.v1/tests/test_refunds_policy.py +778 -0
  128. package/external/aport-policies/finance.transaction.execute.v1/README.md +309 -0
  129. package/external/aport-policies/finance.transaction.execute.v1/express.example.js +261 -0
  130. package/external/aport-policies/finance.transaction.execute.v1/fastapi.example.py +231 -0
  131. package/external/aport-policies/finance.transaction.execute.v1/minimal-example.js +78 -0
  132. package/external/aport-policies/finance.transaction.execute.v1/policy.json +189 -0
  133. package/external/aport-policies/finance.transaction.execute.v1/tests/contexts.jsonl +12 -0
  134. package/external/aport-policies/finance.transaction.execute.v1/tests/expected.jsonl +12 -0
  135. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.instance.json +42 -0
  136. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.template.json +42 -0
  137. package/external/aport-policies/finance.transaction.execute.v1/tests/test_transactions_policy.py +214 -0
  138. package/external/aport-policies/finance.transaction.execute.v1/tests/transactions-policy.test.js +306 -0
  139. package/external/aport-policies/governance.data.access.v1/README.md +292 -0
  140. package/external/aport-policies/governance.data.access.v1/express.example.js +321 -0
  141. package/external/aport-policies/governance.data.access.v1/fastapi.example.py +279 -0
  142. package/external/aport-policies/governance.data.access.v1/minimal-example.js +65 -0
  143. package/external/aport-policies/governance.data.access.v1/policy.json +208 -0
  144. package/external/aport-policies/governance.data.access.v1/tests/contexts.jsonl +12 -0
  145. package/external/aport-policies/governance.data.access.v1/tests/data-access-policy.test.js +308 -0
  146. package/external/aport-policies/governance.data.access.v1/tests/expected.jsonl +12 -0
  147. package/external/aport-policies/governance.data.access.v1/tests/passport.instance.json +56 -0
  148. package/external/aport-policies/governance.data.access.v1/tests/passport.template.json +56 -0
  149. package/external/aport-policies/governance.data.access.v1/tests/test_data_access_policy.py +214 -0
  150. package/external/aport-policies/legal.contract.review.v1/README.md +109 -0
  151. package/external/aport-policies/legal.contract.review.v1/policy.json +378 -0
  152. package/external/aport-policies/legal.contract.review.v1/tests/legal-contract-review-policy.test.js +609 -0
  153. package/external/aport-policies/legal.contract.review.v1/tests/passport.template.json +49 -0
  154. package/external/aport-policies/mcp.tool.execute.v1/README.md +301 -0
  155. package/external/aport-policies/mcp.tool.execute.v1/policy.json +141 -0
  156. package/external/aport-policies/messaging.message.send.v1/README.md +230 -0
  157. package/external/aport-policies/messaging.message.send.v1/express.example.js +183 -0
  158. package/external/aport-policies/messaging.message.send.v1/fastapi.example.py +193 -0
  159. package/external/aport-policies/messaging.message.send.v1/policy.json +144 -0
  160. package/external/aport-policies/policy-template.json +107 -0
  161. package/external/aport-policies/system.command.execute.v1/README.md +275 -0
  162. package/external/aport-policies/system.command.execute.v1/policy.json +146 -0
  163. package/external/aport-spec/CONTRIBUTING.md +273 -0
  164. package/external/aport-spec/LICENSE +21 -0
  165. package/external/aport-spec/README.md +168 -0
  166. package/external/aport-spec/conformance/README.md +294 -0
  167. package/external/aport-spec/conformance/cases/data.export.v1/contexts/allow_users.json +6 -0
  168. package/external/aport-spec/conformance/cases/data.export.v1/contexts/deny_pii.json +6 -0
  169. package/external/aport-spec/conformance/cases/data.export.v1/expected/allow_users.decision.json +19 -0
  170. package/external/aport-spec/conformance/cases/data.export.v1/expected/deny_pii.decision.json +19 -0
  171. package/external/aport-spec/conformance/cases/data.export.v1/passports/template.json +29 -0
  172. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/allow_50usd.json +9 -0
  173. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_150usd.json +9 -0
  174. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_currency.json +9 -0
  175. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/allow_50usd.decision.json +19 -0
  176. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_150usd.decision.json +19 -0
  177. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_currency.decision.json +19 -0
  178. package/external/aport-spec/conformance/cases/payments.refunds.v1/passports/template.json +42 -0
  179. package/external/aport-spec/conformance/package.json +44 -0
  180. package/external/aport-spec/conformance/pnpm-lock.yaml +642 -0
  181. package/external/aport-spec/conformance/src/cases.ts +371 -0
  182. package/external/aport-spec/conformance/src/ed25519.ts +167 -0
  183. package/external/aport-spec/conformance/src/jcs.ts +85 -0
  184. package/external/aport-spec/conformance/src/runner.ts +533 -0
  185. package/external/aport-spec/conformance/src/validators.ts +185 -0
  186. package/external/aport-spec/conformance/test-runner.js +315 -0
  187. package/external/aport-spec/conformance/tsconfig.json +21 -0
  188. package/external/aport-spec/error-schema.json +192 -0
  189. package/external/aport-spec/index.json +12 -0
  190. package/external/aport-spec/integrations/clawmoat/README.md +12 -0
  191. package/external/aport-spec/integrations/shield/README.md +245 -0
  192. package/external/aport-spec/integrations/shield/adapters/index.js +116 -0
  193. package/external/aport-spec/integrations/shield/adapters/system-command-execute.js +133 -0
  194. package/external/aport-spec/integrations/shield/test/README.md +58 -0
  195. package/external/aport-spec/integrations/shield/test/shield.md +40 -0
  196. package/external/aport-spec/integrations/shield/test/test-shield-to-verify.js +274 -0
  197. package/external/aport-spec/metrics-schema.json +504 -0
  198. package/external/aport-spec/oap/CHANGELOG.md +54 -0
  199. package/external/aport-spec/oap/VERSION.md +40 -0
  200. package/external/aport-spec/oap/capability-registry.md +229 -0
  201. package/external/aport-spec/oap/conformance.md +257 -0
  202. package/external/aport-spec/oap/decision-schema.json +114 -0
  203. package/external/aport-spec/oap/examples/context.refund.usd.50.json +9 -0
  204. package/external/aport-spec/oap/examples/decision.allow.sample.json +20 -0
  205. package/external/aport-spec/oap/examples/decision.deny.sample.json +23 -0
  206. package/external/aport-spec/oap/examples/passport.instance.v1.json +50 -0
  207. package/external/aport-spec/oap/examples/passport.template.v1.json +71 -0
  208. package/external/aport-spec/oap/oap-spec.md +426 -0
  209. package/external/aport-spec/oap/passport-schema.json +396 -0
  210. package/external/aport-spec/oap/security.md +213 -0
  211. package/external/aport-spec/oap/vc/context-oap-v1.jsonld +137 -0
  212. package/external/aport-spec/oap/vc/examples/oap-decision-vc.json +37 -0
  213. package/external/aport-spec/oap/vc/examples/oap-passport-vc.json +68 -0
  214. package/external/aport-spec/oap/vc/tools/INTEGRATION.md +375 -0
  215. package/external/aport-spec/oap/vc/tools/README.md +278 -0
  216. package/external/aport-spec/oap/vc/tools/examples/decision-to-vc.js +66 -0
  217. package/external/aport-spec/oap/vc/tools/examples/passport-to-vc.js +83 -0
  218. package/external/aport-spec/oap/vc/tools/examples/vc-to-decision.js +77 -0
  219. package/external/aport-spec/oap/vc/tools/examples/vc-to-passport.js +94 -0
  220. package/external/aport-spec/oap/vc/tools/package.json +38 -0
  221. package/external/aport-spec/oap/vc/tools/pnpm-lock.yaml +472 -0
  222. package/external/aport-spec/oap/vc/tools/src/cli.ts +226 -0
  223. package/external/aport-spec/oap/vc/tools/src/crypto-utils.ts +427 -0
  224. package/external/aport-spec/oap/vc/tools/src/index.ts +653 -0
  225. package/external/aport-spec/oap/vc/tools/src/test.ts +148 -0
  226. package/external/aport-spec/oap/vc/tools/src/vp.ts +382 -0
  227. package/external/aport-spec/oap/vc/tools/test-simple.js +214 -0
  228. package/external/aport-spec/oap/vc/tools/tsconfig.json +19 -0
  229. package/external/aport-spec/oap/vc/vc-mapping.md +443 -0
  230. package/external/aport-spec/passport-schema.json +586 -0
  231. package/external/aport-spec/rate-limiting.md +136 -0
  232. package/external/aport-spec/transport-profile.md +325 -0
  233. package/external/aport-spec/webhook-spec.md +314 -0
  234. package/package.json +70 -0
  235. package/skills/aport-agent-guardrail/SKILL.md +314 -0
  236. package/src/evaluator.js +252 -0
  237. package/src/server/index.js +72 -0
@@ -0,0 +1,276 @@
1
+ #!/bin/bash
2
+ # aport-status.sh
3
+ # Display APort passport status and recent activity
4
+ #
5
+ # Usage: ./aport-status.sh [--passport FILE]
6
+
7
+ set -e
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
10
+ # shellcheck source=bin/aport-resolve-paths.sh
11
+ . "${SCRIPT_DIR}/bin/aport-resolve-paths.sh"
12
+
13
+ if [ "$1" = "--passport" ] && [ -n "$2" ]; then
14
+ PASSPORT_FILE="$2"
15
+ fi
16
+
17
+ echo "🛂 APort Status Dashboard"
18
+ echo "========================="
19
+ echo
20
+
21
+ # Passport info (passport status is source of truth for suspend; no separate kill-switch file)
22
+ if [ ! -f "$PASSPORT_FILE" ]; then
23
+ echo "❌ Passport: NOT FOUND"
24
+ echo " Location: $PASSPORT_FILE"
25
+ echo " Create one with: aport-create-passport.sh"
26
+ echo
27
+ exit 1
28
+ fi
29
+
30
+ echo "📋 Passport Information"
31
+ echo " Location: $PASSPORT_FILE"
32
+
33
+ # Check jq availability
34
+ if ! command -v jq &> /dev/null; then
35
+ echo " ⚠️ jq not found - install with: brew install jq"
36
+ echo
37
+ exit 1
38
+ fi
39
+
40
+ echo " ID: $(jq -r '.passport_id // "unknown"' $PASSPORT_FILE)"
41
+ echo " Kind: $(jq -r '.kind // "unknown"' $PASSPORT_FILE)"
42
+ echo " Owner: $(jq -r '.owner_id // "unknown"' $PASSPORT_FILE) ($(jq -r '.owner_type // "unknown"' $PASSPORT_FILE))"
43
+ echo " Spec Version: $(jq -r '.spec_version // "unknown"' $PASSPORT_FILE)"
44
+ echo " Assurance Level: $(jq -r '.assurance_level // "unknown"' $PASSPORT_FILE)"
45
+
46
+ # Status with color
47
+ status=$(jq -r '.status // "unknown"' $PASSPORT_FILE)
48
+ if [ "$status" = "active" ]; then
49
+ echo " Status: ✅ active"
50
+ elif [ "$status" = "suspended" ]; then
51
+ echo " Status: 🔴 suspended"
52
+ elif [ "$status" = "revoked" ]; then
53
+ echo " Status: ❌ revoked"
54
+ else
55
+ echo " Status: ⚠️ $status"
56
+ fi
57
+
58
+ # Display agent metadata if available
59
+ agent_name=$(jq -r '.metadata.name // ""' $PASSPORT_FILE)
60
+ if [ -n "$agent_name" ] && [ "$agent_name" != "null" ]; then
61
+ echo " Agent Name: $agent_name"
62
+ fi
63
+
64
+ # Expiration with warning
65
+ never_expires=$(jq -r '.never_expires // "false"' $PASSPORT_FILE)
66
+ expires_at=$(jq -r '.expires_at // "null"' $PASSPORT_FILE)
67
+
68
+ if [ "$never_expires" = "true" ]; then
69
+ echo " Expires: Never"
70
+ elif [ "$expires_at" != "null" ] && [ "$expires_at" != "unknown" ]; then
71
+ echo " Expires: $expires_at"
72
+
73
+ # Calculate days until expiration
74
+ if date -v+1d &> /dev/null 2>&1; then
75
+ # BSD date (macOS)
76
+ expires_ts=$(date -jf "%Y-%m-%dT%H:%M:%SZ" "$expires_at" +%s 2> /dev/null || echo 0)
77
+ else
78
+ # GNU date (Linux)
79
+ expires_ts=$(date -d "$expires_at" +%s 2> /dev/null || echo 0)
80
+ fi
81
+
82
+ now_ts=$(date +%s)
83
+ days_left=$((($expires_ts - $now_ts) / 86400))
84
+
85
+ if [ $days_left -le 0 ]; then
86
+ echo " ⚠️ EXPIRED $((days_left * -1)) days ago"
87
+ elif [ $days_left -le 7 ]; then
88
+ echo " ⚠️ Expires in $days_left days - renew soon!"
89
+ else
90
+ echo " ✅ $days_left days until expiration"
91
+ fi
92
+ else
93
+ echo " Expires: Not set"
94
+ fi
95
+
96
+ echo
97
+
98
+ # Capabilities
99
+ echo "🔐 Capabilities"
100
+ cap_count=$(jq '.capabilities | length' $PASSPORT_FILE)
101
+ if [ "$cap_count" -eq 0 ]; then
102
+ echo " (none configured)"
103
+ else
104
+ jq -r '.capabilities[].id // empty' $PASSPORT_FILE | while read cap; do
105
+ echo " • $cap"
106
+ done
107
+ fi
108
+
109
+ echo
110
+
111
+ # Limits summary
112
+ echo "⚙️ Limits"
113
+ jq -r '.limits | keys[]? // empty' $PASSPORT_FILE | while read policy; do
114
+ echo " • $policy:"
115
+ case "$policy" in
116
+ "code.repository.merge")
117
+ max_prs=$(jq -r ".limits.\"$policy\".max_prs_per_day // \"unlimited\"" $PASSPORT_FILE)
118
+ max_size=$(jq -r ".limits.\"$policy\".max_pr_size_kb // \"unlimited\"" $PASSPORT_FILE)
119
+ echo " - Max PRs/day: $max_prs"
120
+ echo " - Max PR size: $max_size files"
121
+ ;;
122
+ "system.command.execute")
123
+ max_time=$(jq -r ".limits.\"$policy\".max_execution_time // \"unlimited\"" $PASSPORT_FILE)
124
+ echo " - Max execution time: $max_time seconds"
125
+ blocked_count=$(jq ".limits.\"$policy\".blocked_patterns | length" $PASSPORT_FILE)
126
+ echo " - Blocked patterns: $blocked_count"
127
+ ;;
128
+ "messaging.message.send")
129
+ msgs_per_day=$(jq -r ".limits.\"$policy\".msgs_per_day // \"unlimited\"" $PASSPORT_FILE)
130
+ echo " - Messages/day: $msgs_per_day"
131
+ ;;
132
+ "data.export")
133
+ max_rows=$(jq -r ".limits.\"$policy\".max_rows // \"unlimited\"" $PASSPORT_FILE)
134
+ allow_pii=$(jq -r ".limits.\"$policy\".allow_pii // false" $PASSPORT_FILE)
135
+ echo " - Max rows: $max_rows"
136
+ echo " - PII export: $allow_pii"
137
+ ;;
138
+ esac
139
+ done
140
+
141
+ echo
142
+
143
+ # Latest decision (OAP v1.0 format)
144
+ if [ -f "$DECISION_FILE" ]; then
145
+ echo "🔍 Latest Decision"
146
+ allow=$(jq -r '.allow // "unknown"' $DECISION_FILE)
147
+ decision_id=$(jq -r '.decision_id // "unknown"' $DECISION_FILE)
148
+ policy_id=$(jq -r '.policy_id // "unknown"' $DECISION_FILE)
149
+
150
+ if [ "$allow" = "true" ]; then
151
+ echo " ✅ ALLOW"
152
+ else
153
+ echo " ❌ DENY"
154
+ fi
155
+ echo " Decision ID: $decision_id"
156
+ echo " Policy ID: $policy_id"
157
+
158
+ # Display OAP v1.0 reasons array
159
+ reasons_count=$(jq '.reasons | length' $DECISION_FILE 2> /dev/null || echo 0)
160
+ if [ "$reasons_count" -gt 0 ]; then
161
+ echo " Reasons:"
162
+ jq -r '.reasons[] | " - [\(.code)] \(.message)"' $DECISION_FILE
163
+ fi
164
+
165
+ # Display issued_at and expires_at
166
+ issued_at=$(jq -r '.issued_at // "unknown"' $DECISION_FILE)
167
+ expires_at_decision=$(jq -r '.expires_at // "unknown"' $DECISION_FILE)
168
+ if [ "$issued_at" != "unknown" ]; then
169
+ echo " Issued: $issued_at"
170
+ fi
171
+ if [ "$expires_at_decision" != "unknown" ]; then
172
+ echo " Expires: $expires_at_decision"
173
+ fi
174
+
175
+ # Display signature info
176
+ kid=$(jq -r '.kid // "unknown"' $DECISION_FILE)
177
+ if [ "$kid" != "unknown" ]; then
178
+ echo " Key ID: $kid"
179
+ fi
180
+ # Show capability context from last audit line (command, recipient, repo/branch)
181
+ if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
182
+ last_context=$(tail -1 "$AUDIT_LOG" | sed -n 's/.*context="\([^"]*\)".*/\1/p')
183
+ if [ -n "$last_context" ]; then
184
+ echo " Context: $last_context"
185
+ fi
186
+ fi
187
+ echo
188
+ fi
189
+
190
+ # Recent activity
191
+ echo "📊 Recent Activity (last 10)"
192
+ if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
193
+ tail -10 "$AUDIT_LOG" | while IFS= read -r line; do
194
+ # Parse log line: [timestamp] tool=X decision_id=Y allow=Z ... context="..." (optional)
195
+ timestamp=$(echo "$line" | sed -n 's/.*\[\([^]]*\)\].*/\1/p')
196
+ tool=$(echo "$line" | sed -n 's/.*tool=\([^ ]*\).*/\1/p')
197
+ allow=$(echo "$line" | sed -n 's/.*allow=\([^ ]*\).*/\1/p')
198
+ context=$(echo "$line" | sed -n 's/.*context="\([^"]*\)".*/\1/p')
199
+ timestamp=${timestamp:-unknown}
200
+ tool=${tool:-unknown}
201
+ allow=${allow:-unknown}
202
+
203
+ short_time=$(echo "$timestamp" | cut -d' ' -f1-2 | cut -d'.' -f1)
204
+ # Show capability + context when present (e.g. "exec.run | cat test.md"); truncate long context
205
+ if [ -n "$context" ]; then
206
+ context_show=$(printf '%.80s' "$context")
207
+ [ "${#context}" -gt 80 ] && context_show="${context_show}..."
208
+ detail="$tool | $context_show"
209
+ else
210
+ detail="$tool"
211
+ fi
212
+
213
+ if [ "$allow" = "true" ]; then
214
+ printf " ✅ %s | %s\n" "$short_time" "$detail"
215
+ else
216
+ printf " ❌ %s | %s\n" "$short_time" "$detail"
217
+ fi
218
+ done
219
+ else
220
+ echo " (no activity yet)"
221
+ fi
222
+
223
+ echo
224
+
225
+ # Usage statistics (sanitize numbers for macOS/BSD)
226
+ if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
227
+ echo "📈 Statistics (all time)"
228
+ total_actions=$(wc -l < "$AUDIT_LOG" | tr -d '[:space:]')
229
+ total_actions=${total_actions:-0}
230
+ allowed=$(grep -c "allow=true" "$AUDIT_LOG" 2> /dev/null || true)
231
+ allowed=$(echo "$allowed" | tr -d '[:space:]')
232
+ allowed=${allowed:-0}
233
+ denied=$(grep -c "allow=false" "$AUDIT_LOG" 2> /dev/null || true)
234
+ denied=$(echo "$denied" | tr -d '[:space:]')
235
+ denied=${denied:-0}
236
+
237
+ echo " Total actions: $total_actions"
238
+ echo " Allowed: $allowed"
239
+ echo " Denied: $denied"
240
+
241
+ if [ -n "$total_actions" ] && [ "$total_actions" -gt 0 ] 2> /dev/null; then
242
+ allow_pct=$((100 * allowed / total_actions))
243
+ echo " Allow rate: ${allow_pct}%"
244
+ fi
245
+ echo
246
+ fi
247
+
248
+ # Commands
249
+ echo "💡 Useful Commands"
250
+ echo " • View full audit log: tail -f $AUDIT_LOG"
251
+ echo " • Edit passport: vim $PASSPORT_FILE"
252
+ echo " • Test policy: aport-guardrail.sh <tool_name> '<context_json>'"
253
+ echo " • Suspend agent (local): set passport status to \"suspended\" in $PASSPORT_FILE (edit with jq or editor)"
254
+ echo " • Resume: set status back to \"active\""
255
+ echo
256
+
257
+ # Upgrade hint (show once per day)
258
+ HINT_FILE="$HOME/.openclaw/.last-status-upgrade-hint"
259
+ if [ ! -f "$HINT_FILE" ] || [ $(($(date +%s) - $(stat -f %m "$HINT_FILE" 2> /dev/null || stat -c %Y "$HINT_FILE" 2> /dev/null || echo 0))) -gt 86400 ]; then
260
+ echo "💰 Upgrade to APort Cloud?"
261
+ echo " You're using APort Local (free tier) - perfect for individual developers!"
262
+ echo
263
+ echo " Upgrade to APort Cloud for teams:"
264
+ echo " • Multi-machine sync (passport changes propagate <15s)"
265
+ echo " • Global suspend (remote passports): log in at aport.io and suspend passport; all agents using it deny in <30s"
266
+ echo " • Ed25519 signed audit logs (court-admissible, SOC 2/IIROC compliant)"
267
+ echo " • Team collaboration (shared passports, role-based policies)"
268
+ echo " • Analytics dashboard (usage metrics, risk scoring, anomaly detection)"
269
+ echo
270
+ echo " Pricing: \$99/user/month (Pro) | \$149/user/month (Enterprise)"
271
+ echo " Free trial: https://aport.io/trial"
272
+ echo " Learn more: https://aport.io/upgrade"
273
+ echo
274
+
275
+ touch "$HINT_FILE"
276
+ fi
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bash
2
+ # CrewAI framework installer/setup
3
+ # Config: ~/.aport/crewai/ or .aport/config.yaml
4
+
5
+ LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
6
+ # shellcheck source=../lib/common.sh
7
+ source "$LIB/common.sh"
8
+ # shellcheck source=../lib/passport.sh
9
+ source "$LIB/passport.sh"
10
+ # shellcheck source=../lib/config.sh
11
+ source "$LIB/config.sh"
12
+
13
+ run_setup() {
14
+ log_info "Setting up APort guardrails for CrewAI..."
15
+ config_dir="$(write_config_template crewai)"
16
+ mkdir -p "$config_dir/aport"
17
+ export APORT_FRAMEWORK=crewai
18
+ run_passport_wizard "$@"
19
+ echo ""
20
+ echo " Next steps (CrewAI):"
21
+ echo " ───────────────────"
22
+ echo " 1. Install the Python adapter (required for runtime enforcement):"
23
+ echo " pip install aport-agent-guardrails-crewai"
24
+ echo " aport-crewai setup"
25
+ echo " 2. Config written to: $config_dir"
26
+ echo " 3. Register the guardrail before running your crew:"
27
+ echo ""
28
+ echo " from aport_guardrails_crewai import register_aport_guardrail"
29
+ echo " register_aport_guardrail()"
30
+ echo " crew.kickoff()"
31
+ echo ""
32
+ echo " Or: @with_aport_guardrail on your entry point. See: docs/frameworks/crewai.md"
33
+ echo ""
34
+ # Fail loudly if Python available but adapter not installed (Issue 4); skip in CI/tests
35
+ if [[ -z "${APORT_SKIP_ADAPTER_CHECK:-}" ]]; then
36
+ if command -v pip &> /dev/null || command -v pip3 &> /dev/null; then
37
+ pip_cmd="pip"
38
+ command -v pip3 &> /dev/null && pip_cmd="pip3"
39
+ if ! $pip_cmd show aport-agent-guardrails-crewai &> /dev/null; then
40
+ echo "[aport] ERROR: Python adapter not installed. Run the following, then use your agent:" >&2
41
+ echo " $pip_cmd install aport-agent-guardrails-crewai" >&2
42
+ echo " aport-crewai setup" >&2
43
+ exit 1
44
+ fi
45
+ fi
46
+ fi
47
+ }
48
+
49
+ run_setup "$@"
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ # Cursor (and optional Copilot/Claude Code) framework installer/setup.
3
+ # Runs passport wizard and writes ~/.cursor/hooks.json pointing at the APort hook script.
4
+ # Same hook script works for Cursor, VS Code + Copilot, and Claude Code.
5
+
6
+ LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
7
+ # shellcheck source=../lib/common.sh
8
+ source "$LIB/common.sh"
9
+ # shellcheck source=../lib/passport.sh
10
+ source "$LIB/passport.sh"
11
+ # shellcheck source=../lib/config.sh
12
+ source "$LIB/config.sh"
13
+
14
+ run_setup() {
15
+ log_info "Setting up APort guardrails for Cursor..."
16
+ # Passport and data live under Cursor's config dir (~/.cursor/aport/ by default).
17
+ config_dir="$(get_config_dir cursor)"
18
+ mkdir -p "$config_dir/aport"
19
+
20
+ export APORT_FRAMEWORK=cursor
21
+ run_passport_wizard "$@"
22
+
23
+ # Resolve absolute path to hook script (works from repo or npx package)
24
+ HOOK_SCRIPT="${APORT_CURSOR_HOOK_SCRIPT:-}"
25
+ if [ -z "$HOOK_SCRIPT" ]; then
26
+ ROOT_FOR_HOOK="$(cd "$LIB/../.." && pwd)"
27
+ HOOK_SCRIPT="$ROOT_FOR_HOOK/bin/aport-cursor-hook.sh"
28
+ fi
29
+ if [ ! -f "$HOOK_SCRIPT" ]; then
30
+ log_warn "Hook script not found at $HOOK_SCRIPT; hooks.json will reference it (create the file for hooks to work)."
31
+ else
32
+ HOOK_SCRIPT="$(cd "$(dirname "$HOOK_SCRIPT")" && pwd)/$(basename "$HOOK_SCRIPT")"
33
+ fi
34
+
35
+ # Write Cursor hooks config: beforeShellExecution and preToolUse run the same script
36
+ CURSOR_HOOKS_DIR="${CURSOR_HOOKS_DIR:-$HOME/.cursor}"
37
+ CURSOR_HOOKS_FILE="$CURSOR_HOOKS_DIR/hooks.json"
38
+ mkdir -p "$CURSOR_HOOKS_DIR"
39
+
40
+ # Merge with existing hooks.json if present; otherwise create new
41
+ if [ -f "$CURSOR_HOOKS_FILE" ] && command -v jq &> /dev/null; then
42
+ EXISTING=$(cat "$CURSOR_HOOKS_FILE")
43
+ if echo "$EXISTING" | jq -e '.hooks' &> /dev/null; then
44
+ # Add APort hook to beforeShellExecution and preToolUse (avoid duplicate)
45
+ NEW_HOOKS=$(echo "$EXISTING" | jq -c --arg cmd "$HOOK_SCRIPT" '
46
+ (.hooks.beforeShellExecution // []) as $b |
47
+ (.hooks.preToolUse // []) as $p |
48
+ .hooks.beforeShellExecution = ($b | map(select(.command != $cmd)) | . + [{ "command": $cmd }]) |
49
+ .hooks.preToolUse = ($p | map(select(.command != $cmd)) | . + [{ "command": $cmd }])
50
+ ')
51
+ echo "$NEW_HOOKS" > "$CURSOR_HOOKS_FILE"
52
+ else
53
+ _write_cursor_hooks_file "$CURSOR_HOOKS_FILE" "$HOOK_SCRIPT"
54
+ fi
55
+ else
56
+ _write_cursor_hooks_file "$CURSOR_HOOKS_FILE" "$HOOK_SCRIPT"
57
+ fi
58
+
59
+ echo ""
60
+ echo " Next steps (Cursor):"
61
+ echo " ────────────────────"
62
+ echo " 1. Hooks config written to: $CURSOR_HOOKS_FILE"
63
+ echo " 2. Hook script: $HOOK_SCRIPT"
64
+ echo " 3. Restart Cursor (or reload window) so hooks are picked up."
65
+ echo " 4. Shell commands and tool use will be checked by APort policy (exit 2 = block)."
66
+ echo ""
67
+ echo " Same script works for VS Code + Copilot and Claude Code — see: docs/frameworks/cursor.md"
68
+ echo ""
69
+ }
70
+
71
+ _write_cursor_hooks_file() {
72
+ local file="$1"
73
+ local cmd="$2"
74
+ if command -v jq &> /dev/null; then
75
+ jq -n -c --arg cmd "$cmd" '{
76
+ version: 1,
77
+ hooks: {
78
+ beforeShellExecution: [{ command: $cmd }],
79
+ preToolUse: [{ command: $cmd }]
80
+ }
81
+ }' > "$file"
82
+ else
83
+ cat > "$file" << EOF
84
+ {
85
+ "version": 1,
86
+ "hooks": {
87
+ "beforeShellExecution": [{"command": "$cmd"}],
88
+ "preToolUse": [{"command": "$cmd"}]
89
+ }
90
+ }
91
+ EOF
92
+ fi
93
+ }
94
+
95
+ run_setup "$@"
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+ # LangChain/LangGraph framework installer/setup
3
+ # Config: ~/.aport/langchain/ or .aport/config.yaml
4
+
5
+ LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
6
+ # shellcheck source=../lib/common.sh
7
+ source "$LIB/common.sh"
8
+ # shellcheck source=../lib/passport.sh
9
+ source "$LIB/passport.sh"
10
+ # shellcheck source=../lib/config.sh
11
+ source "$LIB/config.sh"
12
+
13
+ run_setup() {
14
+ log_info "Setting up APort guardrails for LangChain..."
15
+ config_dir="$(write_config_template langchain)"
16
+ mkdir -p "$config_dir/aport"
17
+ export APORT_FRAMEWORK=langchain
18
+ run_passport_wizard "$@"
19
+ echo ""
20
+ echo " Next steps (LangChain):"
21
+ echo " ───────────────────────"
22
+ echo " 1. Install the Python adapter (required for runtime enforcement):"
23
+ echo " pip install aport-agent-guardrails-langchain"
24
+ echo " aport-langchain setup"
25
+ echo " 2. Config written to: $config_dir"
26
+ echo " 3. Add to your agent:"
27
+ echo ""
28
+ echo " from aport_guardrails_langchain import APortCallback"
29
+ echo " agent = initialize_agent(..., callbacks=[APortCallback()])"
30
+ echo ""
31
+ echo " See: docs/frameworks/langchain.md"
32
+ echo ""
33
+ # Fail loudly if Python available but adapter not installed (Issue 4); skip in CI/tests
34
+ if [[ -z "${APORT_SKIP_ADAPTER_CHECK:-}" ]]; then
35
+ if command -v pip &> /dev/null || command -v pip3 &> /dev/null; then
36
+ pip_cmd="pip"
37
+ command -v pip3 &> /dev/null && pip_cmd="pip3"
38
+ if ! $pip_cmd show aport-agent-guardrails-langchain &> /dev/null; then
39
+ echo "[aport] ERROR: Python adapter not installed. Run the following, then use your agent:" >&2
40
+ echo " $pip_cmd install aport-agent-guardrails-langchain" >&2
41
+ echo " aport-langchain setup" >&2
42
+ exit 1
43
+ fi
44
+ fi
45
+ fi
46
+ }
47
+
48
+ run_setup "$@"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ # n8n framework installer/setup
3
+ # Custom node + credentials; config in n8n credentials store.
4
+ #
5
+ # ⚠️ n8n custom node is NOT YET AVAILABLE. This script only runs the passport wizard
6
+ # and writes config. No APort node is installed. See docs/frameworks/n8n.md and
7
+ # DEPLOYMENT_READINESS.md for status.
8
+
9
+ LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
10
+ # shellcheck source=../lib/common.sh
11
+ source "$LIB/common.sh"
12
+ # shellcheck source=../lib/passport.sh
13
+ source "$LIB/passport.sh"
14
+ # shellcheck source=../lib/config.sh
15
+ source "$LIB/config.sh"
16
+
17
+ run_setup() {
18
+ echo " APort n8n support: coming soon. This installer writes config only; custom node not yet available."
19
+ echo ""
20
+ log_info "Setting up APort guardrails for n8n..."
21
+ config_dir="$(write_config_template n8n)"
22
+ mkdir -p "$config_dir/aport"
23
+ export APORT_FRAMEWORK=n8n
24
+ run_passport_wizard "$@"
25
+ echo ""
26
+ echo " Next steps (n8n):"
27
+ echo " ────────────────"
28
+ echo " 1. Install custom node to ~/.n8n/custom/ (or use HTTP Request node to APort API)."
29
+ echo " 2. In your workflow: add APort Guardrail node before action nodes; branch on allow/deny."
30
+ echo " 3. Store agent_id or passport in n8n credentials."
31
+ echo ""
32
+ echo " See: docs/frameworks/n8n.md"
33
+ echo ""
34
+ }
35
+
36
+ run_setup "$@"
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # OpenClaw framework: delegate to full installer so passport wizard, config,
3
+ # plugin, and next steps all run identically (single source of truth in bin/openclaw).
4
+ # Pass-through: all arguments ($@) are passed to bin/openclaw (e.g. agent_id for
5
+ # hosted passport, or any future flags/openclaw options). Non-interactive use
6
+ # (e.g. agent_id only) is unchanged when invoked via agent-guardrails openclaw <agent_id>.
7
+
8
+ # shellcheck source=../lib/common.sh
9
+ source "$(dirname "${BASH_SOURCE[0]:-.}")/../lib/common.sh"
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)"
12
+ OPENCLAW_BIN="$SCRIPT_DIR/../openclaw"
13
+
14
+ if [[ ! -x "$OPENCLAW_BIN" ]]; then
15
+ log_error "OpenClaw installer not found: $OPENCLAW_BIN"
16
+ exit 1
17
+ fi
18
+
19
+ exec "$OPENCLAW_BIN" "$@"
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ # Command allowlisting helpers (shared across frameworks)
3
+ # Used by evaluator / policy to check allowed_commands vs blocked patterns.
4
+
5
+ # shellcheck source=./common.sh
6
+ source "$(dirname "${BASH_SOURCE[0]:-.}")/common.sh"
7
+
8
+ # Placeholder: allowlist check logic can be shared between bash evaluator and API
9
+ # Returns 0 if command is allowed, 1 if denied
10
+ check_command_allowed() {
11
+ local command_line="$1"
12
+ local allowed_list="${2:-*}"
13
+ # TODO: Implement against passport allowed_commands + blocked patterns
14
+ [[ -z "$command_line" ]] && return 1
15
+ return 0
16
+ }
17
+
18
+ export -f check_command_allowed
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env bash
2
+ # Shared bash functions for APort agent-guardrails (multi-framework)
3
+ # Used by passport wizard, config helpers, and framework installers.
4
+
5
+ set -euo pipefail
6
+
7
+ # Resolve script directory and project root
8
+ SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)}"
9
+ # Project root: bin/lib -> repo root
10
+ ROOT_DIR="${ROOT_DIR:-$(cd "$SCRIPT_DIR/../.." 2> /dev/null && pwd)}"
11
+
12
+ # Log helpers
13
+ log_info() { echo "[aport] $*" >&2; }
14
+ log_warn() { echo "[aport] WARN: $*" >&2; }
15
+ log_error() { echo "[aport] ERROR: $*" >&2; }
16
+
17
+ # Check required commands
18
+ require_cmd() {
19
+ local cmd="$1"
20
+ if ! command -v "$cmd" &> /dev/null; then
21
+ log_error "Required command not found: $cmd"
22
+ exit 1
23
+ fi
24
+ }
25
+
26
+ # Export for subshells
27
+ export SCRIPT_DIR ROOT_DIR
28
+ export -f log_info log_warn log_error require_cmd
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ # Config file management (shared across frameworks)
3
+ # Read/write config, env vars, credential paths.
4
+
5
+ # shellcheck source=./common.sh
6
+ source "$(dirname "${BASH_SOURCE[0]:-.}")/common.sh"
7
+
8
+ # Default config locations per framework (where that framework stores data; can be overridden by env).
9
+ # Default passport path = get_config_dir/aport/passport.json. Keep in sync with packages/core default-passport-paths.json.
10
+ get_config_dir() {
11
+ local framework="${1:-}"
12
+ case "$framework" in
13
+ openclaw) echo "${APORT_OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}" ;;
14
+ langchain) echo "${APORT_LANGCHAIN_CONFIG_DIR:-$HOME/.aport/langchain}" ;;
15
+ crewai) echo "${APORT_CREWAI_CONFIG_DIR:-$HOME/.aport/crewai}" ;;
16
+ n8n) echo "${APORT_N8N_CONFIG_DIR:-$HOME/.n8n}" ;;
17
+ cursor) echo "${APORT_CURSOR_CONFIG_DIR:-$HOME/.cursor}" ;;
18
+ *) echo "${APORT_CONFIG_DIR:-$HOME/.aport}" ;;
19
+ esac
20
+ }
21
+
22
+ # Default passport path per framework (config_dir/aport/passport.json). Used by wizard and evaluator.
23
+ get_default_passport_path() {
24
+ local framework="${1:-}"
25
+ local config_dir
26
+ config_dir="$(get_config_dir "$framework")"
27
+ config_dir="${config_dir/#\~/$HOME}"
28
+ echo "${config_dir}/aport/passport.json"
29
+ }
30
+
31
+ write_config_template() {
32
+ local framework="$1"
33
+ local dest_dir
34
+ dest_dir="$(get_config_dir "$framework")"
35
+ mkdir -p "$dest_dir"
36
+ log_info "Config directory: $dest_dir"
37
+ local lib_dir templates_dir
38
+ lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)"
39
+ templates_dir="$lib_dir/templates"
40
+ if [[ -f "$templates_dir/config.yaml" ]]; then
41
+ cp "$templates_dir/config.yaml" "$dest_dir/config.yaml" 2> /dev/null || true
42
+ fi
43
+ echo "$dest_dir"
44
+ }
45
+
46
+ export -f get_config_dir get_default_passport_path write_config_template