tamfis-code 0.2.3__tar.gz → 0.6.2__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 (148) hide show
  1. tamfis_code-0.6.2/MANIFEST.in +3 -0
  2. tamfis_code-0.6.2/PKG-INFO +252 -0
  3. tamfis_code-0.6.2/README.md +229 -0
  4. tamfis_code-0.6.2/USAGE_INSTALL_RELEASE.md +67 -0
  5. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/pyproject.toml +23 -6
  6. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/__init__.py +3 -7
  7. tamfis_code-0.6.2/tamfis_code/agent_definitions.py +104 -0
  8. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/agents.py +91 -11
  9. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/cli.py +178 -146
  10. tamfis_code-0.6.2/tamfis_code/clipboard.py +41 -0
  11. tamfis_code-0.6.2/tamfis_code/completion.py +118 -0
  12. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/config.py +76 -3
  13. tamfis_code-0.6.2/tamfis_code/custom_commands.py +105 -0
  14. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/doctor.py +108 -3
  15. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/enforcer.py +148 -143
  16. tamfis_code-0.6.2/tamfis_code/evidence.py +106 -0
  17. tamfis_code-0.6.2/tamfis_code/hooks.py +182 -0
  18. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/indexer.py +89 -24
  19. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/interactive.py +588 -99
  20. tamfis_code-0.6.2/tamfis_code/live_input.py +196 -0
  21. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/local_chat.py +12 -8
  22. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/local_tools.py +13 -4
  23. tamfis_code-0.6.2/tamfis_code/mcp.py +1274 -0
  24. tamfis_code-0.6.2/tamfis_code/mcp_stdio_server.py +75 -0
  25. tamfis_code-0.6.2/tamfis_code/model_registry.py +99 -0
  26. tamfis_code-0.6.2/tamfis_code/openhands/__init__.py +17 -0
  27. tamfis_code-0.6.2/tamfis_code/openhands/agent.py +117 -0
  28. tamfis_code-0.6.2/tamfis_code/openhands/agent_server.py +88 -0
  29. tamfis_code-0.6.2/tamfis_code/openhands/automation.py +29 -0
  30. tamfis_code-0.6.2/tamfis_code/openhands/compat.py +10 -0
  31. tamfis_code-0.6.2/tamfis_code/openhands/conversation.py +71 -0
  32. tamfis_code-0.6.2/tamfis_code/openhands/delegation.py +22 -0
  33. tamfis_code-0.6.2/tamfis_code/openhands/events.py +151 -0
  34. tamfis_code-0.6.2/tamfis_code/openhands/leases.py +30 -0
  35. tamfis_code-0.6.2/tamfis_code/openhands/security.py +42 -0
  36. tamfis_code-0.6.2/tamfis_code/openhands/skills.py +55 -0
  37. tamfis_code-0.6.2/tamfis_code/openhands/tools.py +128 -0
  38. tamfis_code-0.6.2/tamfis_code/openhands/workspace.py +190 -0
  39. tamfis_code-0.6.2/tamfis_code/orchestrator/__init__.py +9 -0
  40. tamfis_code-0.6.2/tamfis_code/orchestrator/context.py +78 -0
  41. tamfis_code-0.6.2/tamfis_code/orchestrator/engine.py +198 -0
  42. tamfis_code-0.6.2/tamfis_code/orchestrator/planner.py +195 -0
  43. tamfis_code-0.6.2/tamfis_code/orchestrator/protocols.py +101 -0
  44. tamfis_code-0.6.2/tamfis_code/orchestrator/validator.py +97 -0
  45. tamfis_code-0.6.2/tamfis_code/project.py +351 -0
  46. tamfis_code-0.6.2/tamfis_code/provider_protocols.py +176 -0
  47. tamfis_code-0.6.2/tamfis_code/providers.py +972 -0
  48. tamfis_code-0.6.2/tamfis_code/pty.py +118 -0
  49. tamfis_code-0.6.2/tamfis_code/render.py +996 -0
  50. tamfis_code-0.6.2/tamfis_code/routing.py +165 -0
  51. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/runner.py +239 -34
  52. tamfis_code-0.6.2/tamfis_code/runner_local.py +4319 -0
  53. tamfis_code-0.6.2/tamfis_code/safety.py +339 -0
  54. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/state.py +116 -0
  55. tamfis_code-0.6.2/tamfis_code/swarm.py +197 -0
  56. tamfis_code-0.6.2/tamfis_code/tool_policy.py +41 -0
  57. tamfis_code-0.6.2/tamfis_code/workspace.py +954 -0
  58. tamfis_code-0.6.2/tamfis_code.egg-info/PKG-INFO +252 -0
  59. tamfis_code-0.6.2/tamfis_code.egg-info/SOURCES.txt +125 -0
  60. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code.egg-info/entry_points.txt +1 -0
  61. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code.egg-info/requires.txt +4 -0
  62. tamfis_code-0.6.2/tests/test_agent_definitions.py +76 -0
  63. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_agents_delegation.py +3 -3
  64. tamfis_code-0.6.2/tests/test_build_installation.py +108 -0
  65. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_cli_commands.py +225 -5
  66. tamfis_code-0.6.2/tests/test_clipboard.py +50 -0
  67. tamfis_code-0.6.2/tests/test_context_rollover.py +327 -0
  68. tamfis_code-0.6.2/tests/test_custom_commands.py +90 -0
  69. tamfis_code-0.6.2/tests/test_cwd_validation.py +179 -0
  70. tamfis_code-0.6.2/tests/test_doctor_session_diagnostics.py +210 -0
  71. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_enforcer.py +69 -40
  72. tamfis_code-0.6.2/tests/test_fake_tool_detection.py +171 -0
  73. tamfis_code-0.6.2/tests/test_find_references.py +122 -0
  74. tamfis_code-0.6.2/tests/test_hooks.py +144 -0
  75. tamfis_code-0.6.2/tests/test_indexer.py +185 -0
  76. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_integration_new.py +0 -13
  77. tamfis_code-0.6.2/tests/test_interactive_standalone.py +538 -0
  78. tamfis_code-0.6.2/tests/test_live_input.py +224 -0
  79. tamfis_code-0.6.2/tests/test_local_pty.py +36 -0
  80. tamfis_code-0.6.2/tests/test_mcp.py +611 -0
  81. tamfis_code-0.6.2/tests/test_mcp_search_bounds.py +131 -0
  82. tamfis_code-0.6.2/tests/test_mcp_stdio_server.py +113 -0
  83. tamfis_code-0.6.2/tests/test_openhands_runtime.py +113 -0
  84. tamfis_code-0.6.2/tests/test_openrouter_cost_routing.py +95 -0
  85. tamfis_code-0.6.2/tests/test_orchestrator.py +315 -0
  86. tamfis_code-0.6.2/tests/test_plan_mode_gate.py +115 -0
  87. tamfis_code-0.6.2/tests/test_provider_protocols.py +94 -0
  88. tamfis_code-0.6.2/tests/test_reasoning_effort_capability.py +58 -0
  89. tamfis_code-0.6.2/tests/test_reasoning_plan.py +310 -0
  90. tamfis_code-0.6.2/tests/test_routing.py +215 -0
  91. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_runner_helpers.py +2 -2
  92. tamfis_code-0.6.2/tests/test_runner_local.py +1992 -0
  93. tamfis_code-0.6.2/tests/test_safety.py +364 -0
  94. tamfis_code-0.6.2/tests/test_safety_manifest.py +110 -0
  95. tamfis_code-0.6.2/tests/test_swarm.py +431 -0
  96. tamfis_code-0.6.2/tests/test_tamfis_code_approval.py +234 -0
  97. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_config.py +92 -0
  98. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_intent.py +29 -0
  99. tamfis_code-0.6.2/tests/test_tamfis_code_render.py +536 -0
  100. tamfis_code-0.6.2/tests/test_tamfis_code_workspace.py +487 -0
  101. tamfis_code-0.6.2/tests/test_version_consistency.py +40 -0
  102. tamfis_code-0.6.2/tests/test_workspace_scope.py +190 -0
  103. tamfis_code-0.2.3/PKG-INFO +0 -78
  104. tamfis_code-0.2.3/README.md +0 -59
  105. tamfis_code-0.2.3/tamfis_code/completion.py +0 -137
  106. tamfis_code-0.2.3/tamfis_code/mcp.py +0 -538
  107. tamfis_code-0.2.3/tamfis_code/providers.py +0 -423
  108. tamfis_code-0.2.3/tamfis_code/render.py +0 -575
  109. tamfis_code-0.2.3/tamfis_code/runner_local.py +0 -364
  110. tamfis_code-0.2.3/tamfis_code/safety.py +0 -164
  111. tamfis_code-0.2.3/tamfis_code/workspace.py +0 -329
  112. tamfis_code-0.2.3/tamfis_code.egg-info/PKG-INFO +0 -78
  113. tamfis_code-0.2.3/tamfis_code.egg-info/SOURCES.txt +0 -66
  114. tamfis_code-0.2.3/tests/test_doctor_session_diagnostics.py +0 -111
  115. tamfis_code-0.2.3/tests/test_indexer.py +0 -109
  116. tamfis_code-0.2.3/tests/test_interactive_standalone.py +0 -173
  117. tamfis_code-0.2.3/tests/test_local_mode.py +0 -144
  118. tamfis_code-0.2.3/tests/test_mcp.py +0 -208
  119. tamfis_code-0.2.3/tests/test_runner_local.py +0 -237
  120. tamfis_code-0.2.3/tests/test_safety.py +0 -158
  121. tamfis_code-0.2.3/tests/test_tamfis_code_approval.py +0 -106
  122. tamfis_code-0.2.3/tests/test_tamfis_code_render.py +0 -181
  123. tamfis_code-0.2.3/tests/test_tamfis_code_workspace.py +0 -260
  124. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/setup.cfg +0 -0
  125. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/__main__.py +0 -0
  126. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/api_client.py +0 -0
  127. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/instructions.py +0 -0
  128. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/metrics.py +0 -0
  129. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/references.py +0 -0
  130. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/screenshot.py +0 -0
  131. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/sessions.py +0 -0
  132. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code/tasks.py +0 -0
  133. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code.egg-info/dependency_links.txt +0 -0
  134. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tamfis_code.egg-info/top_level.txt +0 -0
  135. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_agents.py +0 -0
  136. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_completion.py +0 -0
  137. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_instructions.py +0 -0
  138. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_mcp_standalone_degradation.py +0 -0
  139. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_metrics.py +0 -0
  140. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_plan_steps_and_attempts.py +0 -0
  141. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_references.py +0 -0
  142. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_render_task_diagnostics.py +0 -0
  143. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_sessions.py +0 -0
  144. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_api_client.py +0 -0
  145. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_approval_flow.py +0 -0
  146. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_repl_exit.py +0 -0
  147. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_tamfis_code_tasks.py +0 -0
  148. {tamfis_code-0.2.3 → tamfis_code-0.6.2}/tests/test_workspace_discovery_gaps.py +0 -0
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ include USAGE_INSTALL_RELEASE.md
3
+ include pyproject.toml
@@ -0,0 +1,252 @@
1
+ Metadata-Version: 2.4
2
+ Name: tamfis-code
3
+ Version: 0.6.2
4
+ Summary: TamfisGPT Code -- portable subscription-backed terminal coding agent with local tools, PTY, plans, queues, and approvals
5
+ Project-URL: Homepage, https://github.com/tamfitronics/tamfis-code
6
+ Project-URL: Repository, https://github.com/tamfitronics/tamfis-code
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: click>=8.1
10
+ Requires-Dist: httpx>=0.27
11
+ Requires-Dist: rich>=13.0
12
+ Requires-Dist: prompt_toolkit>=3.0
13
+ Requires-Dist: openai>=1.30
14
+ Requires-Dist: mcp>=1.2
15
+ Requires-Dist: fastapi>=0.115
16
+ Requires-Dist: uvicorn>=0.34
17
+ Requires-Dist: websockets>=13
18
+ Provides-Extra: dev
19
+ Requires-Dist: build>=1.0; extra == "dev"
20
+ Requires-Dist: twine>=5.0; extra == "dev"
21
+ Requires-Dist: pytest>=8.0; extra == "dev"
22
+ Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
23
+
24
+ # tamfis-code
25
+
26
+ A portable standalone terminal coding agent. It is designed to be installed
27
+ on any developer workstation, VPS, or server and run its agent loop, file
28
+ tools, shell, PTY/TTY sessions, approvals, plans, and state locally. It must
29
+ not depend on the machine that built it or on a co-located TamfisGPT server.
30
+
31
+ The product subscription boundary is separate from the runtime boundary:
32
+ normal users authenticate the CLI with their TamfisGPT iOS subscription/API
33
+ entitlement, and the CLI makes outbound API calls from the machine where it
34
+ is installed. Admin subscriptions are an account/billing policy, not a
35
+ requirement for installing or running the CLI.
36
+
37
+ The current standalone runtime can also call NVIDIA NIM, OpenRouter, or
38
+ Hugging Face directly. Every provider uses the same local-tool contract:
39
+ model traffic may be remote, but workspace files, commands, PTYs, approvals,
40
+ and mutation evidence remain local unless the user explicitly selects
41
+ `--remote`.
42
+
43
+ `--remote` (or a persistent `default_backend = "remote"` config setting)
44
+ switches to the original architecture: a thin client to the TamfisGPT
45
+ Remote Workspace backend, for TamfisGPT tenants using their hosted account
46
+ the same way Codex CLI uses a ChatGPT/OpenAI account, kimi-code uses a Kimi
47
+ account, or Claude Code uses a Claude account.
48
+
49
+ ## Install
50
+
51
+ ```
52
+ pipx install tamfis-code
53
+ ```
54
+
55
+ See [USAGE_INSTALL_RELEASE.md](./USAGE_INSTALL_RELEASE.md) for installing
56
+ from source, using a TamfisGPT tenancy, and the release process.
57
+
58
+ ## Quick start
59
+
60
+ ```
61
+ export NVIDIA_API_KEY=... # or set OPENROUTER_API_KEY / HF_TOKEN
62
+ tamfis-code doctor # check provider connectivity
63
+ tamfis-code ask "explain what this repo does"
64
+ tamfis-code agent "add a health-check endpoint" # full read/write/execute loop
65
+ tamfis-code # interactive REPL
66
+ ```
67
+
68
+ ### TamfisGPT subscription access
69
+
70
+ Create a developer API key from the TamfisGPT account connected to the iOS
71
+ subscription, then configure the machine where Tamfis-Code is installed:
72
+
73
+ ```bash
74
+ export TAMFIS_API_KEY='tamfis_sk_live_...'
75
+ # Optional for a private gateway or regional deployment:
76
+ export TAMFIS_API_BASE='https://gpt.tamfitronics.com/api/v1/openai'
77
+ tamfis-code doctor
78
+ tamfis-code agent "inspect this repository and fix the failing tests"
79
+ ```
80
+
81
+ The key is checked against the account's active subscription and API scopes
82
+ on every request. The CLI remains portable: the model request goes to the
83
+ TamfisGPT API, while repository files, shell commands, PTY sessions,
84
+ approvals, and mutation evidence stay on the local machine. Admin access is
85
+ not required for ordinary subscription users.
86
+
87
+ ## Providers
88
+
89
+ | Provider | Env var | Notes |
90
+ |---|---|---|
91
+ | NVIDIA NIM | `NVIDIA_API_KEY` | |
92
+ | OpenRouter | `OPENROUTER_API_KEY` | |
93
+ | Hugging Face | `HF_TOKEN` | |
94
+ | TamfisGPT subscription API | `TAMFIS_API_KEY` | Key issued for an active TamfisGPT plan |
95
+
96
+ Select one explicitly with `--provider tamfis|hf|nvidia|openrouter`, or leave it
97
+ as `auto` (default). Auto routes through eligible providers in
98
+ capability-ranked order. The selected provider/model is printed at the
99
+ start of every turn.
100
+
101
+ Interrupted provider streams remain attached to the same task: clean partial
102
+ text is checkpointed to `.memory`, reconnects use visible 5/15/30-second
103
+ backoff, and continuation output is de-duplicated. If all configured routes
104
+ remain unavailable, the CLI reports an actionable error and retains the exact
105
+ checkpoint for `continue` instead of pretending the request completed.
106
+
107
+ ## Local runtime storage
108
+
109
+ Tamfis Code is not tied to the machine that built or packaged it. Each
110
+ installed user gets private runtime storage in that operating system's
111
+ standard per-user location:
112
+
113
+ | Platform | Default |
114
+ |---|---|
115
+ | Linux/Unix | `$XDG_CONFIG_HOME/tamfis-code`, or `~/.config/tamfis-code` |
116
+ | macOS | `~/Library/Application Support/tamfis-code` |
117
+ | Windows | `%APPDATA%\tamfis-code` |
118
+
119
+ Set `TAMFIS_CODE_CONFIG_HOME` to use an explicit portable/container path.
120
+ Session memory is stored below that resolved directory in
121
+ `.memory/session-<id>.json`. No runtime state is written into the source
122
+ checkout or installed package directory, and no VPS/home path is compiled
123
+ into the wheel.
124
+
125
+ ## Hooks
126
+
127
+ Real, user-configurable pre/post-tool-use hooks (no code changes required) —
128
+ arbitrary shell commands that observe, or for `pre_tool_use`, veto, a real
129
+ local tool call in the standalone agent loop. Configure them in
130
+ `hooks.toml`: `~/.config/tamfis-code/hooks.toml` (or the platform-native
131
+ location above) for every session, and/or `<project>/.tamfis/hooks.toml`
132
+ for one project (both apply — project hooks run after user hooks):
133
+
134
+ ```toml
135
+ [[pre_tool_use]]
136
+ matcher = "write_file|edit_file" # regex against the tool name; omit/empty matches every tool
137
+ command = "python3 my_guard.py"
138
+
139
+ [[post_tool_use]]
140
+ matcher = "execute_command"
141
+ command = "notify-send 'tamfis-code ran a command'"
142
+ ```
143
+
144
+ Each hook receives a JSON event on stdin: `{"event", "tool_name",
145
+ "tool_input", "tool_output" (post_tool_use only), "session_id",
146
+ "workspace_root"}`. For `pre_tool_use`, exiting with code `2` blocks the
147
+ call — the tool is never executed, and the hook's stderr (or stdout, if
148
+ stderr is empty) becomes the denial reason the model sees. Any other exit
149
+ code doesn't block. For `post_tool_use`, the tool has already run, so no
150
+ exit code can undo it — stderr/stdout always just surfaces as additional
151
+ context appended for the model. Hooks are read fresh at the start of every
152
+ turn and time out after 30s; a hook that fails to start, errors, or times
153
+ out degrades to a visible diagnostic instead of failing the turn.
154
+
155
+ ## Custom commands
156
+
157
+ Define your own `/command`, no code changes required — drop a markdown
158
+ file into a commands directory and it's available in the interactive REPL
159
+ on the next turn. `~/.config/tamfis-code/commands/<name>.md` (or the
160
+ platform-native location above) applies to every session;
161
+ `<project>/.tamfis/commands/<name>.md` applies to one project (a project
162
+ command with the same name replaces the user one). The filename becomes
163
+ the command name, an optional frontmatter block sets its description, and
164
+ the rest of the file is the prompt template sent as the objective:
165
+
166
+ ```markdown
167
+ ---
168
+ description: Review a diff for security issues
169
+ ---
170
+ Review the following diff for security issues, focusing on injection,
171
+ auth, and secrets handling: $ARGUMENTS
172
+ ```
173
+
174
+ `$ARGUMENTS` is replaced with whatever you type after the command name
175
+ (`/secreview app.py` → the template with `$ARGUMENTS` replaced by
176
+ `app.py`); a template with no `$ARGUMENTS` placeholder still gets any
177
+ typed text appended on a new line. Run `/commands` in the REPL to list
178
+ what's currently loaded. A custom command can never shadow a built-in one
179
+ (`/plan`, `/agent`, etc. always win on a name collision).
180
+
181
+ ## Declarative subagent types
182
+
183
+ Give a delegated sub-task its own specialised system prompt (and,
184
+ optionally, its own model/provider) instead of every `/delegate`/`/swarm`
185
+ sub-objective sharing the same generic coding agent — Claude Code's
186
+ `.claude/agents/*.md` equivalent. `~/.config/tamfis-code/agents/<name>.md`
187
+ (every session) or `<project>/.tamfis/agents/<name>.md` (one project, and
188
+ it replaces a same-named user definition outright) becomes a `/delegate
189
+ --agent <name> ...` / `/swarm --agent <name> ...` target:
190
+
191
+ ```markdown
192
+ ---
193
+ description: Reviews code for bugs and security issues
194
+ model: qwen/qwen3-coder
195
+ provider: openrouter
196
+ ---
197
+ You are a strict, terse code reviewer. Point out real bugs, security
198
+ issues, and correctness problems only — skip style nits.
199
+ ```
200
+
201
+ `model`/`provider` are optional; omit either to use whatever the
202
+ delegating call was already using. Run `/agent-types` to list what's
203
+ loaded. The model itself can also pick a subagent type per sub-task when
204
+ it calls `delegate_parallel_tasks` (each task entry may be `{"objective":
205
+ "...", "agent_type": "reviewer"}` instead of a plain string) — this is
206
+ what actually closes the Claude Code/Kimi gap: the orchestrating model
207
+ decides which specialised subagent handles which piece of independent
208
+ work, not just a human pre-scripting it via CLI flags.
209
+
210
+ ## Plan mode
211
+
212
+ `/plan <objective>` (or `--mode plan`) runs entirely read-only and
213
+ produces a real, grounded plan — no tool call in this turn can mutate
214
+ anything. When it finishes, the REPL asks **"Execute this plan now?
215
+ (y/N)"** right there — approve to switch straight into real execution
216
+ (the exact plan, not a fresh prompt), or decline to keep it saved for
217
+ later (`/plans` to list, `/execute-plan <id>` to run it whenever you're
218
+ ready, or `/plan` again to revise the objective first). This is the one
219
+ explicit approval checkpoint between "here's the plan" and anything
220
+ actually touching the workspace — Claude Code's Plan Mode equivalent.
221
+
222
+ ## Safety model
223
+
224
+ Every mutating tool call (`write_file`, `edit_file`, `execute_command`) is
225
+ risk-classified locally (`tamfis_code/safety.py`), gated by
226
+ `--approval-policy` (or the `/mode` REPL command), and recorded in a local
227
+ mutation ledger — see `tamfis-code diffs` / `tamfis-code diff` /
228
+ `tamfis-code revert`. There is no sandboxing beyond risk classification;
229
+ review dangerous commands yourself before approving them.
230
+
231
+ ## License
232
+
233
+ TBD — decide before the first public PyPI release (a public package still
234
+ needs a stated license; "all rights reserved"/proprietary is a valid choice
235
+ if you don't want redistribution/modification, but it should be explicit
236
+ rather than absent).
237
+
238
+ ## OpenHands-Class Runtime (0.6.1)
239
+
240
+ Tamfis-Code includes an integrated event-driven agent runtime under
241
+ `tamfis_code.openhands`. It provides conversations, immutable event replay,
242
+ local/SSH/remote workspaces, terminal/file/browser/Git tools, skills, security,
243
+ secrets, snapshots, leases, multi-agent delegation, automations and a REST /
244
+ WebSocket agent server. It runs without Docker and preserves the standalone
245
+ provider order NVIDIA → OpenRouter → Hugging Face. Ollama is intentionally not
246
+ included.
247
+
248
+ Start the agent server:
249
+
250
+ ```bash
251
+ tamfis-code-server --host 127.0.0.1 --port 9600
252
+ ```
@@ -0,0 +1,229 @@
1
+ # tamfis-code
2
+
3
+ A portable standalone terminal coding agent. It is designed to be installed
4
+ on any developer workstation, VPS, or server and run its agent loop, file
5
+ tools, shell, PTY/TTY sessions, approvals, plans, and state locally. It must
6
+ not depend on the machine that built it or on a co-located TamfisGPT server.
7
+
8
+ The product subscription boundary is separate from the runtime boundary:
9
+ normal users authenticate the CLI with their TamfisGPT iOS subscription/API
10
+ entitlement, and the CLI makes outbound API calls from the machine where it
11
+ is installed. Admin subscriptions are an account/billing policy, not a
12
+ requirement for installing or running the CLI.
13
+
14
+ The current standalone runtime can also call NVIDIA NIM, OpenRouter, or
15
+ Hugging Face directly. Every provider uses the same local-tool contract:
16
+ model traffic may be remote, but workspace files, commands, PTYs, approvals,
17
+ and mutation evidence remain local unless the user explicitly selects
18
+ `--remote`.
19
+
20
+ `--remote` (or a persistent `default_backend = "remote"` config setting)
21
+ switches to the original architecture: a thin client to the TamfisGPT
22
+ Remote Workspace backend, for TamfisGPT tenants using their hosted account
23
+ the same way Codex CLI uses a ChatGPT/OpenAI account, kimi-code uses a Kimi
24
+ account, or Claude Code uses a Claude account.
25
+
26
+ ## Install
27
+
28
+ ```
29
+ pipx install tamfis-code
30
+ ```
31
+
32
+ See [USAGE_INSTALL_RELEASE.md](./USAGE_INSTALL_RELEASE.md) for installing
33
+ from source, using a TamfisGPT tenancy, and the release process.
34
+
35
+ ## Quick start
36
+
37
+ ```
38
+ export NVIDIA_API_KEY=... # or set OPENROUTER_API_KEY / HF_TOKEN
39
+ tamfis-code doctor # check provider connectivity
40
+ tamfis-code ask "explain what this repo does"
41
+ tamfis-code agent "add a health-check endpoint" # full read/write/execute loop
42
+ tamfis-code # interactive REPL
43
+ ```
44
+
45
+ ### TamfisGPT subscription access
46
+
47
+ Create a developer API key from the TamfisGPT account connected to the iOS
48
+ subscription, then configure the machine where Tamfis-Code is installed:
49
+
50
+ ```bash
51
+ export TAMFIS_API_KEY='tamfis_sk_live_...'
52
+ # Optional for a private gateway or regional deployment:
53
+ export TAMFIS_API_BASE='https://gpt.tamfitronics.com/api/v1/openai'
54
+ tamfis-code doctor
55
+ tamfis-code agent "inspect this repository and fix the failing tests"
56
+ ```
57
+
58
+ The key is checked against the account's active subscription and API scopes
59
+ on every request. The CLI remains portable: the model request goes to the
60
+ TamfisGPT API, while repository files, shell commands, PTY sessions,
61
+ approvals, and mutation evidence stay on the local machine. Admin access is
62
+ not required for ordinary subscription users.
63
+
64
+ ## Providers
65
+
66
+ | Provider | Env var | Notes |
67
+ |---|---|---|
68
+ | NVIDIA NIM | `NVIDIA_API_KEY` | |
69
+ | OpenRouter | `OPENROUTER_API_KEY` | |
70
+ | Hugging Face | `HF_TOKEN` | |
71
+ | TamfisGPT subscription API | `TAMFIS_API_KEY` | Key issued for an active TamfisGPT plan |
72
+
73
+ Select one explicitly with `--provider tamfis|hf|nvidia|openrouter`, or leave it
74
+ as `auto` (default). Auto routes through eligible providers in
75
+ capability-ranked order. The selected provider/model is printed at the
76
+ start of every turn.
77
+
78
+ Interrupted provider streams remain attached to the same task: clean partial
79
+ text is checkpointed to `.memory`, reconnects use visible 5/15/30-second
80
+ backoff, and continuation output is de-duplicated. If all configured routes
81
+ remain unavailable, the CLI reports an actionable error and retains the exact
82
+ checkpoint for `continue` instead of pretending the request completed.
83
+
84
+ ## Local runtime storage
85
+
86
+ Tamfis Code is not tied to the machine that built or packaged it. Each
87
+ installed user gets private runtime storage in that operating system's
88
+ standard per-user location:
89
+
90
+ | Platform | Default |
91
+ |---|---|
92
+ | Linux/Unix | `$XDG_CONFIG_HOME/tamfis-code`, or `~/.config/tamfis-code` |
93
+ | macOS | `~/Library/Application Support/tamfis-code` |
94
+ | Windows | `%APPDATA%\tamfis-code` |
95
+
96
+ Set `TAMFIS_CODE_CONFIG_HOME` to use an explicit portable/container path.
97
+ Session memory is stored below that resolved directory in
98
+ `.memory/session-<id>.json`. No runtime state is written into the source
99
+ checkout or installed package directory, and no VPS/home path is compiled
100
+ into the wheel.
101
+
102
+ ## Hooks
103
+
104
+ Real, user-configurable pre/post-tool-use hooks (no code changes required) —
105
+ arbitrary shell commands that observe, or for `pre_tool_use`, veto, a real
106
+ local tool call in the standalone agent loop. Configure them in
107
+ `hooks.toml`: `~/.config/tamfis-code/hooks.toml` (or the platform-native
108
+ location above) for every session, and/or `<project>/.tamfis/hooks.toml`
109
+ for one project (both apply — project hooks run after user hooks):
110
+
111
+ ```toml
112
+ [[pre_tool_use]]
113
+ matcher = "write_file|edit_file" # regex against the tool name; omit/empty matches every tool
114
+ command = "python3 my_guard.py"
115
+
116
+ [[post_tool_use]]
117
+ matcher = "execute_command"
118
+ command = "notify-send 'tamfis-code ran a command'"
119
+ ```
120
+
121
+ Each hook receives a JSON event on stdin: `{"event", "tool_name",
122
+ "tool_input", "tool_output" (post_tool_use only), "session_id",
123
+ "workspace_root"}`. For `pre_tool_use`, exiting with code `2` blocks the
124
+ call — the tool is never executed, and the hook's stderr (or stdout, if
125
+ stderr is empty) becomes the denial reason the model sees. Any other exit
126
+ code doesn't block. For `post_tool_use`, the tool has already run, so no
127
+ exit code can undo it — stderr/stdout always just surfaces as additional
128
+ context appended for the model. Hooks are read fresh at the start of every
129
+ turn and time out after 30s; a hook that fails to start, errors, or times
130
+ out degrades to a visible diagnostic instead of failing the turn.
131
+
132
+ ## Custom commands
133
+
134
+ Define your own `/command`, no code changes required — drop a markdown
135
+ file into a commands directory and it's available in the interactive REPL
136
+ on the next turn. `~/.config/tamfis-code/commands/<name>.md` (or the
137
+ platform-native location above) applies to every session;
138
+ `<project>/.tamfis/commands/<name>.md` applies to one project (a project
139
+ command with the same name replaces the user one). The filename becomes
140
+ the command name, an optional frontmatter block sets its description, and
141
+ the rest of the file is the prompt template sent as the objective:
142
+
143
+ ```markdown
144
+ ---
145
+ description: Review a diff for security issues
146
+ ---
147
+ Review the following diff for security issues, focusing on injection,
148
+ auth, and secrets handling: $ARGUMENTS
149
+ ```
150
+
151
+ `$ARGUMENTS` is replaced with whatever you type after the command name
152
+ (`/secreview app.py` → the template with `$ARGUMENTS` replaced by
153
+ `app.py`); a template with no `$ARGUMENTS` placeholder still gets any
154
+ typed text appended on a new line. Run `/commands` in the REPL to list
155
+ what's currently loaded. A custom command can never shadow a built-in one
156
+ (`/plan`, `/agent`, etc. always win on a name collision).
157
+
158
+ ## Declarative subagent types
159
+
160
+ Give a delegated sub-task its own specialised system prompt (and,
161
+ optionally, its own model/provider) instead of every `/delegate`/`/swarm`
162
+ sub-objective sharing the same generic coding agent — Claude Code's
163
+ `.claude/agents/*.md` equivalent. `~/.config/tamfis-code/agents/<name>.md`
164
+ (every session) or `<project>/.tamfis/agents/<name>.md` (one project, and
165
+ it replaces a same-named user definition outright) becomes a `/delegate
166
+ --agent <name> ...` / `/swarm --agent <name> ...` target:
167
+
168
+ ```markdown
169
+ ---
170
+ description: Reviews code for bugs and security issues
171
+ model: qwen/qwen3-coder
172
+ provider: openrouter
173
+ ---
174
+ You are a strict, terse code reviewer. Point out real bugs, security
175
+ issues, and correctness problems only — skip style nits.
176
+ ```
177
+
178
+ `model`/`provider` are optional; omit either to use whatever the
179
+ delegating call was already using. Run `/agent-types` to list what's
180
+ loaded. The model itself can also pick a subagent type per sub-task when
181
+ it calls `delegate_parallel_tasks` (each task entry may be `{"objective":
182
+ "...", "agent_type": "reviewer"}` instead of a plain string) — this is
183
+ what actually closes the Claude Code/Kimi gap: the orchestrating model
184
+ decides which specialised subagent handles which piece of independent
185
+ work, not just a human pre-scripting it via CLI flags.
186
+
187
+ ## Plan mode
188
+
189
+ `/plan <objective>` (or `--mode plan`) runs entirely read-only and
190
+ produces a real, grounded plan — no tool call in this turn can mutate
191
+ anything. When it finishes, the REPL asks **"Execute this plan now?
192
+ (y/N)"** right there — approve to switch straight into real execution
193
+ (the exact plan, not a fresh prompt), or decline to keep it saved for
194
+ later (`/plans` to list, `/execute-plan <id>` to run it whenever you're
195
+ ready, or `/plan` again to revise the objective first). This is the one
196
+ explicit approval checkpoint between "here's the plan" and anything
197
+ actually touching the workspace — Claude Code's Plan Mode equivalent.
198
+
199
+ ## Safety model
200
+
201
+ Every mutating tool call (`write_file`, `edit_file`, `execute_command`) is
202
+ risk-classified locally (`tamfis_code/safety.py`), gated by
203
+ `--approval-policy` (or the `/mode` REPL command), and recorded in a local
204
+ mutation ledger — see `tamfis-code diffs` / `tamfis-code diff` /
205
+ `tamfis-code revert`. There is no sandboxing beyond risk classification;
206
+ review dangerous commands yourself before approving them.
207
+
208
+ ## License
209
+
210
+ TBD — decide before the first public PyPI release (a public package still
211
+ needs a stated license; "all rights reserved"/proprietary is a valid choice
212
+ if you don't want redistribution/modification, but it should be explicit
213
+ rather than absent).
214
+
215
+ ## OpenHands-Class Runtime (0.6.1)
216
+
217
+ Tamfis-Code includes an integrated event-driven agent runtime under
218
+ `tamfis_code.openhands`. It provides conversations, immutable event replay,
219
+ local/SSH/remote workspaces, terminal/file/browser/Git tools, skills, security,
220
+ secrets, snapshots, leases, multi-agent delegation, automations and a REST /
221
+ WebSocket agent server. It runs without Docker and preserves the standalone
222
+ provider order NVIDIA → OpenRouter → Hugging Face. Ollama is intentionally not
223
+ included.
224
+
225
+ Start the agent server:
226
+
227
+ ```bash
228
+ tamfis-code-server --host 127.0.0.1 --port 9600
229
+ ```
@@ -0,0 +1,67 @@
1
+ # Install and release TamfisGPT Code
2
+
3
+ ## Install on any server
4
+
5
+ Use an isolated installer so the CLI does not depend on the host Python
6
+ environment:
7
+
8
+ ```bash
9
+ python3 -m pip install --user tamfis-code
10
+ # or:
11
+ pipx install tamfis-code
12
+ ```
13
+
14
+ The runtime stores session state in the platform's user configuration
15
+ directory. It does not require a TamfisGPT server process on the same host.
16
+
17
+ ## Configure the TamfisGPT subscription API
18
+
19
+ Create an API key from the TamfisGPT account connected to the user's active
20
+ iOS subscription, then set:
21
+
22
+ ```bash
23
+ export TAMFIS_API_KEY='tamfis_sk_live_...'
24
+ export TAMFIS_API_BASE='https://gpt.tamfitronics.com/api/v1/openai'
25
+ tamfis-code doctor
26
+ ```
27
+
28
+ The API key is the user's entitlement boundary. Admin credentials are not
29
+ needed for ordinary subscribers. The API handles model access and billing;
30
+ the installed CLI keeps workspace files, commands, PTYs, approvals, and the
31
+ mutation ledger on the local machine.
32
+
33
+ ## Interactive queue controls
34
+
35
+ While a task is running, press `Ctrl+T` to open `queue next>`. The submitted
36
+ line is echoed with a durable queue ID, then applied at the next safe model
37
+ round boundary. Multiple queued updates are processed in order. A second
38
+ terminal can enqueue the same session with:
39
+
40
+ ```bash
41
+ tamfis-code queue "also inspect the authentication flow" --classification follow_up
42
+ ```
43
+
44
+ `/queue` lists pending requests in the interactive REPL. `Ctrl+C` remains the
45
+ interrupt/exit control; ordinary keystrokes are never silently turned into a
46
+ partial instruction while streaming.
47
+
48
+ ## Build and publish a release
49
+
50
+ Run the full checks, build a clean distribution, and inspect it before
51
+ publishing:
52
+
53
+ ```bash
54
+ python3 -m pytest -q
55
+ python3 -m build
56
+ python3 -m twine check dist/*
57
+ ```
58
+
59
+ Publishing requires an account token configured in the release environment:
60
+
61
+ ```bash
62
+ python3 -m twine upload dist/*
63
+ ```
64
+
65
+ The GitHub repository should receive the same source revision and release
66
+ notes as the PyPI upload. Never commit API keys, subscription tokens, local
67
+ session state, or generated build artifacts.
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "tamfis-code"
3
- version = "0.2.3"
4
- description = "TamfisGPT Code -- standalone terminal coding agent (calls HF/NVIDIA NIM/OpenRouter/Ollama directly; --remote for the legacy TamfisGPT Remote backend)"
3
+ version = "0.6.2"
4
+ description = "TamfisGPT Code -- portable subscription-backed terminal coding agent with local tools, PTY, plans, queues, and approvals"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
@@ -10,16 +10,24 @@ dependencies = [
10
10
  "rich>=13.0",
11
11
  "prompt_toolkit>=3.0",
12
12
  # Provider calls (providers.py) go through the openai SDK's client against
13
- # each vendor's OpenAI-compatible endpoint (HF, NVIDIA NIM, OpenRouter,
14
- # Ollama) -- this was imported but never declared, only working because a
13
+ # each vendor's OpenAI-compatible endpoint (HF, NVIDIA NIM, OpenRouter)
14
+ # -- this was imported but never declared, only working because a
15
15
  # copy happened to already be installed system-wide.
16
16
  "openai>=1.30",
17
+ # Outbound MCP server (`tamfis-code mcp-server`, mcp_stdio_server.py) --
18
+ # was already installed system-wide and imported ad hoc; same class of
19
+ # undeclared-dependency gap as openai/pytest-asyncio above, now fixed.
20
+ "mcp>=1.2",
21
+ "fastapi>=0.115",
22
+ "uvicorn>=0.34",
23
+ "websockets>=13",
17
24
  ]
18
25
 
19
26
  [project.scripts]
20
27
  tamfis-code = "tamfis_code.cli:main"
21
28
  tamgpt-code = "tamfis_code.cli:main"
22
29
  tamfis = "tamfis_code.cli:main"
30
+ tamfis-code-server = "tamfis_code.openhands.agent_server:main"
23
31
 
24
32
  [project.urls]
25
33
  Homepage = "https://github.com/tamfitronics/tamfis-code"
@@ -40,5 +48,14 @@ dev = [
40
48
  requires = ["setuptools>=68"]
41
49
  build-backend = "setuptools.build_meta"
42
50
 
43
- [tool.setuptools]
44
- packages = ["tamfis_code"]
51
+ [tool.setuptools.packages.find]
52
+ include = ["tamfis_code*"]
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = ["tests"]
56
+ norecursedirs = [
57
+ "tests.backup.*",
58
+ ".git",
59
+ ".pytest_cache",
60
+ "__pycache__",
61
+ ]
@@ -1,7 +1,7 @@
1
1
  """TamfisGPT Code -- a standalone terminal coding agent.
2
2
 
3
- By default, this package calls an LLM provider directly (Hugging Face,
4
- NVIDIA NIM, OpenRouter, or Ollama -- see providers.py/runner_local.py) and
3
+ By default, this package calls an LLM provider directly (NVIDIA NIM,
4
+ OpenRouter, or Hugging Face -- see providers.py/runner_local.py) and
5
5
  runs its own agent loop, tool execution (mcp.py), and local risk
6
6
  classification/approval/mutation ledger (safety.py) -- no separate backend
7
7
  process required. Every `ask`/`chat`/`audit`/`plan`/`agent`/`exec` command,
@@ -17,7 +17,7 @@ See docs/REMOTE_AGENT_MASTER_SPEC.md, Phase 21, for the original --remote
17
17
  architecture's spec.
18
18
  """
19
19
 
20
- __version__ = "0.2.3"
20
+ __version__ = "0.6.2"
21
21
 
22
22
  # Bumped whenever a CLI release requires a minimum backend Remote API
23
23
  # contract version. Only meaningful for --remote; the standalone path has no
@@ -31,7 +31,6 @@ MIN_COMPATIBLE_API_VERSION = "remote-ai-v2"
31
31
  # New exports
32
32
  from .completion import ShellCompleter
33
33
  from .metrics import MetricsTracker, StreamMetrics
34
- from .sessions import SessionManager, Session, Message
35
34
  from .agents import AgentManager, SubAgent, CodeAnalyzer, TestGenerator, DocGenerator
36
35
  from .mcp import MCPServer, ToolDefinition, call_tool
37
36
  from .indexer import CodeIndexer, CodeSymbol, CodeFile
@@ -41,9 +40,6 @@ __all__ = [
41
40
  'ShellCompleter',
42
41
  'MetricsTracker',
43
42
  'StreamMetrics',
44
- 'SessionManager',
45
- 'Session',
46
- 'Message',
47
43
  'AgentManager',
48
44
  'SubAgent',
49
45
  'CodeAnalyzer',