Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ jobs:
- run: npm run build
- run: npm test
- run: npm run smoke
- run: node scripts/mcp-smoke.mjs
98 changes: 59 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Agent Wallclock

**Stop language models from inventing the time.**
**Stop language models from inventing the time — when a fresh Temporal Briefing or MCP tools are attached.**

Agent Wallclock is a small **local** tool. It reads your real clock and a local effort ledger, then produces a **Temporal Briefing**. You feed that briefing into Claude, ChatGPT, Cursor, or any other model — via paste, custom instructions, or MCP tools.

This is not a hosted product and not a chat UI. It is plumbing so *any* model can stop saying “go to sleep” at 9:30am or “you’ve been at this for days” twelve minutes in.
Soft prompt adapters alone do **not** enforce anything. ChatGPT/Claude web only work if you paste a **fresh** briefing. This is not a hosted product and not a chat UI.

---

Expand All @@ -19,11 +19,11 @@ This is not a hosted product and not a chat UI. It is plumbing so *any* model ca
```

1. **CLI / MCP** on your machine measure real time and logged effort.
2. They emit a **Temporal Briefing** (markdown).
2. They emit a **Temporal Briefing** (markdown) with a **Generated at** timestamp.
3. The model only “knows” time if you **give it that briefing** (or it calls MCP `get_briefing`).
4. Host adapters (custom instructions / skills) tell the model: **trust the briefing; never invent durations.**
4. Host adapters tell the model: **trust a fresh briefing; never invent durations; refresh if stale.**

No cloud sync. No account. The model never sees your store unless you paste a briefing or enable local MCP.
No cloud sync. No account. The Wallclock process itself makes no network calls. Pasting a briefing **does** upload that time data to the host.

---

Expand All @@ -34,8 +34,9 @@ git clone https://github.com/TelivityAI/agent-wallclock.git
cd agent-wallclock
npm install && npm run build

# optional alias
alias wallclock='node '"$PWD"'/packages/cli/dist/bin.js'
# put `wallclock` on PATH for this machine
npm link -w @agent-wallclock/cli
# or one-off: npm exec -w @agent-wallclock/cli -- wallclock ...

wallclock init
wallclock effort start auth-rewrite
Expand All @@ -44,35 +45,38 @@ wallclock brief # print
wallclock brief --copy # copy to clipboard when available
```

Example output:
Example output (real CLI shape; durations use `d`/`h`/`m`/`s`):

![Terminal showing wallclock brief](docs/images/01-cli-brief.png)
![Terminal showing wallclock brief (captured from real CLI)](docs/images/01-cli-brief.png)

```markdown
# Temporal Briefing (Agent Wallclock)

## Freshness
- Generated at: 2026-07-31T07:30:22.605Z
- Stale after: 15m — refresh with `wallclock brief` or MCP `get_briefing` before time-based advice

## Now
- Local date: 2026-07-30
- Local time: 09:30:12
- Weekday: Thursday
- Local date: 2026-07-31
- Local time: 02:30:22
- Weekday: Friday
- Timezone: America/Chicago (Central Daylight Time, UTC-05:00)
- ISO (UTC): ...
- ISO (UTC): 2026-07-31T07:30:22.605Z

## Active session
- Status: open
- Age: 12m
- Started: 2026-07-31T07:18:22.580Z
- Age: 12m (720025 ms)

## Active effort
- Name: auth-rewrite
- Calendar age: 3w 2d
- Logged work time: 14h 20m
- Calendar age: 23d
- Logged work time: 14h 20m (includes open session if any)
...
```

That block is the whole product surface. Everything below is **how each host receives it**.

*(Images below are illustrative walkthroughs of the real CLI / host setup flow.)*

---

## ChatGPT — how it gets the data
Expand All @@ -82,16 +86,16 @@ ChatGPT cannot read your disk. You give it two things:
| Piece | What you do |
|-------|-------------|
| Standing rules | Paste [`adapters/chatgpt-custom-instructions.md`](adapters/chatgpt-custom-instructions.md) into **Customize ChatGPT → Custom instructions** |
| Live clock | At the start of a session (or when time matters), paste `wallclock brief` into the chat |
| Live clock | At the start of a session (or when time matters), paste a **fresh** `wallclock brief` into the chat |

![ChatGPT custom instructions + pasted briefing](docs/images/02-chatgpt-setup.png)
![MOCK: ChatGPT custom instructions + pasted briefing (illustrative UI)](docs/images/02-chatgpt-setup.png)

**Checklist**

1. Open ChatGPT → profile → **Customize ChatGPT**.
2. Put the adapter text in custom instructions.
3. Run `wallclock brief --copy` on your machine.
4. Paste into the chat before asking anything time-sensitive.
4. Paste into the chat before asking anything time-sensitive. Refresh if older than ~15 minutes.
5. Ask: “What time is it for me, and how long have I been on auth-rewrite?” — it should quote the briefing, not invent numbers.

---
Expand All @@ -103,19 +107,18 @@ Two paths (pick one or both):
### A) Paste (works everywhere: claude.ai, Projects, API)

1. Add [`adapters/claude-project-instructions.md`](adapters/claude-project-instructions.md) to a **Project**’s instructions (or custom instructions).
2. Paste `wallclock brief` into the chat when you start work.
2. Paste a fresh `wallclock brief` into the chat when you start work.

![Claude chat using a Temporal Briefing](docs/images/03-claude-chat.png)
![MOCK: Claude chat using a Temporal Briefing (illustrative UI)](docs/images/03-claude-chat.png)

### B) MCP (Claude Desktop)

1. `npm install && npm run build` in this repo.
2. Copy [`adapters/mcp/claude-desktop.json`](adapters/mcp/claude-desktop.json) into Claude Desktop MCP config.
3. Replace `/ABSOLUTE/PATH/TO/agent-wallclock` with your clone path.
4. Restart Claude Desktop.
5. Ask Claude to call **`get_briefing`** before time-based advice.
2. Run `wallclock mcp-config --print claude` and merge the JSON into Claude Desktop MCP config (or edit [`adapters/mcp/claude-desktop.json`](adapters/mcp/claude-desktop.json)).
3. Restart Claude Desktop.
4. Ask Claude to call **`get_briefing`** before time-based advice.

Claude then pulls the same local store the CLI uses — still on your machine, still no upload from the Wallclock process itself.
Claude then pulls the same local store the CLI uses — still on your machine. Write tools stay off unless `AGENT_WALLCLOCK_WRITES=1`.

---

Expand All @@ -125,13 +128,13 @@ Three paths (combine freely):

| Path | What |
|------|------|
| Terminal | Agent runs `wallclock brief` (or you paste it) |
| Terminal | Agent runs absolute `node …/packages/cli/dist/bin.js brief` (or you paste). Do not assume `wallclock` is on PATH. |
| Skill / rule | Copy [`adapters/cursor-skill/`](adapters/cursor-skill/) into your skills dir; add the rule fragment from `rule.md` |
| MCP | Add [`adapters/mcp/cursor-mcp.json`](adapters/mcp/cursor-mcp.json), point `args` at `packages/mcp/dist/server.js`, enable the server |
| MCP | Run `wallclock mcp-config --print cursor` (or edit [`adapters/mcp/cursor-mcp.json`](adapters/mcp/cursor-mcp.json)), enable the server |

![Cursor MCP with agent-wallclock tools](docs/images/04-cursor-mcp.png)
![MOCK: Cursor MCP with agent-wallclock tools (illustrative UI)](docs/images/04-cursor-mcp.png)

**MCP tools:** `get_now`, `get_briefing`, `list_efforts`, `start_effort`, `log_session`.
**MCP tools:** `get_now`, `get_briefing`, `list_efforts` (read). `start_effort`, `log_session` require `AGENT_WALLCLOCK_WRITES=1`.

When the skill/rule is on, Cursor should call `get_briefing` (or run the CLI) instead of guessing “it’s late” or “you’ve been grinding for days.”

Expand All @@ -143,7 +146,7 @@ When the skill/rule is on, Cursor should call `get_briefing` (or run the CLI) in
|-------------------|------------------------|
| “It’s late — you should sleep.” (it’s 9:30am) | “Local time is 09:30 Thursday.” |
| “You’ve been at this for days.” (12 minutes) | “This session is 12 minutes old.” |
| “New chat = new project.” | “Effort `auth-rewrite` has 14h logged over ~3 weeks.” |
| “New chat = new project.” | “Effort `auth-rewrite` has 14h 20m logged over ~23 days.” |

---

Expand All @@ -154,11 +157,26 @@ git clone https://github.com/TelivityAI/agent-wallclock.git
cd agent-wallclock
npm install
npm run build

# recommended: link the CLI onto PATH
npm link -w @agent-wallclock/cli
wallclock --help

# one-off without linking
npm exec -w @agent-wallclock/cli -- wallclock --help
# or
node packages/cli/dist/bin.js --help
```

Requirements: Node.js 20+.

Filled MCP config with absolute server path:

```bash
wallclock mcp-config --print cursor
wallclock mcp-config --print claude
```

---

## Commands
Expand All @@ -167,20 +185,22 @@ Requirements: Node.js 20+.
|---------|---------|
| `wallclock now` | Local date, time, timezone, weekday, ISO |
| `wallclock brief` | Full Temporal Briefing (`--copy` when supported) |
| `wallclock effort start\|list\|status\|log` | Named efforts + cumulative time |
| `wallclock effort start\|list\|status\|log` | Named efforts + cumulative time (names are slug-normalized) |
| `wallclock session start\|end` | Open/close a work block on an effort |
| `wallclock timeline` | Recent sessions |
| `wallclock timeline` | Recent sessions (open rows show live age) |
| `wallclock mcp-config --print <claude\|cursor>` | Emit filled MCP JSON |
| `wallclock init` | Create `~/.agent-wallclock/` and point at adapters |

Override store directory: `AGENT_WALLCLOCK_HOME=/path node packages/cli/dist/bin.js ...`
Override store directory: `AGENT_WALLCLOCK_HOME=/path wallclock ...`

---

## Privacy

- State lives only under `~/.agent-wallclock/` (JSON).
- State lives only under `~/.agent-wallclock/` (JSON; directory `0700`, file `0600` when the OS allows).
- CLI and MCP make **no network calls**.
- A model sees time data only if **you** paste a briefing or enable local MCP in that host.
- A model sees time data only if **you** paste a briefing or enable local MCP in that host — pasting **does** send that data to the host cloud.
- MCP mutations default **off** (`AGENT_WALLCLOCK_WRITES=1` to enable).

---

Expand All @@ -193,7 +213,7 @@ Override store directory: `AGENT_WALLCLOCK_HOME=/path node packages/cli/dist/bin
| `packages/mcp` | Local stdio MCP server |
| `adapters/` | Copy-paste instructions per host |
| `catalog/models.md` | Attach points cheat sheet |
| `docs/images/` | Demo screenshots used above |
| `docs/images/` | Demo screenshots (`01` real CLI; `02`–`04` labeled MOCK) |

---

Expand Down
5 changes: 4 additions & 1 deletion adapters/chatgpt-custom-instructions.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
# ChatGPT custom instructions (Agent Wallclock)

Add the block below under **Customize ChatGPT → Custom instructions** (what ChatGPT should know / how it should respond). Before important sessions, paste a fresh `wallclock brief` into the chat.
Add the block below under **Customize ChatGPT → Custom instructions** (what ChatGPT should know / how it should respond). Before important sessions, paste a **fresh** `wallclock brief` into the chat.

---

You have access to Agent Wallclock temporal context when the user pastes a Temporal Briefing or provides equivalent fields.

Rules:
- Trust only that briefing for local time, timezone, session age, and effort logged time.
- Check **Generated at** / **Stale after**. If the briefing is older than its freshness window (default 15 minutes), ask the user to paste a refreshed `wallclock brief` before making time-based claims.
- Never invent time of day or how long the user has been working.
- If duration or clock fields are missing, say unknown — do not guess.
- Do not tell the user to go to sleep or that they have been at something for days/hours unless the briefing supports it.
- A new chat is not a new project if an active effort shows prior logged work.

When no briefing is present, avoid time-based coaching and ask for `wallclock brief` if temporal claims matter.

Privacy note: pasting a briefing uploads that time data to the ChatGPT host.
5 changes: 4 additions & 1 deletion adapters/claude-project-instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Claude Project / custom instructions (Agent Wallclock)

Add this to a Claude Project’s instructions, or to custom instructions / memory for Claude.ai / Claude Desktop. Prefer MCP `get_briefing` when the Agent Wallclock MCP server is configured; otherwise paste `wallclock brief`.
Add this to a Claude Project’s instructions, or to custom instructions / memory for Claude.ai / Claude Desktop. Prefer MCP `get_briefing` when the Agent Wallclock MCP server is configured; otherwise paste a **fresh** `wallclock brief`.

---

Expand All @@ -9,9 +9,12 @@ Add this to a Claude Project’s instructions, or to custom instructions / memor
When a Temporal Briefing is available (pasted or via MCP tools `get_now` / `get_briefing`):

- Use it as the only source for wall-clock time, session age, and effort duration.
- Check **Generated at** / **Stale after**. If older than the freshness window (default 15 minutes), call `get_briefing` again or ask for a refreshed paste before time-based advice.
- Never invent circadian context (“it’s late”, “go to sleep”) against the briefing’s local time.
- Never invent session length (“you’ve been at this for days”) against session age.
- Never treat a fresh thread as zero history when an effort has accumulated logged time.
- Missing fields → say unknown or ask; never guess.

If tools are available, call `get_briefing` before making time-sensitive statements.

Privacy note: pasting a briefing (or using a cloud host with MCP) shares that time data with the host.
18 changes: 11 additions & 7 deletions adapters/cursor-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ description: >-

## Instructions

1. Before making claims about local time, session length, or effort duration, obtain a Temporal Briefing:
1. Before making claims about local time, session length, or effort duration, obtain a **fresh** Temporal Briefing:
- Prefer MCP tool `get_briefing` when the Agent Wallclock MCP server is configured.
- Otherwise run `wallclock brief` in the terminal (or ask the user to paste it).
2. Treat the briefing as authoritative. Do not invent:
- Otherwise ask the user to paste `wallclock brief`, or run the CLI via an absolute path:
`node /ABSOLUTE/PATH/TO/agent-wallclock/packages/cli/dist/bin.js brief`
(or `npm exec -w @agent-wallclock/cli -- wallclock brief` from the clone).
- Do not assume `wallclock` is on PATH.
2. Check **Generated at** / **Stale after**. If older than the freshness window (default 15 minutes), refresh before time-based advice.
3. Treat the briefing as authoritative. Do not invent:
- time of day / “it’s late”
- session age (“hours”, “days”)
- effort history on multi-week work
3. If briefing data is missing, say **unknown** — never guess from priors.
4. Do not advise sleep or “you’ve done enough” based on invented duration.
5. Optional tools: `get_now`, `list_efforts`, `start_effort`, `log_session`.
4. If briefing data is missing, say **unknown** — never guess from priors.
5. Do not advise sleep or “you’ve done enough” based on invented duration.
6. Optional read tools: `get_now`, `list_efforts`. Write tools (`start_effort`, `log_session`) require `AGENT_WALLCLOCK_WRITES=1`.

## Rule fragment (user rules)

```
Temporal context: Use Agent Wallclock. Never invent clock time, session age, or effort duration. Prefer get_briefing / wallclock brief; missing fields are unknown.
Temporal context: Use Agent Wallclock. Never invent clock time, session age, or effort duration. Prefer get_briefing or a fresh wallclock brief; refresh if stale; missing fields are unknown.
```
2 changes: 1 addition & 1 deletion adapters/cursor-skill/rule.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Cursor user rule fragment — Agent Wallclock

Temporal context: Use Agent Wallclock. Never invent clock time, session age, or effort duration. Prefer MCP `get_briefing` or CLI `wallclock brief`. If fields are missing, say unknown. Do not invent sleep/rest advice from guessed time.
Temporal context: Use Agent Wallclock. Never invent clock time, session age, or effort duration. Prefer MCP `get_briefing` or a fresh CLI briefing. Refresh if **Generated at** is outside the freshness window. If fields are missing, say unknown. Do not invent sleep/rest advice from guessed time. Do not assume `wallclock` is on PATH.
13 changes: 7 additions & 6 deletions adapters/generic-system-prompt.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Agent Wallclock — generic system prompt

Paste this into any model’s system prompt or custom instructions. When a Temporal Briefing is present in the conversation (from `wallclock brief` or MCP `get_briefing`), treat it as authoritative.
Paste this into any model’s system prompt or custom instructions. When a Temporal Briefing is present in the conversation (from `wallclock brief` or MCP `get_briefing`), treat it as authoritative **only while fresh**.

## Temporal rules

1. Use the Temporal Briefing for local date, local time, timezone, session age, and effort duration.
2. Never invent the time of day, how long the user has been working in this chat, or how long a project has been underway.
3. If briefing fields are missing, say **unknown** or ask — do not guess from training priors.
4. Do not advise the user to sleep, stop, or “take a break because it is late” unless the briefing’s local time and session/effort data support that claim.
5. Do not equate a new chat with a new project when an active effort shows multi-day or multi-week logged work.
6. Prefer precise durations from the briefing (e.g. “12 minutes”) over vague claims (“hours”, “days”) when numbers are available.
2. Check **Generated at** / **Stale after**. If the briefing is older than its freshness window (default 15 minutes), request a refreshed briefing before time-based claims.
3. Never invent the time of day, how long the user has been working in this chat, or how long a project has been underway.
4. If briefing fields are missing, say **unknown** or ask — do not guess from training priors.
5. Do not advise the user to sleep, stop, or “take a break because it is late” unless the briefing’s local time and session/effort data support that claim.
6. Do not equate a new chat with a new project when an active effort shows multi-day logged work.
7. Prefer precise durations from the briefing (e.g. “12 minutes”) over vague claims (“hours”, “days”) when numbers are available.

## When no briefing is available

Expand Down
12 changes: 10 additions & 2 deletions adapters/mcp/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# MCP configuration

1. Build the repo (`npm install && npm run build`).
2. Copy `claude-desktop.json` or `cursor-mcp.json` into the host MCP config.
3. Replace `/ABSOLUTE/PATH/TO/agent-wallclock` with the real clone path on the machine.
2. Prefer generating a filled config (absolute server path included):

```bash
node packages/cli/dist/bin.js mcp-config --print cursor
node packages/cli/dist/bin.js mcp-config --print claude
```

3. Or copy `claude-desktop.json` / `cursor-mcp.json` and replace `/ABSOLUTE/PATH/TO/agent-wallclock` with your clone path.
4. Restart the host.

**Writes default off.** Read tools (`get_now`, `get_briefing`, `list_efforts`) always work. Mutating tools (`start_effort`, `log_session`) require `AGENT_WALLCLOCK_WRITES=1` in the server `env` block.

Optional: set `AGENT_WALLCLOCK_HOME` in the server `env` block to point at a non-default store directory.

The server is stdio-only and performs no network I/O.
5 changes: 4 additions & 1 deletion adapters/mcp/claude-desktop.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/agent-wallclock/packages/mcp/dist/server.js"
]
],
"env": {
"AGENT_WALLCLOCK_WRITES": "0"
}
}
}
}
5 changes: 4 additions & 1 deletion adapters/mcp/cursor-mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/agent-wallclock/packages/mcp/dist/server.js"
]
],
"env": {
"AGENT_WALLCLOCK_WRITES": "0"
}
}
}
}
Loading
Loading