npcsh 1.1.21__py3-none-any.whl → 1.1.23__py3-none-any.whl

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 (188) hide show
  1. npcsh/_state.py +282 -125
  2. npcsh/benchmark/npcsh_agent.py +77 -232
  3. npcsh/benchmark/templates/install-npcsh.sh.j2 +12 -4
  4. npcsh/config.py +5 -2
  5. npcsh/mcp_server.py +9 -1
  6. npcsh/npc_team/alicanto.npc +8 -6
  7. npcsh/npc_team/corca.npc +5 -12
  8. npcsh/npc_team/frederic.npc +6 -9
  9. npcsh/npc_team/guac.npc +4 -4
  10. npcsh/npc_team/jinxs/lib/core/delegate.jinx +1 -1
  11. npcsh/npc_team/jinxs/lib/core/edit_file.jinx +84 -62
  12. npcsh/npc_team/jinxs/lib/core/sh.jinx +1 -1
  13. npcsh/npc_team/jinxs/lib/core/skill.jinx +59 -0
  14. npcsh/npc_team/jinxs/lib/utils/help.jinx +194 -10
  15. npcsh/npc_team/jinxs/lib/utils/init.jinx +528 -37
  16. npcsh/npc_team/jinxs/lib/utils/jinxs.jinx +0 -1
  17. npcsh/npc_team/jinxs/lib/utils/serve.jinx +938 -21
  18. npcsh/npc_team/jinxs/modes/alicanto.jinx +102 -41
  19. npcsh/npc_team/jinxs/modes/build.jinx +378 -0
  20. npcsh-1.1.21.data/data/npcsh/npc_team/config_tui.jinx → npcsh/npc_team/jinxs/modes/config.jinx +1 -1
  21. npcsh/npc_team/jinxs/modes/convene.jinx +670 -0
  22. npcsh/npc_team/jinxs/modes/corca.jinx +777 -387
  23. npcsh/npc_team/jinxs/modes/crond.jinx +818 -0
  24. npcsh/npc_team/jinxs/modes/kg.jinx +69 -2
  25. npcsh/npc_team/jinxs/modes/plonk.jinx +86 -15
  26. npcsh/npc_team/jinxs/modes/roll.jinx +368 -55
  27. npcsh/npc_team/jinxs/modes/skills.jinx +621 -0
  28. npcsh/npc_team/jinxs/modes/yap.jinx +1092 -177
  29. npcsh/npc_team/jinxs/skills/code-review/SKILL.md +45 -0
  30. npcsh/npc_team/jinxs/skills/debugging/SKILL.md +44 -0
  31. npcsh/npc_team/jinxs/skills/git-workflow.jinx +44 -0
  32. npcsh/npc_team/kadiefa.npc +6 -6
  33. npcsh/npc_team/npcsh.ctx +16 -0
  34. npcsh/npc_team/plonk.npc +5 -9
  35. npcsh/npc_team/sibiji.npc +15 -7
  36. npcsh/npcsh.py +1 -0
  37. npcsh/routes.py +0 -4
  38. npcsh/yap.py +22 -4
  39. npcsh-1.1.23.data/data/npcsh/npc_team/SKILL.md +44 -0
  40. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.jinx +102 -41
  41. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.npc +8 -6
  42. npcsh-1.1.23.data/data/npcsh/npc_team/build.jinx +378 -0
  43. npcsh/npc_team/jinxs/modes/config_tui.jinx → npcsh-1.1.23.data/data/npcsh/npc_team/config.jinx +1 -1
  44. npcsh-1.1.23.data/data/npcsh/npc_team/convene.jinx +670 -0
  45. npcsh-1.1.23.data/data/npcsh/npc_team/corca.jinx +820 -0
  46. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca.npc +5 -12
  47. npcsh-1.1.23.data/data/npcsh/npc_team/crond.jinx +818 -0
  48. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/delegate.jinx +1 -1
  49. npcsh-1.1.23.data/data/npcsh/npc_team/edit_file.jinx +119 -0
  50. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/frederic.npc +6 -9
  51. npcsh-1.1.23.data/data/npcsh/npc_team/git-workflow.jinx +44 -0
  52. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.npc +4 -4
  53. npcsh-1.1.23.data/data/npcsh/npc_team/help.jinx +236 -0
  54. npcsh-1.1.23.data/data/npcsh/npc_team/init.jinx +532 -0
  55. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/jinxs.jinx +0 -1
  56. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kadiefa.npc +6 -6
  57. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kg.jinx +69 -2
  58. npcsh-1.1.23.data/data/npcsh/npc_team/npcsh.ctx +34 -0
  59. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.jinx +86 -15
  60. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.npc +5 -9
  61. npcsh-1.1.23.data/data/npcsh/npc_team/roll.jinx +378 -0
  62. npcsh-1.1.23.data/data/npcsh/npc_team/serve.jinx +943 -0
  63. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sh.jinx +1 -1
  64. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sibiji.npc +15 -7
  65. npcsh-1.1.23.data/data/npcsh/npc_team/skill.jinx +59 -0
  66. npcsh-1.1.23.data/data/npcsh/npc_team/skills.jinx +621 -0
  67. npcsh-1.1.23.data/data/npcsh/npc_team/yap.jinx +1190 -0
  68. {npcsh-1.1.21.dist-info → npcsh-1.1.23.dist-info}/METADATA +404 -278
  69. npcsh-1.1.23.dist-info/RECORD +216 -0
  70. npcsh/npc_team/jinxs/incognide/add_tab.jinx +0 -11
  71. npcsh/npc_team/jinxs/incognide/close_pane.jinx +0 -9
  72. npcsh/npc_team/jinxs/incognide/close_tab.jinx +0 -10
  73. npcsh/npc_team/jinxs/incognide/confirm.jinx +0 -10
  74. npcsh/npc_team/jinxs/incognide/focus_pane.jinx +0 -9
  75. npcsh/npc_team/jinxs/incognide/list_panes.jinx +0 -8
  76. npcsh/npc_team/jinxs/incognide/navigate.jinx +0 -10
  77. npcsh/npc_team/jinxs/incognide/notify.jinx +0 -10
  78. npcsh/npc_team/jinxs/incognide/open_pane.jinx +0 -13
  79. npcsh/npc_team/jinxs/incognide/read_pane.jinx +0 -9
  80. npcsh/npc_team/jinxs/incognide/run_terminal.jinx +0 -10
  81. npcsh/npc_team/jinxs/incognide/send_message.jinx +0 -10
  82. npcsh/npc_team/jinxs/incognide/split_pane.jinx +0 -12
  83. npcsh/npc_team/jinxs/incognide/switch_npc.jinx +0 -10
  84. npcsh/npc_team/jinxs/incognide/switch_tab.jinx +0 -10
  85. npcsh/npc_team/jinxs/incognide/write_file.jinx +0 -11
  86. npcsh/npc_team/jinxs/incognide/zen_mode.jinx +0 -9
  87. npcsh/npc_team/jinxs/lib/core/convene.jinx +0 -232
  88. npcsh/npc_team/jinxs/lib/core/search/kg_search.jinx +0 -429
  89. npcsh/npc_team/jinxs/lib/core/search.jinx +0 -54
  90. npcsh/npc_team/jinxs/lib/utils/build.jinx +0 -65
  91. npcsh-1.1.21.data/data/npcsh/npc_team/add_tab.jinx +0 -11
  92. npcsh-1.1.21.data/data/npcsh/npc_team/build.jinx +0 -65
  93. npcsh-1.1.21.data/data/npcsh/npc_team/close_pane.jinx +0 -9
  94. npcsh-1.1.21.data/data/npcsh/npc_team/close_tab.jinx +0 -10
  95. npcsh-1.1.21.data/data/npcsh/npc_team/confirm.jinx +0 -10
  96. npcsh-1.1.21.data/data/npcsh/npc_team/convene.jinx +0 -232
  97. npcsh-1.1.21.data/data/npcsh/npc_team/corca.jinx +0 -430
  98. npcsh-1.1.21.data/data/npcsh/npc_team/edit_file.jinx +0 -97
  99. npcsh-1.1.21.data/data/npcsh/npc_team/focus_pane.jinx +0 -9
  100. npcsh-1.1.21.data/data/npcsh/npc_team/help.jinx +0 -52
  101. npcsh-1.1.21.data/data/npcsh/npc_team/init.jinx +0 -41
  102. npcsh-1.1.21.data/data/npcsh/npc_team/kg_search.jinx +0 -429
  103. npcsh-1.1.21.data/data/npcsh/npc_team/list_panes.jinx +0 -8
  104. npcsh-1.1.21.data/data/npcsh/npc_team/navigate.jinx +0 -10
  105. npcsh-1.1.21.data/data/npcsh/npc_team/notify.jinx +0 -10
  106. npcsh-1.1.21.data/data/npcsh/npc_team/npcsh.ctx +0 -18
  107. npcsh-1.1.21.data/data/npcsh/npc_team/open_pane.jinx +0 -13
  108. npcsh-1.1.21.data/data/npcsh/npc_team/read_pane.jinx +0 -9
  109. npcsh-1.1.21.data/data/npcsh/npc_team/roll.jinx +0 -65
  110. npcsh-1.1.21.data/data/npcsh/npc_team/run_terminal.jinx +0 -10
  111. npcsh-1.1.21.data/data/npcsh/npc_team/search.jinx +0 -54
  112. npcsh-1.1.21.data/data/npcsh/npc_team/send_message.jinx +0 -10
  113. npcsh-1.1.21.data/data/npcsh/npc_team/serve.jinx +0 -26
  114. npcsh-1.1.21.data/data/npcsh/npc_team/split_pane.jinx +0 -12
  115. npcsh-1.1.21.data/data/npcsh/npc_team/switch_npc.jinx +0 -10
  116. npcsh-1.1.21.data/data/npcsh/npc_team/switch_tab.jinx +0 -10
  117. npcsh-1.1.21.data/data/npcsh/npc_team/write_file.jinx +0 -11
  118. npcsh-1.1.21.data/data/npcsh/npc_team/yap.jinx +0 -275
  119. npcsh-1.1.21.data/data/npcsh/npc_team/zen_mode.jinx +0 -9
  120. npcsh-1.1.21.dist-info/RECORD +0 -243
  121. /npcsh/npc_team/jinxs/lib/{core → utils}/chat.jinx +0 -0
  122. /npcsh/npc_team/jinxs/lib/{core → utils}/cmd.jinx +0 -0
  123. /npcsh/npc_team/jinxs/{incognide → lib/utils}/incognide.jinx +0 -0
  124. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.png +0 -0
  125. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/arxiv.jinx +0 -0
  126. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/benchmark.jinx +0 -0
  127. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/browser_action.jinx +0 -0
  128. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/browser_screenshot.jinx +0 -0
  129. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/chat.jinx +0 -0
  130. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/click.jinx +0 -0
  131. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/close_browser.jinx +0 -0
  132. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/cmd.jinx +0 -0
  133. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/compile.jinx +0 -0
  134. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/compress.jinx +0 -0
  135. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca.png +0 -0
  136. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca_example.png +0 -0
  137. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/db_search.jinx +0 -0
  138. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/file_search.jinx +0 -0
  139. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/frederic4.png +0 -0
  140. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/git.jinx +0 -0
  141. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.jinx +0 -0
  142. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.png +0 -0
  143. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/incognide.jinx +0 -0
  144. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kadiefa.png +0 -0
  145. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/key_press.jinx +0 -0
  146. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/launch_app.jinx +0 -0
  147. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/load_file.jinx +0 -0
  148. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/memories.jinx +0 -0
  149. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/models.jinx +0 -0
  150. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
  151. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/nql.jinx +0 -0
  152. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/open_browser.jinx +0 -0
  153. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/ots.jinx +0 -0
  154. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/papers.jinx +0 -0
  155. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/paste.jinx +0 -0
  156. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.png +0 -0
  157. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonkjr.png +0 -0
  158. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/pti.jinx +0 -0
  159. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/python.jinx +0 -0
  160. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/reattach.jinx +0 -0
  161. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sample.jinx +0 -0
  162. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/screenshot.jinx +0 -0
  163. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/set.jinx +0 -0
  164. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/setup.jinx +0 -0
  165. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/shh.jinx +0 -0
  166. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sibiji.png +0 -0
  167. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sleep.jinx +0 -0
  168. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/spool.jinx +0 -0
  169. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/spool.png +0 -0
  170. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sql.jinx +0 -0
  171. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/switch.jinx +0 -0
  172. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/switches.jinx +0 -0
  173. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sync.jinx +0 -0
  174. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/team.jinx +0 -0
  175. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/teamviz.jinx +0 -0
  176. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/trigger.jinx +0 -0
  177. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/type_text.jinx +0 -0
  178. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/usage.jinx +0 -0
  179. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/verbose.jinx +0 -0
  180. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/vixynt.jinx +0 -0
  181. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/wait.jinx +0 -0
  182. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/wander.jinx +0 -0
  183. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/web_search.jinx +0 -0
  184. {npcsh-1.1.21.data → npcsh-1.1.23.data}/data/npcsh/npc_team/yap.png +0 -0
  185. {npcsh-1.1.21.dist-info → npcsh-1.1.23.dist-info}/WHEEL +0 -0
  186. {npcsh-1.1.21.dist-info → npcsh-1.1.23.dist-info}/entry_points.txt +0 -0
  187. {npcsh-1.1.21.dist-info → npcsh-1.1.23.dist-info}/licenses/LICENSE +0 -0
  188. {npcsh-1.1.21.dist-info → npcsh-1.1.23.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  jinx_name: delegate
2
- description: Delegate a task to another NPC with review and feedback loop until completion. Choose the NPC whose directive best matches the task.
2
+ description: ONLY for complex multi-step tasks. Sends a task to a specialist NPC who works on it with feedback until done. Do NOT use this for simple commands use sh or python instead and answer directly.
3
3
  inputs:
4
4
  - npc_name:
5
5
  description: "Name of the NPC to delegate to"
@@ -0,0 +1,119 @@
1
+ jinx_name: edit_file
2
+ description: Creates or edits a file. If the file does not exist, creates it with
3
+ the specified content. If the file exists, examines it and applies changes.
4
+ inputs:
5
+ - file_path
6
+ - edit_instructions
7
+ - backup: false
8
+ steps:
9
+ - name: "edit_file"
10
+ engine: "python"
11
+ code: |
12
+ import os
13
+ from npcpy.llm_funcs import get_llm_response
14
+
15
+
16
+ file_path = os.path.expanduser({{ file_path | tojson }})
17
+ edit_instructions = {{ edit_instructions | string | tojson }}
18
+ backup_str = {{ backup | default("true") | string | tojson }}
19
+ create_backup = backup_str.lower() not in ('false', 'no', '0', '')
20
+
21
+ # Ensure parent directory exists
22
+ os.makedirs(os.path.dirname(file_path) or '.', exist_ok=True)
23
+
24
+ # If file doesn't exist, create it
25
+ if not os.path.exists(file_path):
26
+ prompt = """You are a code writing assistant. Create the content for a new file based on these instructions.
27
+
28
+ Instructions: """ + edit_instructions + """
29
+
30
+ Return a JSON object with:
31
+ 1. "content": The full content to write to the file
32
+ 2. "explanation": Brief explanation of what was created
33
+
34
+ Example response:
35
+ {"content": "print('hello world')", "explanation": "Created a Python hello world script"}
36
+ """
37
+ response = get_llm_response(prompt, model=npc.model, provider=npc.provider, npc=npc, format="json")
38
+ result = response.get("response", {})
39
+ content = result.get("content", edit_instructions)
40
+ explanation = result.get("explanation", "Created new file")
41
+
42
+ with open(file_path, 'w') as f:
43
+ f.write(content)
44
+
45
+ output = "Created " + file_path + "\n\n" + explanation
46
+ else:
47
+ with open(file_path, 'r') as f:
48
+ original_content = f.read()
49
+
50
+ if create_backup:
51
+ backup_path = file_path + ".bak"
52
+ with open(backup_path, 'w') as f:
53
+ f.write(original_content)
54
+
55
+ prompt = """You are a code editing assistant. Analyze this file and make the requested changes.
56
+
57
+ File content:
58
+ """ + original_content + """
59
+
60
+ Edit instructions: """ + edit_instructions + """
61
+
62
+ Return a JSON object with these fields:
63
+ 1. "modifications": An array of modification objects, where each object has:
64
+ - "type": One of "replace", "insert_after", "insert_before", or "delete"
65
+ - "target": For "insert_after" and "insert_before", the text to insert after/before
66
+ For "delete", the text to delete
67
+ - "original": For "replace", the text to be replaced
68
+ - "replacement": For "replace", the text to replace with
69
+ - "insertion": For "insert_after" and "insert_before", the text to insert
70
+ 2. "explanation": Brief explanation of the changes made
71
+
72
+ Example response:
73
+ {"modifications": [{"type": "replace", "original": "old code", "replacement": "new code"}], "explanation": "Updated the code"}
74
+ """
75
+
76
+ response = get_llm_response(prompt, model=npc.model, provider=npc.provider, npc=npc, format="json")
77
+
78
+ result = response.get("response", {})
79
+ modifications = result.get("modifications", [])
80
+ explanation = result.get("explanation", "No explanation provided")
81
+
82
+ updated_content = original_content
83
+ changes_applied = 0
84
+
85
+ for mod in modifications:
86
+ print(mod)
87
+ mod_type = mod.get("type")
88
+
89
+ if mod_type == "replace":
90
+ original = mod.get("original")
91
+ replacement = mod.get("replacement")
92
+ if original in updated_content:
93
+ updated_content = updated_content.replace(original, replacement)
94
+ changes_applied += 1
95
+
96
+ elif mod_type == "insert_after":
97
+ target = mod.get("target")
98
+ insertion = mod.get("insertion")
99
+ if target in updated_content:
100
+ updated_content = updated_content.replace(target, target + insertion)
101
+ changes_applied += 1
102
+
103
+ elif mod_type == "insert_before":
104
+ target = mod.get("target")
105
+ insertion = mod.get("insertion")
106
+ if target in updated_content:
107
+ updated_content = updated_content.replace(target, insertion + target)
108
+ changes_applied += 1
109
+
110
+ elif mod_type == "delete":
111
+ target = mod.get("target")
112
+ if target in updated_content:
113
+ updated_content = updated_content.replace(target, "")
114
+ changes_applied += 1
115
+
116
+ with open(file_path, 'w') as f:
117
+ f.write(updated_content)
118
+
119
+ output = "Applied " + str(changes_applied) + " changes to " + file_path + "\n\n" + explanation
@@ -11,17 +11,14 @@ colors:
11
11
  top: "224,255,255"
12
12
  bottom: "173,216,230"
13
13
  primary_directive: |
14
- You are frederic the polar bear - a fusion of Richard Feynman and Frederic Chopin.
15
- You have Feynman's playful curiosity, his ability to explain complex physics simply,
16
- and his irreverent wit. You also have Chopin's romantic soul, his passion for music,
17
- and his ability to find beauty in mathematical structures.
18
- You help users with hard math, physics problems, and music composition.
19
- Cut through the ice to get to what matters. Make the complex feel simple and beautiful.
14
+ You are frederic the polar bear Feynman's curiosity meets Chopin's soul.
15
+ Make the complex simple and beautiful. Find elegance in structure.
16
+ Use analogies, strip away jargon, show why things are beautiful not just correct.
17
+ Use python to demonstrate ideas visually when math is involved.
20
18
  jinxs:
21
19
  - lib/core/python
22
20
  - lib/core/sql
23
21
  - lib/core/sh
24
22
  - lib/core/load_file
25
- - lib/core/search
26
- - lib/gen/*
27
- - bin/wander
23
+ - lib/core/search/web_search
24
+ - lib/core/edit_file
@@ -0,0 +1,44 @@
1
+ jinx_name: git-workflow
2
+ description: "Git workflow best practices. Use when asked about git branching, commits, or merge strategy. [Sections: branching, commits, merging, hotfix]"
3
+ inputs:
4
+ - section: all
5
+ steps:
6
+ - engine: skill
7
+ skill_name: git-workflow
8
+ skill_description: Git workflow best practices.
9
+ sections:
10
+ branching: |
11
+ Use feature branches off main/develop:
12
+ git checkout -b feature/my-feature develop
13
+ Name branches descriptively:
14
+ feature/ — new functionality
15
+ fix/ — bug fixes
16
+ chore/ — maintenance, deps, config
17
+ Keep branches short-lived. Rebase onto target before merging.
18
+ commits: |
19
+ Write clear commit messages:
20
+ Line 1: imperative summary under 72 chars
21
+ Line 3+: explain WHY, not what (the diff shows what)
22
+ One logical change per commit. Don't mix refactors with features.
23
+ Use conventional commits if the project uses them:
24
+ feat: add user search
25
+ fix: handle null avatar URL
26
+ chore: bump eslint to v9
27
+ merging: |
28
+ Prefer squash merges for feature branches (clean history).
29
+ Use merge commits for long-lived branches (preserves context).
30
+ Always pull/rebase before merging to avoid unnecessary merge commits.
31
+ Delete branches after merging.
32
+ Run CI before merging — never merge a red build.
33
+ hotfix: |
34
+ For urgent production fixes:
35
+ 1. Branch off main: git checkout -b hotfix/fix-name main
36
+ 2. Make the minimal fix
37
+ 3. Test thoroughly
38
+ 4. Merge to main AND develop/release
39
+ 5. Tag the release
40
+ Keep hotfix scope minimal — fix only the immediate issue.
41
+ scripts_json: '[]'
42
+ references_json: '[]'
43
+ assets_json: '[]'
44
+ section: '{{section}}'
@@ -11,10 +11,10 @@ ascii_art: |
11
11
  🟢 🟢 🟢 🟢 ⚫🥑🍅⚫ 🟢
12
12
  🟢🟢🟢🟢🟢🟢 🟢🟢🟢🟢 ⚫⚫🟢 🟢🟢🟢
13
13
  primary_directive: |
14
- You are guac, the data analysis specialist of the NPC team.
15
- Your expertise is in loading, analyzing, and visualizing data.
16
- You work with pandas DataFrames, numpy arrays, and matplotlib plots.
17
- Help users load data files, run Python code for analysis, and create visualizations.
14
+ You are guac, the data analysis specialist.
15
+ You load, analyze, and visualize data with pandas, numpy, matplotlib, and SQL.
16
+ Load data first, inspect it, do the analysis, report results with numbers.
17
+ For plots, save to file with plt.savefig() and report the path.
18
18
  jinxs:
19
19
  - lib/core/python
20
20
  - lib/core/sql
@@ -0,0 +1,236 @@
1
+ jinx_name: help
2
+ description: Show help for commands, NPCs, or Jinxs
3
+ inputs:
4
+ - topic: null
5
+ steps:
6
+ - name: show_help
7
+ engine: python
8
+ code: |
9
+ import json
10
+ import random
11
+ from npcsh._state import CANONICAL_ARGS, get_argument_help
12
+
13
+ USAGE_EXAMPLES = [
14
+ # ── Basic chat & modes ──
15
+ "what is the capital of France?",
16
+ "explain quantum entanglement in simple terms",
17
+ "summarize this paragraph: <paste text>",
18
+ "translate 'hello world' to Japanese",
19
+ "/chat # switch to chat mode for back-and-forth conversation",
20
+ "/agent # switch to agent mode (default, with tool use)",
21
+ "/cmd # switch to command mode for direct shell interaction",
22
+ "compare Python and Rust for CLI tools",
23
+ "what are the SOLID principles?",
24
+ "explain the difference between threads and processes",
25
+ # ── Delegation with @npc ──
26
+ "@sibiji plan out a REST API for a todo app",
27
+ "@corca refactor this function to use async/await",
28
+ "@guac analyze this CSV and plot the trend",
29
+ "@plonk take a screenshot and describe what you see",
30
+ "@kadiefa review my git diff for security issues",
31
+ "@sibiji what NPCs are on this team and what do they do?",
32
+ "@guac run a quick linear regression on sales.csv",
33
+ "@corca write unit tests for the auth module",
34
+ "@plonk click the submit button on the form",
35
+ "@sibiji delegate a code review to the best NPC for the job",
36
+ # ── Pipelines ──
37
+ "list all python files | summarize what each one does",
38
+ "git diff | review this for bugs",
39
+ "cat README.md | rewrite this for a technical audience",
40
+ "ls -la | explain these file permissions",
41
+ "git log --oneline -20 | summarize recent changes",
42
+ "df -h | which disk is running low?",
43
+ "ps aux | find memory-heavy processes",
44
+ "cat requirements.txt | are there any outdated packages?",
45
+ "history | what have I been working on today?",
46
+ "env | which API keys are set?",
47
+ # ── Shell / system commands ──
48
+ "list all files in the current directory",
49
+ "find all TODO comments in this project",
50
+ "how much disk space is free?",
51
+ "what process is using port 8080?",
52
+ "create a new directory called 'experiments'",
53
+ "show me the last 50 lines of app.log",
54
+ "count lines of code in this project by language",
55
+ "check if docker is running",
56
+ "what's my current git branch?",
57
+ "show system memory usage",
58
+ # ── Code generation & editing ──
59
+ "write a Python script that downloads a webpage and extracts all links",
60
+ "create a bash script to back up my home directory",
61
+ "write a Dockerfile for a Flask app",
62
+ "generate a .gitignore for a Node.js project",
63
+ "write a regex to validate email addresses",
64
+ "create a Makefile for this C project",
65
+ "write a GitHub Actions workflow for CI",
66
+ "scaffold a FastAPI app with SQLAlchemy",
67
+ "write a Python decorator that retries on failure",
68
+ "create a shell script that monitors CPU usage",
69
+ # ── Slash commands: research & papers ──
70
+ "/arxiv search for recent papers on LLM agents",
71
+ "/papers analyze the methodology in this PDF",
72
+ "/alicanto deep-dive into transformer attention mechanisms",
73
+ "/arxiv find papers about retrieval augmented generation",
74
+ "/papers compare these two papers on reinforcement learning",
75
+ "/alicanto investigate multi-agent coordination strategies",
76
+ "/arxiv latest papers on code generation with LLMs",
77
+ "/papers summarize key findings from this conference proceedings",
78
+ "/alicanto explore the landscape of AI safety research",
79
+ "/arxiv search for graph neural network applications in biology",
80
+ # ── Slash commands: interactive modes ──
81
+ "/guac # open interactive Python REPL with data tools",
82
+ "/wander # creative exploration and brainstorming mode",
83
+ "/convene # multi-NPC discussion on a topic",
84
+ "/plonk # vision-based GUI automation",
85
+ "/git # interactive git TUI for staging, diffs, commits",
86
+ "/spool # isolated chat session with specific model",
87
+ "/pti # reasoning REPL with interruptions",
88
+ "/yap # voice-controlled agent loop",
89
+ "/vixynt # image generation and editing",
90
+ "/roll # video generation studio",
91
+ "/crond # system task manager (cron, daemons, processes)",
92
+ # ── Slash commands: data & knowledge ──
93
+ "/kg # browse the knowledge graph",
94
+ "/memories # manage stored memories",
95
+ "/nql # interactive database viewer",
96
+ "/sql SELECT * FROM messages LIMIT 10",
97
+ "/db_search find entries about authentication",
98
+ "/file_search *.py # search for Python files",
99
+ "/web_search latest news on AI regulation",
100
+ "/kg # explore facts, concepts, and relationships",
101
+ "/memories # review and approve pending memories",
102
+ "/nql # query and browse your conversation data",
103
+ # ── Slash commands: config & management ──
104
+ "/set model=claude-3-5-sonnet # change the active model",
105
+ "/set provider=openai # switch provider",
106
+ "/set mode=chat # change default mode",
107
+ "/models # list available models",
108
+ "/jinxs # list available jinxs",
109
+ "/team # manage your NPC team",
110
+ "/reattach # rejoin a previous conversation",
111
+ "/usage # check token usage and costs",
112
+ "/verbose # enable verbose output",
113
+ "/shh # quiet mode, less output",
114
+ # ── Browser & computer use ──
115
+ "/open_browser https://example.com",
116
+ "/browser_screenshot # capture the current browser page",
117
+ "/browser_action click the login button",
118
+ "/screenshot # take a screenshot of the desktop",
119
+ "/click 500 300 # click at screen coordinates",
120
+ "/type_text Hello World # type text into focused app",
121
+ "/key_press enter # press a key",
122
+ "/launch_app Terminal",
123
+ "/open_browser https://github.com # open a URL",
124
+ "/browser_action scroll down and find the pricing section",
125
+ # ── File operations ──
126
+ "/load_file data.csv # load a file into context",
127
+ "/edit_file app.py # edit a file with AI assistance",
128
+ "/compress output.tar.gz src/ # compress files",
129
+ "/write_file notes.md # write content to a file",
130
+ "read config.yaml and explain each setting",
131
+ "compare these two files and list the differences",
132
+ "refactor utils.py to use dataclasses instead of dicts",
133
+ "add type hints to all functions in this file",
134
+ "find and fix the bug in parser.py",
135
+ "add error handling to the database connection code",
136
+ # ── Building & deployment ──
137
+ "/build # interactive build TUI",
138
+ "/compile # compile NPC profiles",
139
+ "/serve # server dashboard TUI (start, stop, logs, endpoints)",
140
+ "/init # initialize a new NPC project",
141
+ "/setup # run setup wizard",
142
+ "/config # open configuration interface",
143
+ "/corca # MCP-powered development agent",
144
+ "/build # create deployment artifacts from your team",
145
+ "/compile sibiji # compile a specific NPC profile",
146
+ "/sync # synchronize team data",
147
+ # ── Conversation management ──
148
+ "/reattach # browse and rejoin previous conversations",
149
+ "/set conversation_id=abc123 # switch to a specific conversation",
150
+ "/clear # clear the screen",
151
+ "/exit # quit npcsh",
152
+ "/help arxiv # get detailed help on a specific command",
153
+ "/reattach # pick up where you left off in a prior session",
154
+ "/spool -m gpt-4o # isolated chat with a specific model",
155
+ "/convene discuss the pros and cons of microservices",
156
+ "/wander # let the AI explore ideas freely",
157
+ "/team # see and manage your NPC team members",
158
+ # ── Multi-step workflows ──
159
+ "analyze my codebase and suggest improvements",
160
+ "read all test files and identify gaps in coverage",
161
+ "review the git history and summarize what changed this week",
162
+ "find all API endpoints and document them",
163
+ "scan for security vulnerabilities in this project",
164
+ "profile this Python script and suggest optimizations",
165
+ "generate a changelog from the last 20 commits",
166
+ "create a project README based on the codebase",
167
+ "audit package.json for known CVEs",
168
+ "explain the architecture of this project to a new developer",
169
+ # ── Fun & creative ──
170
+ "write a haiku about programming",
171
+ "tell me a programming joke",
172
+ "explain recursion like I'm five",
173
+ "write a commit message for: fixed the thing that was broken",
174
+ "roast my code (paste code)",
175
+ "explain this error message: (paste error)",
176
+ "what's the most Pythonic way to flatten a nested list?",
177
+ "write ASCII art of a robot",
178
+ "create a fun loading message for a CLI tool",
179
+ "design a color scheme for a terminal app",
180
+ ]
181
+
182
+ topic = context.get('topic')
183
+
184
+ if not topic:
185
+ output_lines = ["# npcsh - Available Commands\n\n"]
186
+
187
+ output_lines.append("## Quick Start\n\n")
188
+ output_lines.append("- Type naturally to talk to your NPC\n")
189
+ output_lines.append("- Use `/command` for slash commands\n")
190
+ output_lines.append("- Use `@npc_name` to delegate to a specific NPC\n")
191
+ output_lines.append("- Use `|` to pipe output between stages\n")
192
+ output_lines.append("- Use `/reattach` to rejoin a previous conversation\n")
193
+ output_lines.append("- Press **Tab** to autocomplete commands and NPC names\n\n")
194
+
195
+ all_jinxs = {}
196
+ if hasattr(npc, 'team') and npc.team and hasattr(npc.team, 'jinxs_dict'):
197
+ all_jinxs.update(npc.team.jinxs_dict)
198
+ if hasattr(npc, 'jinxs_dict') and npc.jinxs_dict:
199
+ all_jinxs.update(npc.jinxs_dict)
200
+
201
+ for cmd in sorted(all_jinxs.keys()):
202
+ jinx_obj = all_jinxs[cmd]
203
+ desc = getattr(jinx_obj, 'description', 'No description')
204
+ output_lines.append(f"/{cmd} - {desc}\n\n")
205
+
206
+ arg_help_map = get_argument_help()
207
+ if arg_help_map:
208
+ output_lines.append("## Common Command-Line Flags\n\n")
209
+ output_lines.append("The shortest unambiguous prefix works.\n")
210
+
211
+ for arg in sorted(CANONICAL_ARGS):
212
+ aliases = arg_help_map.get(arg, [])
213
+ alias_str = f"(-{min(aliases, key=len)})" if aliases else ""
214
+ output_lines.append(f"--{arg:<20} {alias_str}\n")
215
+
216
+ output_lines.append("\n## Things to Try\n\n")
217
+ samples = random.sample(USAGE_EXAMPLES, min(3, len(USAGE_EXAMPLES)))
218
+ for i, example in enumerate(samples, 1):
219
+ output_lines.append(f"{i}. `{example}`\n")
220
+ output_lines.append(f"\n*Showing 3 of {len(USAGE_EXAMPLES)} examples — run `/help` again to see more.*\n")
221
+
222
+ output = "".join(output_lines)
223
+ else:
224
+ jinx_obj = None
225
+ if hasattr(npc, 'team') and npc.team and hasattr(npc.team, 'jinxs_dict'):
226
+ jinx_obj = npc.team.jinxs_dict.get(topic)
227
+ if not jinx_obj and hasattr(npc, 'jinxs_dict'):
228
+ jinx_obj = npc.jinxs_dict.get(topic)
229
+
230
+ if jinx_obj:
231
+ output = f"## Help for Jinx: `/{topic}`\n\n"
232
+ output += f"- **Description**: {jinx_obj.description}\n"
233
+ if hasattr(jinx_obj, 'inputs') and jinx_obj.inputs:
234
+ output += f"- **Inputs**: {json.dumps(jinx_obj.inputs, indent=2)}\n"
235
+ else:
236
+ output = f"No help topic found for `{topic}`."