{"id":"31d5e23d-e127-4dde-afb8-41552f264517","shortId":"wseXsX","kind":"skill","title":"smalltalk-debugger","tagline":"Systematic debugging guide for Pharo Smalltalk development. Provides expertise in error diagnosis (MessageNotUnderstood, KeyNotFound, SubscriptOutOfBounds, AssertionFailure), incremental code execution with eval tool, intermediate value inspection, error handling patterns (`on:do","description":"# Smalltalk Debugger\n\nSystematic debugging techniques for Pharo Smalltalk development using AI editors.\n\n## Core Debugging Workflow\n\nWhen tests fail or errors occur, follow this systematic approach:\n\n### 1. Identify Error Location\n\nFrom error message, confirm:\n- **Error type** (MessageNotUnderstood, KeyNotFound, etc.)\n- **Stack trace** - where error occurred\n- **Expected vs Actual** - what went wrong\n\n### 2. Verify with Partial Execution\n\nUse `/st-eval` tool to execute relevant code incrementally.\n\n**Basic error capture pattern:**\n```smalltalk\n| result |\nresult := Array new: 2.\n[ | ret |\n  ret := objA doSomething.\n  result at: 1 put: ret printString.\n] on: Error do: [:ex | result at: 2 put: ex description].\n^ result\n```\n\n**Interpreting results:**\n- `result at: 1` - Normal result (success case)\n- `result at: 2` - Error description (failure case)\n\n### 3. Check Intermediate Values\n\nInspect state at each step:\n\n```smalltalk\n| step1 step2 |\nstep1 := self getData.\nstep2 := step1 select: [:each | each isValid].\n{\n    'step1 count' -> step1 size.\n    'step2 count' -> step2 size.\n    'step2 result' -> step2 printString\n} asDictionary printString\n```\n\n### 4. Fix and Re-test\n\n1. **Fix in Tonel file** (never in Pharo)\n2. **Re-import** with `import_package`\n3. **Re-test** with `run_class_test`\n\n## When Operations Stop Responding\n\nIf MCP tool calls hang or timeout with no response, a **debugger window may have opened in the Pharo image**. Since the debugger is invisible from the AI editor, operations will appear stuck.\n\n### Detecting Hidden Debuggers\n\nUse the `read_screen` tool to capture the Pharo UI state:\n\n```\nmcp__smalltalk-interop__read_screen: target_type='world'\n```\n\nThis captures all morphs including debugger windows. Look for:\n- Window titles containing \"Debugger\", \"Error\", or \"Exception\"\n- UI hierarchy showing debugger-related components\n- Error messages or stack traces in window content\n\n### Resolution Steps\n\n1. **Notify the user**: Inform them that a debugger window appears to be open in Pharo\n2. **Request manual intervention**: Ask the user to:\n   - Check their Pharo image for open debugger windows\n   - Close any debugger windows\n   - Review the error shown in the debugger to understand the root cause\n3. **Address root cause**: Once the debugger is closed, investigate and fix the underlying error using standard debugging techniques\n4. **Retry operation**: Re-run the failed MCP operation\n\n**Note**: The Pharo debugger cannot be controlled remotely through MCP tools. User intervention in the Pharo image is required.\n\nFor complete UI debugging guidance, see [UI Debugging Reference](references/ui-debugging.md).\n\n## Essential Debugging Patterns\n\n### Pattern 1: Execute with Error Handling\n\nSafely test code that might fail:\n\n```smalltalk\n| result |\nresult := Array new: 2.\n[\n    | obj |\n    obj := MyClass new name: 'Test'.\n    result at: 1 put: obj process printString.\n] on: Error do: [:ex |\n    result at: 2 put: ex description\n].\n^ result\n```\n\n### Pattern 2: Inspect Object State\n\nCheck what object contains:\n\n```smalltalk\n{\n    'class' -> obj class name.\n    'value' -> obj printString.\n    'size' -> obj size.\n    'isEmpty' -> obj isEmpty\n} asDictionary printString\n```\n\n### Pattern 3: Debug Collection Operations\n\nTrack data flow through transformations:\n\n```smalltalk\n| items filtered mapped |\nitems := self getItems.\nfiltered := items select: [:each | each isValid].\nmapped := filtered collect: [:each | each name].\n{\n    'items size' -> items size.\n    'filtered size' -> filtered size.\n    'mapped' -> mapped printString\n} asDictionary printString\n```\n\n## Common Error Types Quick Reference\n\n### MessageNotUnderstood\n**Cause**: Method doesn't exist or typo in method name\n**Debug**: Check spelling, search implementors\n```\nmcp__smalltalk-interop__search_implementors: 'methodName'\n```\n\n### KeyNotFound\n**Cause**: Accessing non-existent Dictionary key\n**Debug**: List keys, use at:ifAbsent:\n```smalltalk\ndict keys printString\ndict at: #key ifAbsent: ['default']\n```\n\n### SubscriptOutOfBounds\n**Cause**: Collection index out of range\n**Debug**: Check size, use at:ifAbsent:\n```smalltalk\ncollection size printString\ncollection at: index ifAbsent: [nil]\n```\n\n### ZeroDivide\n**Cause**: Division by zero\n**Debug**: Check denominator before dividing\n```smalltalk\ncount = 0 ifTrue: [0] ifFalse: [sum / count]\n```\n\n### AssertionFailure (in tests)\n**Cause**: Test expectation doesn't match actual\n**Debug**: Execute test code with `/st-eval`, check if package imported\n\nFor complete error patterns and solutions, see [Error Patterns Reference](references/error-patterns.md).\n\n## Object Inspection Quick Guide\n\n### Basic Inspection\n```smalltalk\n\" Object class \"\nobj class printString\n\n\" Instance variables \"\nobj instVarNames\n\n\" Check method exists \"\nobj respondsTo: #methodName\n```\n\n### Collection Inspection\n```smalltalk\n\" Size and elements \"\ncollection size\ncollection printString\n\n\" Safe first/last \"\ncollection ifEmpty: [nil] ifNotEmpty: [:col | col first]\n```\n\n### Dictionary Inspection\n```smalltalk\n\" Keys and values \"\ndict keys\ndict values\n\n\" Safe access \"\ndict at: #key ifAbsent: ['default']\n```\n\nFor comprehensive inspection techniques, see [Inspection Techniques Reference](references/inspection-techniques.md).\n\n## Debugging Best Practices\n\n### 1. Divide into Small Steps\nBreak problems into incremental steps and verify each:\n\n```smalltalk\n\" Step 1: Verify object creation \"\nobj := MyClass new.\nobj printString\n\n\" Step 2: Verify method call \"\nresult := obj doSomething.\nresult printString\n```\n\n### 2. Always Use printString\nWhen returning objects via JSON/MCP:\n\n```smalltalk\n✅ obj printString\n✅ collection printString\n✅ dict printString\n\n❌ obj  \" Don't return raw objects \"\n```\n\n### 3. Check Intermediate Values\nNever assume - verify at each step:\n\n```smalltalk\nintermediate := obj step1.\n\" Check here \"\nresult := intermediate step2.\n\" Check here too \"\n```\n\n### 4. Use Error Handling\nAlways capture errors with `on:do:`:\n\n```smalltalk\n[\n    risky operation\n] on: Error do: [:ex |\n    \" Handle or log error \"\n    ex description\n]\n```\n\n### 5. Fix in Tonel, Not Pharo\n- ✅ Edit `.st` file → Import → Test\n- ❌ Edit in Pharo → Export → Commit\n\n## Debugging Tools\n\n### Primary Tool: `/st-eval`\n\nExecute any Smalltalk code for testing and verification:\n\n```\nmcp__smalltalk-interop__eval: 'Smalltalk version'\nmcp__smalltalk-interop__eval: '1 + 1'\nmcp__smalltalk-interop__eval: 'MyClass new doSomething printString'\n```\n\n### Code Inspection Tools\n\n```\nmcp__smalltalk-interop__get_class_source: 'ClassName'\nmcp__smalltalk-interop__get_method_source: class: 'ClassName' method: 'methodName'\nmcp__smalltalk-interop__search_implementors: 'methodName'\nmcp__smalltalk-interop__search_references: 'methodName'\n```\n\n## Practical Examples\n\n### Example 1: Test Failure\n\n**Error**: `Expected 'John Doe' but got 'John nil'`\n\n**Debug process**:\n1. Execute test code with `/st-eval`\n2. Check if lastName was set\n3. Inspect method implementation\n4. Identify missing `^ self` in setter\n5. Fix in Tonel file\n6. Re-import and re-test\n\n### Example 2: KeyNotFound\n\n**Error**: `KeyNotFound: key #age not found`\n\n**Debug process**:\n1. List dictionary keys: `dict keys`\n2. Check if age key exists: `dict includesKey: #age`\n3. Use safe access: `dict at: #age ifAbsent: [0]`\n4. Fix initialization to include age key\n\nFor complete debugging scenarios with step-by-step solutions, see [Debug Scenarios Examples](examples/debug-scenarios.md).\n\n## Troubleshooting Checklist\n\nWhen debugging, systematically check:\n\n- [ ] Read complete error message\n- [ ] Use `/st-eval` to test incrementally\n- [ ] Inspect all intermediate values\n- [ ] Check method implementation\n- [ ] Verify package was imported\n- [ ] Edit Tonel file (not Pharo)\n- [ ] Re-import after fixing\n- [ ] Re-run tests\n\n## Complete Documentation\n\nThis skill provides focused debugging guidance. For comprehensive information:\n\n- **[Error Patterns Reference](references/error-patterns.md)** - All error types with solutions\n- **[Inspection Techniques](references/inspection-techniques.md)** - Complete object inspection guide\n- **[Debug Scenarios](examples/debug-scenarios.md)** - Real-world debugging examples\n\n## Summary\n\n**Core debugging cycle:**\n\n```\nError occurs\n    ↓\nIdentify error type\n    ↓\nUse /st-eval to test incrementally\n    ↓\nInspect intermediate values\n    ↓\nIdentify root cause\n    ↓\nFix in Tonel file\n    ↓\nRe-import\n    ↓\nRe-test → Success or repeat\n```\n\n**Remember**: Systematic approach, incremental testing, fix in Tonel, always re-import.","tags":["smalltalk","debugger","dev","plugin","mumez","agent-skills","agents","claude-code","marketplace","mcp","pharo-smalltalk","skills"],"capabilities":["skill","source-mumez","skill-smalltalk-debugger","topic-agent-skills","topic-agents","topic-claude-code","topic-marketplace","topic-mcp","topic-pharo-smalltalk","topic-plugin","topic-skills","topic-smalltalk"],"categories":["smalltalk-dev-plugin"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/mumez/smalltalk-dev-plugin/smalltalk-debugger","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add mumez/smalltalk-dev-plugin","source_repo":"https://github.com/mumez/smalltalk-dev-plugin","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (8,534 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T07:03:21.813Z","embedding":null,"createdAt":"2026-04-23T13:04:03.280Z","updatedAt":"2026-04-24T07:03:21.813Z","lastSeenAt":"2026-04-24T07:03:21.813Z","tsv":"'/st-eval':89,624,831,920,1018,1092 '0':603,605,984 '1':59,112,131,184,300,410,435,710,725,852,853,902,915,961 '2':83,105,122,138,192,316,426,446,452,735,744,921,951,967 '3':143,199,348,477,766,927,976 '4':178,367,788,931,985 '5':811,937 '6':942 'access':548,692,979 'actual':79,618 'address':349 'age':956,970,975,982,990 'ai':44,238 'alway':745,792,1123 'appear':242,310 'approach':58,1117 'array':103,424 'asdictionari':176,474,516 'ask':320 'assertionfailur':19,609 'assum':771 'basic':96,644 'best':708 'break':715 'call':214,738 'cannot':381 'captur':98,253,268,793 'case':135,142 'caus':347,351,524,547,570,592,612,1101 'check':144,324,456,535,577,597,625,656,767,780,785,922,968,1012,1026 'checklist':1008 'class':205,461,463,648,650,871,881 'classnam':873,882 'close':332,356 'code':21,94,417,622,835,863,918 'col':678,679 'collect':479,501,571,583,586,662,668,670,674,756 'commit':826 'common':518 'complet':397,630,993,1014,1047,1070 'compon':289 'comprehens':699,1056 'confirm':66 'contain':278,459 'content':297 'control':383 'core':46,1083 'count':165,169,602,608 'creation':728 'cycl':1085 'data':482 'debug':5,37,47,365,399,403,407,478,534,554,576,596,619,707,827,913,959,994,1003,1010,1053,1074,1080,1084 'debugg':3,35,222,233,246,272,279,287,308,330,334,342,354,380 'debugger-rel':286 'default':568,697 'denomin':598 'descript':125,140,449,810 'detect':244 'develop':10,42 'diagnosi':15 'dict':561,564,687,689,693,758,965,973,980 'dictionari':552,681,963 'divid':600,711 'divis':593 'document':1048 'doe':908 'doesn':526,615 'dosometh':109,741,861 'edit':817,822,1033 'editor':45,239 'element':667 'error':14,29,53,61,64,67,75,97,117,139,280,290,338,362,413,441,519,631,636,790,794,802,808,905,953,1015,1058,1063,1086,1089 'essenti':406 'etc':71 'eval':24,844,851,858 'ex':119,124,443,448,804,809 'exampl':900,901,950,1005,1081 'examples/debug-scenarios.md':1006,1076 'except':282 'execut':22,87,92,411,620,832,916 'exist':528,551,658,972 'expect':77,614,906 'expertis':12 'export':825 'fail':51,374,420 'failur':141,904 'file':188,819,941,1035,1105 'filter':488,493,500,509,511 'first':680 'first/last':673 'fix':179,185,359,812,938,986,1042,1102,1120 'flow':483 'focus':1052 'follow':55 'found':958 'get':870,878 'getdata':157 'getitem':492 'got':910 'guid':6,643,1073 'guidanc':400,1054 'handl':30,414,791,805 'hang':215 'hidden':245 'hierarchi':284 'identifi':60,932,1088,1099 'ifabs':559,567,581,589,696,983 'ifempti':675 'iffals':606 'ifnotempti':677 'iftru':604 'imag':230,327,393 'implement':930,1028 'implementor':538,544,890 'import':195,197,628,820,945,1032,1040,1108,1126 'includ':271,989 'includeskey':974 'increment':20,95,718,1021,1095,1118 'index':572,588 'inform':304,1057 'initi':987 'inspect':28,147,453,641,645,663,682,700,703,864,928,1022,1067,1072,1096 'instanc':652 'instvarnam':655 'intermedi':26,145,768,777,783,1024,1097 'interop':261,542,843,850,857,869,877,888,895 'interpret':127 'intervent':319,389 'investig':357 'invis':235 'isempti':471,473 'isvalid':163,498 'item':487,490,494,505,507 'john':907,911 'json/mcp':752 'key':553,556,562,566,684,688,695,955,964,966,971,991 'keynotfound':17,70,546,952,954 'lastnam':924 'list':555,962 'locat':62 'log':807 'look':274 'manual':318 'map':489,499,513,514 'match':617 'may':224 'mcp':212,258,375,386,539,840,847,854,866,874,885,892 'messag':65,291,1016 'messagenotunderstood':16,69,523 'method':525,532,657,737,879,883,929,1027 'methodnam':545,661,884,891,898 'might':419 'miss':933 'morph':270 'myclass':429,730,859 'name':431,464,504,533 'never':189,770 'new':104,425,430,731,860 'nil':590,676,912 'non':550 'non-exist':549 'normal':132 'note':377 'notifi':301 'obj':427,428,437,462,466,469,472,649,654,659,729,732,740,754,760,778 'obja':108 'object':454,458,640,647,727,750,765,1071 'occur':54,76,1087 'open':226,313,329 'oper':208,240,369,376,480,800 'packag':198,627,1030 'partial':86 'pattern':31,99,408,409,451,476,632,637,1059 'pharo':8,40,191,229,255,315,326,379,392,816,824,1037 'practic':709,899 'primari':829 'printstr':115,175,177,439,467,475,515,517,563,585,651,671,733,743,747,755,757,759,862 'problem':716 'process':438,914,960 'provid':11,1051 'put':113,123,436,447 'quick':521,642 'rang':575 'raw':764 're':182,194,201,371,944,948,1039,1044,1107,1110,1125 're-import':193,943,1038,1106,1124 're-run':370,1043 're-test':181,200,947,1109 'read':249,262,1013 'real':1078 'real-world':1077 'refer':404,522,638,705,897,1060 'references/error-patterns.md':639,1061 'references/inspection-techniques.md':706,1069 'references/ui-debugging.md':405 'relat':288 'relev':93 'rememb':1115 'remot':384 'repeat':1114 'request':317 'requir':395 'resolut':298 'respond':210 'respondsto':660 'respons':220 'result':101,102,110,120,126,128,129,133,136,173,422,423,433,444,450,739,742,782 'ret':106,107,114 'retri':368 'return':749,763 'review':336 'riski':799 'root':346,350,1100 'run':204,372,1045 'safe':415,672,691,978 'scenario':995,1004,1075 'screen':250,263 'search':537,543,889,896 'see':401,635,702,1002 'select':160,495 'self':156,491,934 'set':926 'setter':936 'show':285 'shown':339 'sinc':231 'size':167,171,468,470,506,508,510,512,578,584,665,669 'skill':1050 'skill-smalltalk-debugger' 'small':713 'smalltalk':2,9,34,41,100,152,260,421,460,486,541,560,582,601,646,664,683,723,753,776,798,834,842,845,849,856,868,876,887,894 'smalltalk-debugg':1 'smalltalk-interop':259,540,841,848,855,867,875,886,893 'solut':634,1001,1066 'sourc':872,880 'source-mumez' 'spell':536 'st':818 'stack':72,293 'standard':364 'state':148,257,455 'step':151,299,714,719,724,734,775,998,1000 'step-by-step':997 'step1':153,155,159,164,166,779 'step2':154,158,168,170,172,174,784 'stop':209 'stuck':243 'subscriptoutofbound':18,569 'success':134,1112 'sum':607 'summari':1082 'systemat':4,36,57,1011,1116 'target':264 'techniqu':38,366,701,704,1068 'test':50,183,202,206,416,432,611,613,621,821,837,903,917,949,1020,1046,1094,1111,1119 'timeout':217 'titl':277 'tonel':187,814,940,1034,1104,1122 'tool':25,90,213,251,387,828,830,865 'topic-agent-skills' 'topic-agents' 'topic-claude-code' 'topic-marketplace' 'topic-mcp' 'topic-pharo-smalltalk' 'topic-plugin' 'topic-skills' 'topic-smalltalk' 'trace':73,294 'track':481 'transform':485 'troubleshoot':1007 'type':68,265,520,1064,1090 'typo':530 'ui':256,283,398,402 'under':361 'understand':344 'use':43,88,247,363,557,579,746,789,977,1017,1091 'user':303,322,388 'valu':27,146,465,686,690,769,1025,1098 'variabl':653 'verif':839 'verifi':84,721,726,736,772,1029 'version':846 'via':751 'vs':78 'went':81 'window':223,273,276,296,309,331,335 'workflow':48 'world':266,1079 'wrong':82 'zero':595 'zerodivid':591","prices":[{"id":"3bc9c7c8-1d33-4c63-a69a-1f85e02027f5","listingId":"31d5e23d-e127-4dde-afb8-41552f264517","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"mumez","category":"smalltalk-dev-plugin","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:03.280Z"}],"sources":[{"listingId":"31d5e23d-e127-4dde-afb8-41552f264517","source":"github","sourceId":"mumez/smalltalk-dev-plugin/smalltalk-debugger","sourceUrl":"https://github.com/mumez/smalltalk-dev-plugin/tree/develop/skills/smalltalk-debugger","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:03.280Z","lastSeenAt":"2026-04-24T07:03:21.813Z"}],"details":{"listingId":"31d5e23d-e127-4dde-afb8-41552f264517","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"mumez","slug":"smalltalk-debugger","github":{"repo":"mumez/smalltalk-dev-plugin","stars":11,"topics":["agent-skills","agents","claude-code","marketplace","mcp","pharo-smalltalk","plugin","skills","smalltalk"],"license":"mit","html_url":"https://github.com/mumez/smalltalk-dev-plugin","pushed_at":"2026-04-21T15:21:41Z","description":"Claude Code plugin for AI-driven Smalltalk (Pharo) development","skill_md_sha":"acaf9479a8eb8325d59fe044a589f36b1bb271f1","skill_md_path":"skills/smalltalk-debugger/SKILL.md","default_branch":"develop","skill_tree_url":"https://github.com/mumez/smalltalk-dev-plugin/tree/develop/skills/smalltalk-debugger"},"layout":"multi","source":"github","category":"smalltalk-dev-plugin","frontmatter":{"name":"smalltalk-debugger","description":"Systematic debugging guide for Pharo Smalltalk development. Provides expertise in error diagnosis (MessageNotUnderstood, KeyNotFound, SubscriptOutOfBounds, AssertionFailure), incremental code execution with eval tool, intermediate value inspection, error handling patterns (`on:do:` blocks), stack trace analysis, UI debugger window detection (read_screen for hung operations), and debug-fix-reimport workflow. Use when encountering Pharo test failures, Smalltalk exceptions, unexpected behavior, timeout or non-responsive operations, need to verify intermediate values, execute code incrementally for diagnosis, or troubleshoot Tonel import errors."},"skills_sh_url":"https://skills.sh/mumez/smalltalk-dev-plugin/smalltalk-debugger"},"updatedAt":"2026-04-24T07:03:21.813Z"}}