anyfs 0.1.0.dev1__tar.gz → 0.1.0.dev3__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 (89) hide show
  1. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/PKG-INFO +1 -1
  2. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/PKG-INFO +1 -1
  3. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/apps/cli/src/anyfs_cli/main.py +134 -0
  4. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/pyproject.toml +1 -1
  5. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/README.md +0 -0
  6. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/SOURCES.txt +0 -0
  7. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/dependency_links.txt +0 -0
  8. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/entry_points.txt +0 -0
  9. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/requires.txt +0 -0
  10. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/anyfs.egg-info/top_level.txt +0 -0
  11. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/apps/cli/src/anyfs_cli/__init__.py +0 -0
  12. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-claude-code/src/anyfs_adapter_claude_code/__init__.py +0 -0
  13. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-claude-code/src/anyfs_adapter_claude_code/adapter.py +0 -0
  14. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-codex-cli/src/anyfs_adapter_codex_cli/__init__.py +0 -0
  15. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-codex-cli/src/anyfs_adapter_codex_cli/adapter.py +0 -0
  16. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-gemini-cli/src/anyfs_adapter_gemini_cli/__init__.py +0 -0
  17. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-gemini-cli/src/anyfs_adapter_gemini_cli/adapter.py +0 -0
  18. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-hermes/src/anyfs_adapter_hermes/__init__.py +0 -0
  19. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-hermes/src/anyfs_adapter_hermes/adapter.py +0 -0
  20. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-nanobot/src/anyfs_adapter_nanobot/__init__.py +0 -0
  21. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-nanobot/src/anyfs_adapter_nanobot/adapter.py +0 -0
  22. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-openclaw/src/anyfs_adapter_openclaw/__init__.py +0 -0
  23. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-openclaw/src/anyfs_adapter_openclaw/adapter.py +0 -0
  24. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-opencode/src/anyfs_adapter_opencode/__init__.py +0 -0
  25. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapter-opencode/src/anyfs_adapter_opencode/adapter.py +0 -0
  26. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapters-core/src/anyfs_adapters_core/__init__.py +0 -0
  27. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/adapters-core/src/anyfs_adapters_core/base.py +0 -0
  28. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/crypto/src/anyfs_crypto/__init__.py +0 -0
  29. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/crypto/src/anyfs_crypto/keys.py +0 -0
  30. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/lineage/src/anyfs_lineage/__init__.py +0 -0
  31. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/lineage/src/anyfs_lineage/graph.py +0 -0
  32. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/local-state/src/anyfs_local_state/__init__.py +0 -0
  33. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/local-state/src/anyfs_local_state/state.py +0 -0
  34. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/packaging/src/anyfs_packaging/__init__.py +0 -0
  35. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/packaging/src/anyfs_packaging/afpkg.py +0 -0
  36. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/schemas/src/anyfs_schemas/__init__.py +0 -0
  37. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/schemas/src/anyfs_schemas/models.py +0 -0
  38. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/schemas/src/anyfs_schemas/transcript.py +0 -0
  39. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/sdk-python/src/anyfs_sdk/__init__.py +0 -0
  40. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/sdk-python/src/anyfs_sdk/service.py +0 -0
  41. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/sdk-python/src/anyfs_sdk/skill_runtime.py +0 -0
  42. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/skill-spec/src/anyfs_skill_spec/__init__.py +0 -0
  43. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/skill-spec/src/anyfs_skill_spec/actions.py +0 -0
  44. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/__init__.py +0 -0
  45. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/__init__.py +0 -0
  46. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/claude_code.py +0 -0
  47. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/codex_cli.py +0 -0
  48. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/gemini_cli.py +0 -0
  49. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/hermes.py +0 -0
  50. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/nanobot.py +0 -0
  51. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/openclaw.py +0 -0
  52. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/exporters/opencode.py +0 -0
  53. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/__init__.py +0 -0
  54. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/claude_code.py +0 -0
  55. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/codex_cli.py +0 -0
  56. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/context.py +0 -0
  57. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/cursor.py +0 -0
  58. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/injectors/gemini_cli.py +0 -0
  59. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/__init__.py +0 -0
  60. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/base.py +0 -0
  61. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/claude_code.py +0 -0
  62. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/codex_cli.py +0 -0
  63. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/gemini_cli.py +0 -0
  64. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/hermes.py +0 -0
  65. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/nanobot.py +0 -0
  66. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/openclaw.py +0 -0
  67. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/parsers/opencode.py +0 -0
  68. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/registry.py +0 -0
  69. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/renderers/__init__.py +0 -0
  70. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/renderers/chat.py +0 -0
  71. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/packages/transcript/src/anyfs_transcript/renderers/markdown.py +0 -0
  72. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/setup.cfg +0 -0
  73. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_claude_code.py +0 -0
  74. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_codex_cli.py +0 -0
  75. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_gemini_cli.py +0 -0
  76. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_hermes.py +0 -0
  77. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_nanobot.py +0 -0
  78. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_openclaw.py +0 -0
  79. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapter_opencode.py +0 -0
  80. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_adapters_core.py +0 -0
  81. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_crypto.py +0 -0
  82. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_lineage.py +0 -0
  83. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_local_state.py +0 -0
  84. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_packaging.py +0 -0
  85. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_schemas.py +0 -0
  86. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_sdk_flow.py +0 -0
  87. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_skill_spec.py +0 -0
  88. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_transcript_resume.py +0 -0
  89. {anyfs-0.1.0.dev1 → anyfs-0.1.0.dev3}/tests/test_transfer_matrix_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anyfs
3
- Version: 0.1.0.dev1
3
+ Version: 0.1.0.dev3
4
4
  Summary: AnyFS command line interface and Python toolkit
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anyfs
3
- Version: 0.1.0.dev1
3
+ Version: 0.1.0.dev3
4
4
  Summary: AnyFS command line interface and Python toolkit
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -33,6 +33,63 @@ def service() -> AnyFSService:
33
33
  return AnyFSService()
34
34
 
35
35
 
36
+ def _workspace_next_steps(result: dict, workspace: str) -> list[str]:
37
+ if result.get("namespace") != "workspace":
38
+ return []
39
+ output_file = result.get("output_file")
40
+ restore_dir = result.get("restore_dir")
41
+ if not output_file:
42
+ return []
43
+ try:
44
+ bundle = json.loads(Path(output_file).read_text(encoding="utf-8"))
45
+ except Exception:
46
+ return []
47
+ binding = bundle.get("binding") or {}
48
+ mode = bundle.get("mode") or result.get("workspace_mode") or "changed"
49
+ steps: list[str] = []
50
+ remote = binding.get("remote")
51
+ commit_sha = binding.get("commit_sha")
52
+ if remote:
53
+ checkout = f" and checkout {commit_sha}" if commit_sha else ""
54
+ steps.append(f"Clone {remote}{checkout}.")
55
+ if restore_dir:
56
+ if mode == "full":
57
+ steps.append(f"Workspace was fully restored at {restore_dir}. You can continue directly from that directory.")
58
+ elif mode == "changed":
59
+ steps.append(f"Workspace overlay was restored at {restore_dir}. Review and apply those files onto your local checkout.")
60
+ else:
61
+ steps.append(f"Workspace metadata was restored at {restore_dir}.")
62
+ if binding.get("branch") and not remote:
63
+ steps.append(f"Use branch {binding['branch']} when recreating the workspace locally.")
64
+ return steps
65
+
66
+
67
+ def _process_next_steps(result: dict, workspace: str, target: str | None) -> list[str]:
68
+ if result.get("namespace") != "process":
69
+ return []
70
+ output_file = result.get("output_file")
71
+ if not output_file:
72
+ return []
73
+ suggested_target = target or "<target-agent>"
74
+ return [
75
+ f"Read the restored process at {output_file}.",
76
+ f"When you want native session restore, run: anyfs resume {output_file} --target {suggested_target} -w {workspace}",
77
+ ]
78
+
79
+
80
+ def _emit_open_next_steps(results: list[dict], workspace: str, target: str | None) -> None:
81
+ steps: list[str] = []
82
+ for result in results:
83
+ steps.extend(_workspace_next_steps(result, workspace))
84
+ for result in results:
85
+ steps.extend(_process_next_steps(result, workspace, target))
86
+ if not steps:
87
+ return
88
+ typer.echo("\nNext:")
89
+ for idx, step in enumerate(steps, start=1):
90
+ typer.echo(f" {idx}. {step}")
91
+
92
+
36
93
  # ── Primary commands (register / share / open) ─────────────────
37
94
 
38
95
  @app.command("register")
@@ -129,6 +186,33 @@ def share_command(
129
186
  _run_share(workspace, namespaces, password, message, workspace_mode, agent_type, process_scope, artifacts_public, artifact)
130
187
 
131
188
 
189
+ def _detect_current_agent_type() -> str | None:
190
+ """Best-effort guess of the agent harness currently running this command.
191
+
192
+ Used to make the register hint after `anyfs open` concrete instead of
193
+ forcing the user to pick from a list.
194
+ """
195
+ import os
196
+ # Most harnesses expose a distinctive env var when they spawn a shell.
197
+ env_signals = (
198
+ ("CLAUDE_CODE_ENTRYPOINT", "claude-code"),
199
+ ("CLAUDECODE", "claude-code"),
200
+ ("CLAUDE_CONFIG_DIR", "claude-code"),
201
+ ("CODEX_THREAD_ID", "codex-cli"),
202
+ ("CODEX_HOME", "codex-cli"),
203
+ ("GEMINI_CLI_SESSION_ID", "gemini-cli"),
204
+ ("OPENCLAW_SESSION", "openclaw"),
205
+ ("OPENCODE_SESSION", "opencode"),
206
+ ("HERMES_SESSION", "hermes"),
207
+ ("NANOBOT_SESSION", "nanobot"),
208
+ ("CURSOR_WORKSPACE", "cursor"),
209
+ )
210
+ for env_name, agent_type in env_signals:
211
+ if os.environ.get(env_name):
212
+ return agent_type
213
+ return None
214
+
215
+
132
216
  @app.command("open")
133
217
  def open_command(
134
218
  share_paths: list[str] = typer.Argument(..., help="One or more share URLs or paths to .share.json files"),
@@ -137,6 +221,16 @@ def open_command(
137
221
  resume: bool = typer.Option(False, "--resume", help="Auto-resume the session after decrypting"),
138
222
  target: str | None = typer.Option(None, "--target", "-t", help="Target agent for resume (default: auto-detect)"),
139
223
  workspace: str = typer.Option(str(Path.cwd()), "--workspace", "-w"),
224
+ register_as: str | None = typer.Option(
225
+ None,
226
+ "--register-as",
227
+ help="After decrypting, auto-register this workspace's agent with the given display name",
228
+ ),
229
+ register_type: str | None = typer.Option(
230
+ None,
231
+ "--register-type",
232
+ help="Agent type to register as (auto-detected from the environment when omitted)",
233
+ ),
140
234
  ) -> None:
141
235
  """Decrypt and load a shared context."""
142
236
  svc = service()
@@ -154,6 +248,7 @@ def open_command(
154
248
  msg = next((r["message"] for r in results if r.get("message")), None)
155
249
  if msg:
156
250
  typer.echo(f"\n Message: {msg}")
251
+ _emit_open_next_steps(results, workspace, target)
157
252
  if resume:
158
253
  process_results = [r for r in results if r["namespace"] == "process"]
159
254
  for result in process_results:
@@ -164,6 +259,45 @@ def open_command(
164
259
  files = export_transcript(t, target_agent=tgt, workspace=workspace)
165
260
  typer.echo(f" Resumed session {t.session.id} -> {tgt}")
166
261
 
262
+ # ── Post-open: prompt the receiver to claim an agent identity ──
263
+ #
264
+ # If the receiving workspace has no AnyFS agent yet, they can consume
265
+ # this share but cannot share / publish back. We either auto-register
266
+ # (when `--register-as` was passed) or emit a loud, agent-readable
267
+ # warning on stderr so the assistant can walk the user through it.
268
+ agent_json = Path(workspace).expanduser().resolve() / ".anyfs" / "agent.json"
269
+ if agent_json.exists():
270
+ return
271
+
272
+ detected_type = register_type or _detect_current_agent_type()
273
+
274
+ if register_as:
275
+ chosen_type = detected_type or "claude-code"
276
+ try:
277
+ reg = svc.register_agent(chosen_type, workspace, register_as)
278
+ svc.agent_create_remote(workspace, chosen_type)
279
+ typer.echo("\n✅ Registered AnyFS agent for this workspace:")
280
+ typer.echo(f" Name: {reg['display_name']}")
281
+ typer.echo(f" Type: {reg['agent_type']}")
282
+ typer.echo(f" DID: {reg['agent_id']}")
283
+ except Exception as exc:
284
+ typer.echo(f"\n⚠️ Auto-register failed: {exc}", err=True)
285
+ typer.echo(
286
+ f" Run manually: anyfs register --type {chosen_type} {register_as}",
287
+ err=True,
288
+ )
289
+ return
290
+
291
+ hint_type = detected_type or "<agent-type>"
292
+ typer.echo("", err=True)
293
+ typer.echo("⚠️ This workspace has no AnyFS agent identity yet.", err=True)
294
+ typer.echo(" You can read the decrypted context, but you cannot share or", err=True)
295
+ typer.echo(" publish back until you register. To register now, run:", err=True)
296
+ typer.echo("", err=True)
297
+ typer.echo(f" anyfs register --type {hint_type} <your-display-name>", err=True)
298
+ typer.echo("", err=True)
299
+ typer.echo(" Or re-run `anyfs open` with `--register-as <display-name>`.", err=True)
300
+
167
301
 
168
302
  # ── Core commands ────────────────────────────────────────────────
169
303
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "anyfs"
3
- version = "0.1.0.dev1"
3
+ version = "0.1.0.dev3"
4
4
  description = "AnyFS command line interface and Python toolkit"
5
5
  requires-python = ">=3.10"
6
6
  readme = "README.md"
File without changes
File without changes