stcode 0.0.1a1__tar.gz → 0.0.1a2__tar.gz

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 (206) hide show
  1. {stcode-0.0.1a1 → stcode-0.0.1a2}/PKG-INFO +1 -1
  2. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/configuration.md +4 -4
  3. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/daemon.md +14 -6
  4. {stcode-0.0.1a1 → stcode-0.0.1a2}/pyproject.toml +1 -1
  5. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/main.py +3 -1
  6. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/services/client.py +7 -1
  7. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/configs.py +5 -1
  8. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/server.py +4 -0
  9. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode.example.toml +4 -4
  10. stcode-0.0.1a2/tests/integration/transport_test.py +96 -0
  11. {stcode-0.0.1a1 → stcode-0.0.1a2}/uv.lock +1 -1
  12. {stcode-0.0.1a1 → stcode-0.0.1a2}/.dockerignore +0 -0
  13. {stcode-0.0.1a1 → stcode-0.0.1a2}/.gitignore +0 -0
  14. {stcode-0.0.1a1 → stcode-0.0.1a2}/CLAUDE.md +0 -0
  15. {stcode-0.0.1a1 → stcode-0.0.1a2}/Dockerfile +0 -0
  16. {stcode-0.0.1a1 → stcode-0.0.1a2}/LICENSE +0 -0
  17. {stcode-0.0.1a1 → stcode-0.0.1a2}/README.md +0 -0
  18. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/agent-loop.md +0 -0
  19. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/cli.md +0 -0
  20. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/harness.md +0 -0
  21. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/index.md +0 -0
  22. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/mcp.md +0 -0
  23. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/providers.md +0 -0
  24. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/session.md +0 -0
  25. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/supervisor.md +0 -0
  26. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/team.md +0 -0
  27. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/architecture/tracing.md +0 -0
  28. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/contributing/releasing.md +0 -0
  29. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/contributing/testing.md +0 -0
  30. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/contributing/workflow.md +0 -0
  31. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0001-tool-search.md +0 -0
  32. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0002-file-and-image-input.md +0 -0
  33. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0003-what-the-tui-owns.md +0 -0
  34. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0004-what-a-remote-client-may-change.md +0 -0
  35. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0005-an-agent-is-a-config-file.md +0 -0
  36. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0006-cli-and-core-are-separate-programs.md +0 -0
  37. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/0007-cli-layers.md +0 -0
  38. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/decisions/index.md +0 -0
  39. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/getting-started/configuration.md +0 -0
  40. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/getting-started/installation.md +0 -0
  41. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/getting-started/quickstart.md +0 -0
  42. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/approval-modes.md +0 -0
  43. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/mcp.md +0 -0
  44. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/repl.md +0 -0
  45. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/sessions.md +0 -0
  46. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/shapes.md +0 -0
  47. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/skills.md +0 -0
  48. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/tools.md +0 -0
  49. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/tracing.md +0 -0
  50. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/guide/tui.md +0 -0
  51. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/index.md +0 -0
  52. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/sdk/custom-tools.md +0 -0
  53. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/sdk/daemon-protocol.md +0 -0
  54. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/sdk/embedding.md +0 -0
  55. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/sdk/streaming.md +0 -0
  56. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/teams/roles.md +0 -0
  57. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/teams/setup.md +0 -0
  58. {stcode-0.0.1a1 → stcode-0.0.1a2}/docs/teams/workflow.md +0 -0
  59. {stcode-0.0.1a1 → stcode-0.0.1a2}/examples/agents/ba.toml +0 -0
  60. {stcode-0.0.1a1 → stcode-0.0.1a2}/examples/agents/backend-dev.toml +0 -0
  61. {stcode-0.0.1a1 → stcode-0.0.1a2}/examples/agents/devops.toml +0 -0
  62. {stcode-0.0.1a1 → stcode-0.0.1a2}/examples/agents/frontend-dev.toml +0 -0
  63. {stcode-0.0.1a1 → stcode-0.0.1a2}/mkdocs.yml +0 -0
  64. {stcode-0.0.1a1 → stcode-0.0.1a2}/pytest.ini +0 -0
  65. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/__init__.py +0 -0
  66. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/__init__.py +0 -0
  67. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/bootstrap.py +0 -0
  68. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/labels.py +0 -0
  69. {stcode-0.0.1a1/stcode/cli/ui/screens/chat → stcode-0.0.1a2/stcode/cli/logic}/__init__.py +0 -0
  70. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/commands.py +0 -0
  71. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/completion.py +0 -0
  72. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/connection.py +0 -0
  73. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/requests.py +0 -0
  74. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/sessions.py +0 -0
  75. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/settings.py +0 -0
  76. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/state.py +0 -0
  77. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/logic/workspace.py +0 -0
  78. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/models.py +0 -0
  79. {stcode-0.0.1a1/stcode/cli/ui/screens → stcode-0.0.1a2/stcode/cli/services}/__init__.py +0 -0
  80. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/services/launcher.py +0 -0
  81. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/services/paths.py +0 -0
  82. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/services/preferences.py +0 -0
  83. {stcode-0.0.1a1/stcode/cli/ui/components → stcode-0.0.1a2/stcode/cli/ui}/__init__.py +0 -0
  84. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/app.py +0 -0
  85. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/app.tcss +0 -0
  86. {stcode-0.0.1a1/stcode/cli/ui → stcode-0.0.1a2/stcode/cli/ui/components}/__init__.py +0 -0
  87. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/banner.py +0 -0
  88. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/cards.py +0 -0
  89. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/prompt.py +0 -0
  90. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/status.py +0 -0
  91. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/transcript/__init__.py +0 -0
  92. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/transcript/entries.py +0 -0
  93. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/transcript/formatting.py +0 -0
  94. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/components/transcript/view.py +0 -0
  95. {stcode-0.0.1a1/stcode/cli/services → stcode-0.0.1a2/stcode/cli/ui/screens}/__init__.py +0 -0
  96. {stcode-0.0.1a1/stcode/cli/logic → stcode-0.0.1a2/stcode/cli/ui/screens/chat}/__init__.py +0 -0
  97. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/chat/chat.tcss +0 -0
  98. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/chat/presenter.py +0 -0
  99. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/chat/screen.py +0 -0
  100. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/connect.py +0 -0
  101. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/connect.tcss +0 -0
  102. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/dialog.tcss +0 -0
  103. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/sessions.py +0 -0
  104. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/settings.py +0 -0
  105. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/settings.tcss +0 -0
  106. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/screens/trust.py +0 -0
  107. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/cli/ui/theme.py +0 -0
  108. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/__main__.py +0 -0
  109. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/agent/__init__.py +0 -0
  110. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/agent/agent.py +0 -0
  111. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/agent/events.py +0 -0
  112. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/agent/supervisor.py +0 -0
  113. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/agent/task.py +0 -0
  114. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/__init__.py +0 -0
  115. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/compat.py +0 -0
  116. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/ids.py +0 -0
  117. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/tools.py +0 -0
  118. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/trace.py +0 -0
  119. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/common/truncate.py +0 -0
  120. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/__init__.py +0 -0
  121. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/autonomy.py +0 -0
  122. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/main.py +0 -0
  123. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/protocol.py +0 -0
  124. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/runner.py +0 -0
  125. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/daemon/workspace.py +0 -0
  126. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/__init__.py +0 -0
  127. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/approvals.py +0 -0
  128. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/context.py +0 -0
  129. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/errors.py +0 -0
  130. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/harness.py +0 -0
  131. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/mcp.py +0 -0
  132. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/outputs.py +0 -0
  133. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/prompts/__init__.py +0 -0
  134. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/prompts/execute.py +0 -0
  135. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/prompts/plan.py +0 -0
  136. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/prompts/sections.py +0 -0
  137. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/skills/__init__.py +0 -0
  138. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/skills/loader.py +0 -0
  139. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/__init__.py +0 -0
  140. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/base.py +0 -0
  141. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/files.py +0 -0
  142. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/interact.py +0 -0
  143. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/registry.py +0 -0
  144. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/repl.py +0 -0
  145. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/schema.py +0 -0
  146. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/search.py +0 -0
  147. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/shell.py +0 -0
  148. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/skill.py +0 -0
  149. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/todo.py +0 -0
  150. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/harness/tools/web.py +0 -0
  151. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/__init__.py +0 -0
  152. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/anthropic_claude.py +0 -0
  153. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/base.py +0 -0
  154. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/gateway.py +0 -0
  155. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/google_gemini.py +0 -0
  156. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/openai_gpt.py +0 -0
  157. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/registry.py +0 -0
  158. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/providers/types.py +0 -0
  159. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/repl/__init__.py +0 -0
  160. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/repl/_worker.py +0 -0
  161. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/repl/client.py +0 -0
  162. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/session/__init__.py +0 -0
  163. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/session/session.py +0 -0
  164. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/team/__init__.py +0 -0
  165. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/team/mailbox.py +0 -0
  166. {stcode-0.0.1a1 → stcode-0.0.1a2}/stcode/core/team/tools.py +0 -0
  167. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/architecture_test.py +0 -0
  168. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/labels_test.py +0 -0
  169. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/logic/completion_test.py +0 -0
  170. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/logic/connection_test.py +0 -0
  171. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/logic/sessions_test.py +0 -0
  172. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/logic/workflows_test.py +0 -0
  173. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/main_test.py +0 -0
  174. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/services/launcher_test.py +0 -0
  175. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/services/preferences_test.py +0 -0
  176. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/ui/components/prompt_test.py +0 -0
  177. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/ui/components/transcript_test.py +0 -0
  178. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/cli/ui/theme_test.py +0 -0
  179. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/conftest.py +0 -0
  180. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/agent_test.py +0 -0
  181. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/common_test.py +0 -0
  182. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/configs_test.py +0 -0
  183. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/daemon_main_test.py +0 -0
  184. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/daemon_test.py +0 -0
  185. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/harness_test.py +0 -0
  186. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/providers_test.py +0 -0
  187. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/repl_test.py +0 -0
  188. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/session_test.py +0 -0
  189. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/team_test.py +0 -0
  190. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/trace_test.py +0 -0
  191. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/core/workspace_discovery_test.py +0 -0
  192. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/driving.py +0 -0
  193. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fakes.py +0 -0
  194. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/.agents/skills/db-migrations/SKILL.md +0 -0
  195. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/.agents/skills/release-notes/SKILL.md +0 -0
  196. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/AGENTS.md +0 -0
  197. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/README.md +0 -0
  198. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/config.toml +0 -0
  199. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/mcp_server.py +0 -0
  200. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/src/app.py +0 -0
  201. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/fixtures/workspace/src/util.py +0 -0
  202. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/integration/conftest.py +0 -0
  203. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/integration/conversation_test.py +0 -0
  204. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/integration/trace_live_test.py +0 -0
  205. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/integration/tui_test.py +0 -0
  206. {stcode-0.0.1a1 → stcode-0.0.1a2}/tests/integration/workspace_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stcode
3
- Version: 0.0.1a1
3
+ Version: 0.0.1a2
4
4
  Summary: A coding agent that lives in a daemon, and a UI that is a client of it.
5
5
  Project-URL: Homepage, https://ming-doan.github.io/stcode/
6
6
  Project-URL: Documentation, https://ming-doan.github.io/stcode/docs/
@@ -127,14 +127,14 @@ project) and `keep`, the number of session files `prune` leaves behind.
127
127
 
128
128
  | Key | Default | |
129
129
  | --- | --- | --- |
130
- | `transport` | `"unix"` | `unix` on your machine, `tcp` in a container |
130
+ | `transport` | `"unix"` on Unix, `"tcp"` on Windows | `tcp` also works in a container |
131
131
  | `socket` | `~/.stcode/daemon.sock` | `unix` only |
132
132
  | `host` / `port` | `127.0.0.1` / `7717` | `tcp` only |
133
133
  | `max_clients` | *unset* | concurrent connections. **Unset = 1 in a container, unlimited on the host**; `0` is unlimited everywhere |
134
134
 
135
- Read by the daemon only. The UI connects to `~/.stcode/daemon.sock` unless given
136
- `--socket` or `--transport tcp --host --port`, and starts the daemon on that same
137
- address. → [daemon.md](daemon.md#one-client-in-a-container)
135
+ Read by the daemon only. The UI connects to `~/.stcode/daemon.sock` on Unix or
136
+ `127.0.0.1:7717` over TCP on Windows unless given address flags, and starts the daemon
137
+ on that same address. → [daemon.md](daemon.md#one-client-in-a-container)
138
138
 
139
139
  ### `[mcp]`
140
140
 
@@ -41,9 +41,10 @@ stcode --daemonless # the UI alone, attached to a daemon elsewhere
41
41
  ```
42
42
 
43
43
  No implementation switches between them. `--headless` replaces the `stcode` process
44
- with `stcode-daemon`. Plain `stcode` connects to `~/.stcode/daemon.sock` (or the address
45
- its flags name); if nothing answers, `cli/services/launcher.py` starts `stcode-daemon` on that
46
- address as a subprocess, logging to `~/.stcode/daemon.log`, and stops it again when the
44
+ with `stcode-daemon`. Plain `stcode` connects to `~/.stcode/daemon.sock` on Unix or
45
+ `127.0.0.1:7717` over TCP on Windows (or the address its flags name); if nothing answers,
46
+ `cli/services/launcher.py` starts `stcode-daemon` on that address as a subprocess,
47
+ logging to `daemon.log` in the stcode home directory, and stops it again when the
47
48
  UI exits. A daemon it *found* is left running — quitting is a detach. `stcode --restart`
48
49
  sends `shutdown` to whatever is listening first, for a daemon that is wedged or running
49
50
  old code.
@@ -260,17 +261,24 @@ the container is the mitigation.
260
261
 
261
262
  ```toml
262
263
  [daemon]
263
- transport = "unix" # "tcp" inside a container
264
+ # transport = "unix" # default on Unix; "tcp" on Windows
264
265
  socket = "~/.stcode/daemon.sock"
265
266
  host = "127.0.0.1"
266
267
  port = 7717
267
268
  ```
268
269
 
269
- `unix` for solo — no port to collide with, and filesystem permissions are the access
270
- control (the socket is chmod 0600; anyone who can open it can drive an agent with your
270
+ `unix` for solo on Unix — no port to collide with, and filesystem permissions are the
271
+ access control (the socket is chmod 0600; anyone who can open it can drive an agent with your
271
272
  privileges). `tcp` for a container, which has no host filesystem to put a socket on. Same
272
273
  JSONL framing either way, so a WebSocket adapter later is an adapter, not a protocol.
273
274
 
275
+ Both the client and daemon default to loopback TCP when asyncio's Unix socket APIs
276
+ are unavailable, as on Windows. Explicitly requesting `unix` on such a platform
277
+ reports an unsupported transport with a hint to use `--transport tcp`.
278
+ On Windows, set provider keys in the daemon's config file or environment: TCP still
279
+ refuses API key updates and protocol shutdown, including `--restart` of a running
280
+ daemon. The launcher can stop a daemon it started when the UI exits.
281
+
274
282
  **Transport is configuration, not architecture.** The one thing that reads it is
275
283
  `Daemon.local_only`, which decides what only this machine's user may do — send a key,
276
284
  stop the daemon. Anything else that needs to know is in the wrong layer.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stcode"
3
- version = "0.0.1a1"
3
+ version = "0.0.1a2"
4
4
  description = "A coding agent that lives in a daemon, and a UI that is a client of it."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -178,7 +178,9 @@ def main(
178
178
  def _address(
179
179
  transport: str | None, socket: str | None, host: str | None, port: int | None
180
180
  ) -> Address:
181
- address = Address(transport=transport or "unix")
181
+ address = Address()
182
+ if transport:
183
+ address.transport = transport
182
184
  if socket:
183
185
  address.socket = Path(socket).expanduser()
184
186
  address.host = host or address.host
@@ -44,7 +44,9 @@ rather than hung on."""
44
44
  class Address:
45
45
  """Where a daemon listens."""
46
46
 
47
- transport: str = "unix"
47
+ transport: str = field(
48
+ default_factory=lambda: "unix" if hasattr(asyncio, "open_unix_connection") else "tcp"
49
+ )
48
50
  socket: Path = field(default_factory=lambda: stcode_home() / "daemon.sock")
49
51
  host: str = "127.0.0.1"
50
52
  port: int = 7717
@@ -91,6 +93,10 @@ class DaemonClient:
91
93
  """Open the transport. `OSError` when nothing is listening — the caller's cue to
92
94
  start a daemon or ask for another address, not an error to hide."""
93
95
  if address.transport == "unix":
96
+ if not hasattr(asyncio, "open_unix_connection"):
97
+ raise OSError(
98
+ "Unix sockets are unavailable on this platform; use --transport tcp."
99
+ )
94
100
  reader, writer = await asyncio.open_unix_connection(
95
101
  str(address.socket.expanduser()), limit=STREAM_LIMIT
96
102
  )
@@ -17,6 +17,7 @@ A leaf: imports nothing from `stcode`, so anything in `core/` may import it.
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
+ import asyncio
20
21
  import os
21
22
  import re
22
23
  from pathlib import Path
@@ -103,13 +104,16 @@ class DaemonConfig(BaseModel):
103
104
  """Where the daemon listens.
104
105
  Args:
105
106
  transport: `unix` — socket via `socket` path, `tcp` — socket via `host` and `port`.
107
+ Defaults to `tcp` when asyncio has no Unix socket support (Windows).
106
108
  socket: Path to the Unix socket file. Ignored if `transport` is `tcp`.
107
109
  host: Hostname to bind to. Ignored if `transport` is `unix`.
108
110
  port: Port to bind to. Ignored if `transport` is `unix`.
109
111
  max_clients: How many clients may be connected at once. 0 = unlimited. Unset =
110
112
  1 in a container, unlimited on the host.
111
113
  """
112
- transport: Literal["unix", "tcp"] = "unix"
114
+ transport: Literal["unix", "tcp"] = Field(
115
+ default_factory=lambda: "unix" if hasattr(asyncio, "start_unix_server") else "tcp"
116
+ )
113
117
  socket: Path = Field(default_factory=lambda: home_dir() / "daemon.sock")
114
118
  host: str = "127.0.0.1"
115
119
  port: int = 7717
@@ -155,6 +155,10 @@ class Daemon:
155
155
 
156
156
  settings = self.config.daemon
157
157
  if settings.transport == "unix":
158
+ if not hasattr(asyncio, "start_unix_server"):
159
+ raise OSError(
160
+ "Unix sockets are unavailable on this platform; use --transport tcp."
161
+ )
158
162
  path = socket_path(settings.socket)
159
163
  path.parent.mkdir(parents=True, exist_ok=True)
160
164
  _clear_stale_socket(path)
@@ -63,11 +63,11 @@ difficulty = "high"
63
63
  # dir = "./.stcode/sessions"
64
64
  # keep = 100
65
65
 
66
- # Where the daemon listens. `unix` on your own machine, `tcp` inside a container.
67
- # The UI does not read this: it connects to ~/.stcode/daemon.sock unless told otherwise
68
- # with --socket / --transport tcp --host --port, and starts the daemon on that address.
66
+ # Where the daemon listens. Default: `unix` on Unix, loopback `tcp` on Windows.
67
+ # Use `tcp` inside a container. The UI does not read this: it uses the same platform
68
+ # default unless given --transport / --socket / --host / --port flags.
69
69
  [daemon]
70
- transport = "unix"
70
+ # transport = "unix" # use "tcp" on Windows or inside a container
71
71
  # socket = "~/.stcode/daemon.sock"
72
72
  # host = "0.0.0.0" # when transport = "tcp"
73
73
  # port = 7717
@@ -0,0 +1,96 @@
1
+ """Platform transport defaults must agree without requiring Unix-only asyncio APIs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+ from driving import asynctest
10
+
11
+ from stcode.cli.main import _address
12
+ from stcode.cli.services.client import Address, DaemonClient
13
+ from stcode.core.configs import Config, load_config
14
+ from stcode.core.daemon import Daemon
15
+
16
+
17
+ @pytest.fixture
18
+ def without_unix_sockets(monkeypatch: pytest.MonkeyPatch) -> None:
19
+ """Match Windows' asyncio surface while still using real TCP sockets."""
20
+ monkeypatch.delattr(asyncio, "open_unix_connection", raising=False)
21
+ monkeypatch.delattr(asyncio, "start_unix_server", raising=False)
22
+
23
+
24
+ @pytest.mark.skipif(
25
+ not hasattr(asyncio, "open_unix_connection")
26
+ or not hasattr(asyncio, "start_unix_server"),
27
+ reason="Unix socket APIs are unavailable",
28
+ )
29
+ def test_unix_remains_the_default_where_supported() -> None:
30
+ assert Address().transport == "unix"
31
+ assert _address(None, None, None, None).transport == "unix"
32
+ assert Config().daemon.transport == "unix"
33
+ assert _address("tcp", None, "127.0.0.1", 9000).daemon_args() == [
34
+ "--transport", "tcp", "--host", "127.0.0.1", "--port", "9000",
35
+ ]
36
+
37
+
38
+ @asynctest
39
+ async def test_defaults_connect_over_tcp_without_unix_apis(
40
+ tmp_path: Path, without_unix_sockets: None,
41
+ ) -> None:
42
+ address = _address(None, None, None, None)
43
+ assert address.transport == Address().transport == "tcp"
44
+ assert str(address) == "127.0.0.1:7717"
45
+ assert address.daemon_args() == [
46
+ "--transport", "tcp", "--host", "127.0.0.1", "--port", "7717",
47
+ ]
48
+
49
+ path = tmp_path / "config.toml"
50
+ config = load_config(
51
+ path,
52
+ create_if_missing=True,
53
+ overrides={"session.dir": str(tmp_path / "sessions"), "daemon.port": 0},
54
+ )
55
+ assert config.daemon.transport == "tcp"
56
+ assert load_config(path).daemon.transport == "tcp"
57
+ assert config.daemon.host == address.host
58
+
59
+ async with Daemon(config) as daemon:
60
+ assert daemon._server is not None
61
+ address.port = daemon._server.sockets[0].getsockname()[1]
62
+ async with await DaemonClient.connect(address) as client:
63
+ frame = await client.get_config()
64
+ assert frame["path"] == str(path)
65
+ assert frame["keys_editable"] is False
66
+ assert await client.sessions() == []
67
+
68
+
69
+ @asynctest
70
+ async def test_explicit_unix_client_reports_how_to_use_tcp(
71
+ tmp_path: Path, without_unix_sockets: None,
72
+ ) -> None:
73
+ address = _address("unix", str(tmp_path / "d.sock"), None, None)
74
+ assert address.transport == "unix"
75
+ with pytest.raises(OSError, match="Unix sockets.*--transport tcp"):
76
+ await DaemonClient.connect(address)
77
+
78
+
79
+ @asynctest
80
+ async def test_explicit_unix_daemon_reports_how_to_use_tcp(
81
+ tmp_path: Path, without_unix_sockets: None,
82
+ ) -> None:
83
+ config = load_config(
84
+ tmp_path / "config.toml",
85
+ create_if_missing=True,
86
+ overrides={
87
+ "daemon.transport": "unix",
88
+ "daemon.socket": str(tmp_path / "d.sock"),
89
+ "session.dir": str(tmp_path / "sessions"),
90
+ },
91
+ )
92
+ assert config.daemon.transport == "unix"
93
+ with pytest.raises(OSError, match="Unix sockets.*--transport tcp"):
94
+ async with Daemon(config):
95
+ pass
96
+ assert not config.daemon.socket.exists()
@@ -3289,7 +3289,7 @@ wheels = [
3289
3289
 
3290
3290
  [[package]]
3291
3291
  name = "stcode"
3292
- version = "0.0.1a1"
3292
+ version = "0.0.1a2"
3293
3293
  source = { editable = "." }
3294
3294
  dependencies = [
3295
3295
  { name = "anthropic" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes