agent-sessions-cli 0.2.0__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.
- agent_sessions/__init__.py +3 -0
- agent_sessions/__main__.py +3 -0
- agent_sessions/adapters/__init__.py +136 -0
- agent_sessions/adapters/base.py +108 -0
- agent_sessions/adapters/claude_code.py +300 -0
- agent_sessions/adapters/codex.py +360 -0
- agent_sessions/adapters/gemini.py +176 -0
- agent_sessions/adapters/opencode.py +231 -0
- agent_sessions/cli.py +858 -0
- agent_sessions/core.py +748 -0
- agent_sessions/model.py +119 -0
- agent_sessions/templates/gitattributes +2 -0
- agent_sessions/templates/sessions-README.md +31 -0
- agent_sessions/templates/summary.md +31 -0
- agent_sessions_cli-0.2.0.dist-info/METADATA +141 -0
- agent_sessions_cli-0.2.0.dist-info/RECORD +19 -0
- agent_sessions_cli-0.2.0.dist-info/WHEEL +4 -0
- agent_sessions_cli-0.2.0.dist-info/entry_points.txt +2 -0
- agent_sessions_cli-0.2.0.dist-info/licenses/LICENSE +21 -0
agent_sessions/model.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Agent-neutral session model. Adapters produce it, the renderer consumes it."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import datetime as dt
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import List, Optional, Tuple
|
|
9
|
+
|
|
10
|
+
# Canonical tool kinds. Adapters map their native tool names onto these; the
|
|
11
|
+
# renderer and the result policy never see agent-specific names.
|
|
12
|
+
KINDS = ("shell", "read", "edit", "write", "search", "web", "agent", "mcp", "ask", "other")
|
|
13
|
+
STUB_KINDS = {"read", "web", "mcp"} # results replaced by a one-line stub
|
|
14
|
+
SNIPPET_KINDS = {"edit", "write"} # inputs shown as short snippets
|
|
15
|
+
SENSITIVE_PROBE_KINDS = {"shell", "read", "edit", "write", "search"}
|
|
16
|
+
|
|
17
|
+
# A user turn that invoked push, in any agent's syntax.
|
|
18
|
+
PUSH_MARKER_RE = re.compile(
|
|
19
|
+
r"<command-name>\s*/[\w-]*sessions[\w-]*:push\s*</command-name>"
|
|
20
|
+
r"|/sessions:push\b"
|
|
21
|
+
r"|\$agent-sessions\s+push\b"
|
|
22
|
+
r"|\bagent-sessions\s+push\b"
|
|
23
|
+
r"|\bsessions-push\b",
|
|
24
|
+
re.I,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# The shell call that *is* the locate preflight. Used to recognise the live
|
|
28
|
+
# session: it is the one whose most recent shell call is this and has no output yet.
|
|
29
|
+
SELF_REF_RE = re.compile(r"sessions(?:\.sh|\.py)?\b[^\n]{0,200}\blocate\b|\bagent-sessions\b[^\n]{0,80}\blocate\b", re.I)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class ToolCall:
|
|
34
|
+
kind: str # one of KINDS
|
|
35
|
+
name: str # agent-native name
|
|
36
|
+
label: str # one-line summary shown in <summary>
|
|
37
|
+
input: object = None # dict when structured, str when opaque
|
|
38
|
+
output: str = ""
|
|
39
|
+
is_error: bool = False
|
|
40
|
+
paths: List[str] = field(default_factory=list) # files this call touched (edit/write)
|
|
41
|
+
pending: bool = False # no output recorded yet (call in flight)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class Event:
|
|
46
|
+
kind: str # user | assistant | thinking | tool | compaction | note
|
|
47
|
+
text: str = ""
|
|
48
|
+
ts: Optional[dt.datetime] = None
|
|
49
|
+
is_push_invocation: bool = False
|
|
50
|
+
command: str = "" # slash command the user ran ("/compact"), if any
|
|
51
|
+
tool: Optional[ToolCall] = None
|
|
52
|
+
meta: dict = field(default_factory=dict)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class Session:
|
|
57
|
+
agent: str # claude-code | codex | opencode | gemini-cli
|
|
58
|
+
session_id: str
|
|
59
|
+
short_id: str
|
|
60
|
+
title: Optional[str]
|
|
61
|
+
cwd: Optional[str]
|
|
62
|
+
started: Optional[dt.datetime]
|
|
63
|
+
ended: Optional[dt.datetime]
|
|
64
|
+
events: List[Event]
|
|
65
|
+
source: str # file path or "sqlite:<db>#<id>"
|
|
66
|
+
agent_version: Optional[str] = None
|
|
67
|
+
originator: Optional[str] = None
|
|
68
|
+
parent_id: Optional[str] = None
|
|
69
|
+
subagent_files: int = 0
|
|
70
|
+
tokens: Optional[dict] = None
|
|
71
|
+
tested_version: Optional[Tuple[int, ...]] = None
|
|
72
|
+
warnings: List[str] = field(default_factory=list)
|
|
73
|
+
record_count: int = 0
|
|
74
|
+
bad_lines: int = 0
|
|
75
|
+
|
|
76
|
+
def files_touched(self) -> List[str]:
|
|
77
|
+
seen = {}
|
|
78
|
+
for e in self.events:
|
|
79
|
+
if e.tool:
|
|
80
|
+
for p in e.tool.paths:
|
|
81
|
+
seen.setdefault(p, None)
|
|
82
|
+
return list(seen.keys())
|
|
83
|
+
|
|
84
|
+
def user_prompts(self, limit: int = 200) -> List[Tuple[Optional[dt.datetime], str]]:
|
|
85
|
+
out = []
|
|
86
|
+
for e in self.events:
|
|
87
|
+
if e.kind != "user" or e.is_push_invocation:
|
|
88
|
+
continue
|
|
89
|
+
if e.command:
|
|
90
|
+
out.append((e.ts, "/" + e.command.lstrip("/")))
|
|
91
|
+
elif e.text:
|
|
92
|
+
out.append((e.ts, re.sub(r"\s+", " ", e.text)[:limit]))
|
|
93
|
+
return out
|
|
94
|
+
|
|
95
|
+
def agent_tasks(self) -> List[str]:
|
|
96
|
+
return [re.sub(r"\s+", " ", e.tool.label)[:120] for e in self.events if e.tool and e.tool.kind == "agent"]
|
|
97
|
+
|
|
98
|
+
def last_user_text(self) -> str:
|
|
99
|
+
for e in reversed(self.events):
|
|
100
|
+
if e.kind == "user":
|
|
101
|
+
return e.text or e.command
|
|
102
|
+
return ""
|
|
103
|
+
|
|
104
|
+
def has_pending_self_call(self) -> bool:
|
|
105
|
+
"""True when the most recent shell call is our own `locate` and has produced no output yet."""
|
|
106
|
+
for e in reversed(self.events):
|
|
107
|
+
if e.tool and e.tool.kind == "shell":
|
|
108
|
+
return bool(e.tool.pending and SELF_REF_RE.search(_input_blob(e.tool.input)))
|
|
109
|
+
return False
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _input_blob(value: object) -> str:
|
|
113
|
+
if isinstance(value, str):
|
|
114
|
+
return value
|
|
115
|
+
if isinstance(value, dict):
|
|
116
|
+
return " ".join(_input_blob(v) for v in value.values())
|
|
117
|
+
if isinstance(value, list):
|
|
118
|
+
return " ".join(_input_blob(v) for v in value)
|
|
119
|
+
return "" if value is None else str(value)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Shared coding-agent sessions
|
|
2
|
+
|
|
3
|
+
This folder holds sessions that teammates chose to share, whichever coding agent they used. Each session is one directory:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
YYYY-MM-DD_<slug>_<handle>_<short-id>/
|
|
7
|
+
├── summary.md handoff written by the author's agent at push time: goal, outcome, decisions, files, gotchas, next steps, paste-ready handoff prompt
|
|
8
|
+
├── transcript.md the conversation rendered to markdown; tool calls collapsed, secrets redacted, query results omitted
|
|
9
|
+
└── meta.json machine-readable index entry (title, author, agent, branch, files touched, tags, outcome)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Start with `summary.md`. Open `transcript.md` only when you need to see exactly what was tried.
|
|
13
|
+
|
|
14
|
+
## How to push and pull, by agent
|
|
15
|
+
|
|
16
|
+
| Agent | Share this session | Read teammates' sessions |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Claude Code | `/sessions:push [title] [--yes]` | `/sessions:pull [keyword]` |
|
|
19
|
+
| Codex CLI | `$agent-sessions push [title] --yes` | `$agent-sessions pull [keyword]` |
|
|
20
|
+
| OpenCode, Gemini CLI, Cursor, Copilot | ask the agent to *use the agent-sessions skill to push this session* | ask it to *use the agent-sessions skill to pull [keyword]* |
|
|
21
|
+
| Any terminal | `agent-sessions push` (after `pip install agent-sessions-cli`) | `agent-sessions list` |
|
|
22
|
+
|
|
23
|
+
Useful pull flags: `--full <id>` reads one full transcript, `--all-branches` includes sessions on unmerged branches, `--mine` filters to your own.
|
|
24
|
+
|
|
25
|
+
Install once: Claude Code users are prompted to install the `sessions` plugin when they open this repo. Everyone else runs `scripts/setup.sh --skills` (or `setup.ps1 -Skills`) from https://github.com/prajwalgajakesari/agent-sessions, which copies the skill into `~/.agents/skills/`. If `.agents/skills/agent-sessions/` exists in this repo, the skill is already vendored and nothing needs installing.
|
|
26
|
+
|
|
27
|
+
## What gets redacted
|
|
28
|
+
|
|
29
|
+
Structured secrets (cloud keys, tokens, JWTs, private keys, connection-string passwords, SAS signatures) are replaced with `[REDACTED:<kind>]` before anything is committed. Results from file reads, web fetches and MCP tools are omitted and other tool output is truncated, so query rows and file contents do not end up here. Keyword-based redactions (`password=`, `api_key=`) are flagged for the author to review at push time. Nothing here is guaranteed clean: treat a transcript as you would treat a chat log.
|
|
30
|
+
|
|
31
|
+
There is no generated index on purpose. Directories are per session and per author, so concurrent pushes never conflict. `agent-sessions list` builds the index from `meta.json` files on demand.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "<3 to 8 words naming the work>"
|
|
3
|
+
session_id: "<set by export>"
|
|
4
|
+
author: "<set by export>"
|
|
5
|
+
handle: "<set by export>"
|
|
6
|
+
date: "<set by export>"
|
|
7
|
+
branch: "<set by export>"
|
|
8
|
+
tags: [<area>, <kind-of-work>]
|
|
9
|
+
outcome: "<one sentence: what is true now that was not before>"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
What was asked for, in two or three sentences. Include the why when it was stated.
|
|
14
|
+
|
|
15
|
+
## Outcome
|
|
16
|
+
What was delivered, what was verified, and what was left undone. Say plainly if something failed or was skipped.
|
|
17
|
+
|
|
18
|
+
## Key decisions and why
|
|
19
|
+
- Decision. Reason. Alternative that was rejected and why.
|
|
20
|
+
|
|
21
|
+
## Files changed
|
|
22
|
+
- `path/to/file` — what changed and why.
|
|
23
|
+
|
|
24
|
+
## Commands and gotchas
|
|
25
|
+
Exact commands a teammate will need, in fenced blocks. Anything that bit us: wrong assumptions, flaky steps, environment quirks.
|
|
26
|
+
|
|
27
|
+
## Open questions and next steps
|
|
28
|
+
- Item. What or who it is waiting on.
|
|
29
|
+
|
|
30
|
+
## Handoff prompt
|
|
31
|
+
A paste-ready prompt for a teammate starting a fresh Claude Code session: the goal, the current state, the files to read first, and the next concrete action.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agent-sessions-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Share coding-agent sessions (Claude Code, Codex CLI, OpenCode, Gemini CLI) with your team through git.
|
|
5
|
+
Project-URL: Homepage, https://github.com/prajwalgajakesari/agent-sessions
|
|
6
|
+
Project-URL: Repository, https://github.com/prajwalgajakesari/agent-sessions
|
|
7
|
+
Project-URL: Changelog, https://github.com/prajwalgajakesari/agent-sessions/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Issues, https://github.com/prajwalgajakesari/agent-sessions/issues
|
|
9
|
+
Author: Prajwal P
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: claude-code,codex,gemini-cli,git,handoff,opencode,sessions,team,transcript
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Topic :: Software Development
|
|
21
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# agent-sessions
|
|
26
|
+
|
|
27
|
+
Share coding-agent sessions with your team through the git repo you already work in. One folder, `.claude/sessions/`, holds handoffs from **Claude Code, Codex CLI, OpenCode** and (experimentally) **Gemini CLI**; anyone on any agent can pull them back into their own chat.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
/sessions:push "Reconcile fabric tables" Claude Code, end of a session
|
|
31
|
+
$agent-sessions pull reconcile a teammate in Codex, next morning
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Coding agents keep sessions in private, undocumented, short-lived local stores. This tool turns one into three committed files and gives teammates one command to load them.
|
|
35
|
+
|
|
36
|
+
## What a pushed session looks like
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
.claude/sessions/2026-09-22_reconcile-fabric-tables_prajwal-p_7dcecef6/
|
|
40
|
+
├── summary.md handoff the author's agent wrote at push time: goal, outcome, decisions and why,
|
|
41
|
+
│ files changed, commands and gotchas, open questions, a paste-ready handoff prompt (≤120 lines)
|
|
42
|
+
├── transcript.md the conversation as markdown along the active path (rewinds and compaction handled),
|
|
43
|
+
│ tool calls collapsed, secrets redacted, file reads and query results omitted
|
|
44
|
+
└── meta.json title, author, agent and version, branch, dates, files touched (subagents included), tags, outcome, tokens
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Pull reads `summary.md` first and loads a transcript only when asked, so a teammate gets the reasoning without burning their context window.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
| You use | Do this once |
|
|
52
|
+
|---|---|
|
|
53
|
+
| Claude Code | `/plugin marketplace add prajwalgajakesari/agent-sessions` then `/plugin install sessions@agent-sessions`. Repos set up with `init` prompt you automatically. |
|
|
54
|
+
| Codex CLI, OpenCode, Gemini CLI, Cursor, Copilot | `scripts/setup.sh --skills` (or `scripts\setup.ps1 -Skills`) from a checkout. It copies the `agent-sessions` skill into `~/.agents/skills/`, which all of them read. |
|
|
55
|
+
| Any terminal | `pip install agent-sessions-cli` or `uvx agent-sessions-cli`, then `agent-sessions doctor`. |
|
|
56
|
+
|
|
57
|
+
Requirements: git and Python 3.9+ (`python3`, `python`, or the Windows `py` launcher). No Python packages.
|
|
58
|
+
|
|
59
|
+
Then, in each repo you want to share sessions in: `/sessions:init` in Claude Code, or `$agent-sessions init` in Codex, or `agent-sessions init` in a terminal. It fixes a blanket `.claude/` ignore rule so only `.claude/sessions/` and `.claude/settings.json` are tracked, drops a README and `.gitattributes`, registers the Claude plugin in `.claude/settings.json`, and commits exactly those files. Add `--vendor-skill` to also copy the portable skill into `.agents/skills/` so every teammate's agent discovers it on clone.
|
|
60
|
+
|
|
61
|
+
## Using it
|
|
62
|
+
|
|
63
|
+
| Agent | Share this session | Read teammates' sessions |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Claude Code | `/sessions:push [title] [--yes]` | `/sessions:pull [keyword]` |
|
|
66
|
+
| Codex CLI | `$agent-sessions push [title] --yes` | `$agent-sessions pull [keyword]` |
|
|
67
|
+
| OpenCode, Gemini CLI, Cursor, Copilot | "use the agent-sessions skill to push this session" | "use the agent-sessions skill to pull [keyword]" |
|
|
68
|
+
| Terminal | `agent-sessions locate` → write `summary.md` → `export` → `commit --push` | `agent-sessions list` |
|
|
69
|
+
|
|
70
|
+
Push flow, whichever agent runs it:
|
|
71
|
+
|
|
72
|
+
1. `locate` finds this session in the agent's store, checks the repo (ignore rules, detached HEAD, merges in progress, missing upstream) and prints an outline of the conversation.
|
|
73
|
+
2. The agent writes `summary.md` from the template, using the outline plus its own memory, through `write-summary` (agents' file tools tend to refuse `.claude/`).
|
|
74
|
+
3. `export` renders and redacts the transcript, writes `meta.json`, renames the folder to the final title, and prints a redaction report.
|
|
75
|
+
4. You see a short preview and confirm once. `--yes` skips it.
|
|
76
|
+
5. `commit --push` builds the commit on a temporary index inside `.git` and pushes to your current branch. Your staged changes, working tree and any in-progress merge are untouched. `--branch` pushes to a new remote branch instead.
|
|
77
|
+
|
|
78
|
+
Pushing the same session again updates the same folder and keeps everything after the first push.
|
|
79
|
+
|
|
80
|
+
Pull flags: `--n N` how many summaries (default 3), `--full <id>` one full transcript, `--all-branches` sessions on unmerged branches, `--mine` your own.
|
|
81
|
+
|
|
82
|
+
## How the live session is found
|
|
83
|
+
|
|
84
|
+
No agent tells a shell command which session it belongs to, so `locate` never guesses:
|
|
85
|
+
|
|
86
|
+
| Signal | Used by |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `--session-id` passed by the skill | Claude Code (`${CLAUDE_SESSION_ID}` is substituted into the preflight) |
|
|
89
|
+
| Environment variable | Claude Code (`CLAUDE_CODE_SESSION_ID`); Codex if `CODEX_THREAD_ID` reaches child shells |
|
|
90
|
+
| **Self-reference**: the `locate` call itself is the newest shell call in exactly one session and has no output yet | Codex, OpenCode, Claude Code |
|
|
91
|
+
| A push invocation in the latest user turn | any |
|
|
92
|
+
| Exactly one session for this repo | any |
|
|
93
|
+
|
|
94
|
+
If more than one session still matches, `locate` prints `CANDIDATES:` and the skill asks you which one, then re-runs with `--agent` and `--session-id`. Codex fork and compaction stubs are skipped.
|
|
95
|
+
|
|
96
|
+
## Where each agent keeps sessions
|
|
97
|
+
|
|
98
|
+
| Agent | Store | Notes |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| Claude Code | `~/.claude/projects/<encoded-cwd>/<id>.jsonl` (+ `subagents/`) | active path via `parentUuid`, compaction boundaries, subagent edits counted |
|
|
101
|
+
| Codex CLI | `$CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl`, `session_index.jsonl` for titles | `exec` snippets parsed for `exec_command` and `apply_patch`; `compacted` history rendered once; developer messages and environment wrappers dropped |
|
|
102
|
+
| OpenCode | `~/.local/share/opencode/opencode.db` (SQLite, WAL) | opened read-only, copied if locked; `compaction` parts; child sessions feed files touched; tokens and cost from the session row |
|
|
103
|
+
| Gemini CLI | `~/.gemini/tmp/<hash>/chats/session-*.jsonl` | **experimental**: built from the source schema without a real sample; `$set`/`$rewindTo` applied |
|
|
104
|
+
| Copilot CLI, Cursor | detected, not exported | pull and init work; push says so. Cursor's plain-text agent transcripts are the next adapter once a sample exists |
|
|
105
|
+
|
|
106
|
+
## What is and is not redacted
|
|
107
|
+
|
|
108
|
+
| Layer | What it does |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Result policy | Results of file reads, web fetches and MCP tools are replaced by a one-line stub. Other tool output is cut to 30 lines or 2 KB. `--include-results` keeps up to 20 KB per result. |
|
|
111
|
+
| Sensitive files | Any tool call that reads or edits `.env*`, `local.settings.json`, `appsettings*.json`, `secrets.json`, key and certificate files, Terraform state, `.netrc`, `.pypirc`, `.databrickscfg` or anything under `.azure/` has both input and result withheld. |
|
|
112
|
+
| Pattern redaction | AWS keys, GitHub, Slack, OpenAI and Anthropic tokens, JWTs, private keys, credentials in URLs, Azure storage account keys, shared access keys and SAS signatures, Azure DevOps PATs, Entra client secrets, bearer tokens. Keyword hits such as `password=`, `client_secret=`, `-P` after `sqlcmd` are redacted too and listed for you to review. |
|
|
113
|
+
|
|
114
|
+
GUIDs are never redacted. Placeholders like `${DB_PASSWORD}` and `<your-key>` are left alone. If a high-confidence pattern still matches after redaction, export deletes the transcript and refuses. Treat a pushed transcript the way you treat a chat log: read the preview before you say yes.
|
|
115
|
+
|
|
116
|
+
## Sandboxes and permissions
|
|
117
|
+
|
|
118
|
+
Codex's default sandbox blocks network access, so `commit --push` may fail; approve the escalation when Codex offers it, or run the printed `MANUAL` command in your own terminal. The temporary index lives inside `.git`, which stays writable. In OpenCode, allow the skill's script in `opencode.json` permissions to avoid a prompt per step.
|
|
119
|
+
|
|
120
|
+
## Layout of this repo
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
agent_sessions/ the package (stdlib only): cli.py, core.py, model.py, adapters/, templates/
|
|
124
|
+
scripts/sessions.py, sessions.sh entry point + shim (finds Python, always exits 0, prints STATUS)
|
|
125
|
+
scripts/setup.sh, setup.ps1 teammate bootstrap: --claude, --skills, --repo <path>
|
|
126
|
+
skills/{push,pull,init}/ the Claude Code plugin skills
|
|
127
|
+
agents-skills/agent-sessions/ the portable Agent-Skills skill, with a bundled copy of the package
|
|
128
|
+
tools/sync_bundle.py keeps that copy identical (`--check` in CI)
|
|
129
|
+
tests/ python3 -m unittest discover -s tests
|
|
130
|
+
.claude-plugin/ plugin.json (name: sessions) and marketplace.json (name: agent-sessions)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Test the Claude plugin from a checkout with `claude --plugin-dir /path/to/agent-sessions`. Test the portable skill by copying `agents-skills/agent-sessions` into `~/.agents/skills/`.
|
|
134
|
+
|
|
135
|
+
## Contributing an adapter
|
|
136
|
+
|
|
137
|
+
An adapter is one file in `agent_sessions/adapters/` that turns a native store into `Session` events with canonical tool kinds (`shell`, `read`, `edit`, `write`, `search`, `web`, `agent`, `mcp`, `ask`). The renderer, result policy, redaction and files-touched logic never see agent names. Start from `gemini.py` (small) or `codex.py` (complete). A real session sample from your agent, with secrets removed, is the most useful contribution.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
agent_sessions/__init__.py,sha256=ZBlIOF1aJ6SH6KOZXU_pHq97J9AK4729UxBcBXKiaj0,101
|
|
2
|
+
agent_sessions/__main__.py,sha256=iqL5sqaJteojUO-yluSE4moQ3YYJvhp0lJWkXincvCQ,32
|
|
3
|
+
agent_sessions/cli.py,sha256=ySkBiJJwC9Ijl6Su06hQy6Nzb4bgHkLcyR8Jogt1O9A,41456
|
|
4
|
+
agent_sessions/core.py,sha256=pxe_1Cn7pYVSTUYP1M8RZFjGROLw9d7q3toYYd8eR9M,29543
|
|
5
|
+
agent_sessions/model.py,sha256=WgyGmRyJ_JcsYqiR-t0LH7jORgV2TXH8M2Rcko72yEg,4502
|
|
6
|
+
agent_sessions/adapters/__init__.py,sha256=yRdrRfXzb6EJmfvMAEHuN4FuNrpcrcdqQISRbiEB2Hs,4734
|
|
7
|
+
agent_sessions/adapters/base.py,sha256=LFLuEqsY1YYJysP5Mw_sbsWGrO0-irWzBpKbDa7y5PU,3868
|
|
8
|
+
agent_sessions/adapters/claude_code.py,sha256=cFdeX4GGxS-zExjcq4_ByLZy6tltFJChyVXTNClmD5A,13801
|
|
9
|
+
agent_sessions/adapters/codex.py,sha256=aFICqc4dmtypzK4_W7HTKX5cGTqn30Onq8dP9TnJVks,17123
|
|
10
|
+
agent_sessions/adapters/gemini.py,sha256=Tk-TplUD2w-6XSBFFgx3AynDt5rYhA3Rm8sc5koPLas,8753
|
|
11
|
+
agent_sessions/adapters/opencode.py,sha256=aEdSUNtCz9vrdqfPOFgmvrBBgP2C6o6DEGLcVzhbjrI,10900
|
|
12
|
+
agent_sessions/templates/gitattributes,sha256=CqVhUjk5gfSHWcYFxzNC6ljDWHvDjRk0KQT_eD5DKgQ,90
|
|
13
|
+
agent_sessions/templates/sessions-README.md,sha256=iqQsBeH4AbAvwPR41hDHOKMedmYfvPvcqGG11AdXVkQ,2536
|
|
14
|
+
agent_sessions/templates/summary.md,sha256=MgOwZTCR1h1cyXrhEUdWPDMtL7E6TvvdGU8eQQKSu-Q,1041
|
|
15
|
+
agent_sessions_cli-0.2.0.dist-info/METADATA,sha256=i8Vyddks3GotTCqJh7G78OImIawHrFX9HTy7kzQNSfk,10194
|
|
16
|
+
agent_sessions_cli-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
17
|
+
agent_sessions_cli-0.2.0.dist-info/entry_points.txt,sha256=7qbuo2GYN9YI36zyanCrTBxcG8gBHwnFaeL8kduHNlU,60
|
|
18
|
+
agent_sessions_cli-0.2.0.dist-info/licenses/LICENSE,sha256=1Xi4rec797g2CpFmhYBuDCNYb8O8rwLvTm6AttWv8H0,1066
|
|
19
|
+
agent_sessions_cli-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Prajwal P
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|