Setting the file. One moment.
Test Portability · Agents Pay · aws/agent-toolkit-for-aws · Skills Docs
Repo No. 14 · Agents Pay
↖ Back to the coverEnd User Computing Skills
Messaging And Streaming Skills
Migration And Modernization Skills
Networking And Content Delivery Skills
Security And Identity Skills
Web And Mobile Development
132 skills · 818 min
ContentsBack to the top of the page 70
Creating Amazon Aurora Db Cluster With Instances
93
Routing Traffic With Route53 And CloudFront
Resilience Program Design
Creating API Gateway Stage
scripts/test_portability.py
scripts/ test_portability.py
Python · 187 lines · 8 KB
15 4. Scripts must import and run from the copied-in-isolation folder, using only
16 the stdlib plus declared third-party deps.
17
18 Exit code 0 means portable.
19 """
20
21 from __future__ import annotations
22
23 import re
24 import shutil
25 import subprocess
26 import sys
27 import tempfile
28 from pathlib import Path
29
30 # Resolve the skill dir from this file's own location, so the check works from
31 # any checkout, any copy, and any working directory.
32 SKILL = Path( __file__ ).resolve().parent.parent
33
34 failures: list[ str ] = []
35 checks = 0
36
37
38 def check (ok: bool , label: str , detail: str = "" ) -> None :
39 global checks
40 checks += 1
41 if ok:
42 print ( f " [pass] { label } " )
43 else :
44 print ( f " [FAIL] { label } " + ( f " — { detail } " if detail else "" ))
45 failures.append(label)
46
47
48 def parse_frontmatter (text: str ) -> dict :
49 """Mimic a permissive, schema-less frontmatter reader (OpenClaw's approach).
50
51 Flattens nested maps the way OpenClaw does (objects get stringified), and
52 accepts multi-line `>` block scalars, which the shipped parser handles even
53 though the docs claim single-line only.
54 """
55 if not text.startswith( "--- \n " ):
56 raise ValueError ( "no frontmatter" )
57 end = text.find( " \n --- \n " , 4 )
58 if end == - 1 :
59 raise ValueError ( "unterminated frontmatter" )
60 body = text[ 4 :end]
61
62 out: dict[ str , str ] = {}
63 key: str | None = None
64 for line in body.splitlines():
65 if not line.strip():
66 continue
67 if re.match( r " ^[ A-Za-z_ ][ A-Za-z0-9_- ] * :" , line):
68 k, _, v = line.partition( ":" )
69 key = k.strip()
70 v = v.strip()
71 out[key] = "" if v in ( ">" , "|" , ">-" , "|-" ) else v
72 elif key and line.startswith(( " " , " \t " )):
73 out[key] = (out[key] + " " + line.strip()).strip()
74 return out
75
76
77 print ( f "Simulating harness load of: { SKILL .name }\n " )
78
79 # ---------------------------------------------------------------- 1. frontmatter
80 print ( "1. Schema-less frontmatter parsing (OpenClaw-style)" )
81 text = ( SKILL / "SKILL.md" ).read_text()
82 try :
83 fm = parse_frontmatter(text)
84 check( True , "frontmatter parses without error" )
85 check( bool (fm.get( "description" )), "description present (else silently dropped)" )
86 check(fm.get( "name" ) == SKILL .name, f "name matches directory ( { fm.get( 'name' ) } )" )
87 check( len (fm.get( "description" , "" )) >= 20 , "description >= 20 chars (repo validator)" )
88 forbidden = [k for k in fm if k == "stages" or k.startswith( "owner_" )]
89 check( not forbidden, "no CI-forbidden keys (stages/owner_*)" , str (forbidden))
90 # Unknown-to-OpenClaw keys must be harmless, not fatal.
91 for k in ( "allowed-tools" , "metadata" ):
92 if k in fm:
93 print ( f " (note: ' { k } ' parsed then ignored by OpenClaw — inert, not fatal)" )
94 except Exception as e: # noqa: BLE001
95 check( False , "frontmatter parses without error" , str (e))
96
97 # --------------------------------------------------------- 2. no render-time exec
98 print ( " \n 2. No render-time shell execution (Claude Code executes these)" )
99 md_files = [ SKILL / "SKILL.md" , * sorted (( SKILL / "references" ).glob( "*.md" ))]
100 bang_backtick = re.compile( r " (?<! [ ` \w] ) !` [ ^` ] + `" )
101 bang_fence = re.compile( r " ^\s * ```!" , re. MULTILINE )
102 for f in md_files:
103 t = f.read_text()
104 hits = bang_backtick.findall(t) + bang_fence.findall(t)
105 check( not hits, f " { f.name } : no !`cmd` or ```! blocks" , str (hits[: 2 ]))
106
107 # ------------------------------------------------------------- 3. no ../ escapes
108 print ( " \n 3. No references outside the skill directory (flattening-safe)" )
109 for f in md_files:
110 t = f.read_text()
111 # Markdown links/targets that climb out of the skill dir.
112 escapes = re.findall( r " \]\(\.\. / [ ^) ] * \) " , t) + re.findall( r " (?m) ^\s * (?: python3 ? \s + ) ? \.\. / \S + " , t)
113 check( not escapes, f " { f.name } : no ../ path references" , str (escapes[: 2 ]))
114
115 # ------------------------------------------- 4. survives isolated (flattened) copy
116 print ( " \n 4. Works after being copied in isolation (npx skills add / fs.cp fallback)" )
117 with tempfile.TemporaryDirectory() as tmp:
118 dest = Path(tmp) / "skills" / SKILL .name
119 shutil.copytree( SKILL , dest)
120 check( True , f "copied to isolated root { dest.parent } " )
121
122 # Every relative link must resolve inside the copy.
123 missing = []
124 for f in [dest / "SKILL.md" , * sorted ((dest / "references" ).glob( "*.md" ))]:
125 for target in re.findall( r " \]\( (?! https ? : ) ([ ^)# ][ ^) ] * ) \) " , f.read_text()):
126 if not (f.parent / target).exists():
127 missing.append( f " { f.name } -> { target } " )
128 check( not missing, "all relative links resolve in the isolated copy" , "; " .join(missing[: 3 ]))
129
130 # Scripts must import and the suite must pass from the copy.
131 r = subprocess.run(
132 [sys.executable, "test_x402_policy.py" ],
133 cwd = dest / "scripts" , capture_output = True , text = True , timeout = 180 ,
134 )
135 check(r.returncode == 0 , "test suite passes from the isolated copy" ,
136 r.stderr.strip().splitlines()[ - 1 ] if r.stderr else "" )
137 ran = re.search( r "Ran (\d + ) tests" , r.stderr or "" )
138 if ran:
139 print ( f " ( { ran.group( 1 ) } tests executed)" )
140
141 r = subprocess.run(
142 [sys.executable, "-c" , "import x402_policy, x402_fetch; print('ok')" ],
143 cwd = dest / "scripts" , capture_output = True , text = True , timeout = 120 ,
144 )
145 check(r.returncode == 0 , "x402_policy + x402_fetch import from the isolated copy" ,
146 r.stderr.strip().splitlines()[ - 1 ] if r.stderr else "" )
147
148 r = subprocess.run(
149 [sys.executable, "agents_pay_admin.py" , "--help" ],
150 cwd = dest / "scripts" , capture_output = True , text = True , timeout = 120 ,
151 )
152 check(r.returncode == 0 , "admin CLI runs from the isolated copy" )
153
154 # ------------------------------------------------------------------ 5. dependencies
155 print ( " \n 5. Runtime dependency surface" )
156 imports: set[ str ] = set ()
157 for py in sorted (( SKILL / "scripts" ).glob( "*.py" )):
158 # Only real import statements. A docstring line like "Dependencies: pip install
159 # valkey" or "no runtime beyond Python" would otherwise register as a module, so
160 # track triple-quoted blocks and skip their contents.
161 in_docstring = False
162 for line in py.read_text().splitlines():
163 if line.count( '"""' ) % 2 or line.count( "'''" ) % 2 :
164 in_docstring = not in_docstring
165 continue
166 if in_docstring:
167 continue
168 m = re.match( r " \s * (?: import | from )\s + ([ A-Za-z_ ][\w . ] * ) " , line)
169 if m:
170 imports.add(m.group( 1 ).split( "." )[ 0 ])
171 stdlib = set (sys.stdlib_module_names)
172 third_party = sorted (
173 i for i in imports
174 if i not in stdlib and not i.startswith( "x402" ) and i != "agents_pay_admin"
175 )
176 print ( f " third-party: { third_party or 'none' } " )
177 check( set (third_party) <= { "httpx" , "bedrock_agentcore" , "certifi" , "boto3" , "botocore" },
178 "third-party deps limited to httpx / bedrock_agentcore / certifi / boto3 / botocore" , str (third_party))
179
180 print ( f " \n{ '=' * 62 } " )
181 if failures:
182 print ( f "PORTABILITY: FAILED — { len (failures) } / { checks } checks failed" )
183 for f in failures:
184 print ( f " - { f } " )
185 sys.exit( 1 )
186 print ( f "PORTABILITY: PASSED — { checks } / { checks } checks" )
187 sys.exit( 0 )