deptime 0.1.0__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.
- deptime-0.1.0/.claude-plugin/marketplace.json +15 -0
- deptime-0.1.0/.dockerignore +14 -0
- deptime-0.1.0/.env.example +22 -0
- deptime-0.1.0/.github/ISSUE_TEMPLATE/bug-report.yml +29 -0
- deptime-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- deptime-0.1.0/.github/ISSUE_TEMPLATE/package-request.yml +24 -0
- deptime-0.1.0/.github/ISSUE_TEMPLATE/wrong-answer.yml +42 -0
- deptime-0.1.0/.github/pull_request_template.md +11 -0
- deptime-0.1.0/.github/workflows/build-index.yml +168 -0
- deptime-0.1.0/.github/workflows/ci.yml +20 -0
- deptime-0.1.0/.github/workflows/release.yml +35 -0
- deptime-0.1.0/.gitignore +32 -0
- deptime-0.1.0/.python-version +1 -0
- deptime-0.1.0/BACKLOG.md +193 -0
- deptime-0.1.0/CLAUDE.md +62 -0
- deptime-0.1.0/CODE_OF_CONDUCT.md +10 -0
- deptime-0.1.0/CONTRIBUTING.md +48 -0
- deptime-0.1.0/Dockerfile +26 -0
- deptime-0.1.0/LICENSE +21 -0
- deptime-0.1.0/PKG-INFO +128 -0
- deptime-0.1.0/README.md +98 -0
- deptime-0.1.0/SECURITY.md +16 -0
- deptime-0.1.0/bench/README.md +37 -0
- deptime-0.1.0/bench/cases/seed.jsonl +8 -0
- deptime-0.1.0/data/.gitkeep +0 -0
- deptime-0.1.0/docs/03-product-spec.md +163 -0
- deptime-0.1.0/docs/04-architecture.md +104 -0
- deptime-0.1.0/docs/05-hosting-and-sustainability.md +41 -0
- deptime-0.1.0/docs/06-launch-and-adoption.md +62 -0
- deptime-0.1.0/docs/07-risks-and-spikes.md +79 -0
- deptime-0.1.0/docs/08-privacy-and-security.md +67 -0
- deptime-0.1.0/docs/adr/0001-python-single-language-stack.md +18 -0
- deptime-0.1.0/docs/adr/0002-static-analysis-never-import.md +25 -0
- deptime-0.1.0/docs/adr/0003-sqlite-index-with-span-encoding.md +20 -0
- deptime-0.1.0/docs/adr/0005-stateless-mcp-plus-json-api.md +19 -0
- deptime-0.1.0/docs/adr/0006-no-llm-at-serve-time.md +22 -0
- deptime-0.1.0/docs/adr/0007-open-source-local-first.md +36 -0
- deptime-0.1.0/docs/assets/deptime-icon.svg +1 -0
- deptime-0.1.0/docs/assets/deptime-wordmark-dark.svg +1 -0
- deptime-0.1.0/docs/assets/deptime-wordmark-light.svg +1 -0
- deptime-0.1.0/docs/assets/deptime-wordmark-mono.svg +1 -0
- deptime-0.1.0/fly.toml +29 -0
- deptime-0.1.0/integrations/claude-code/.claude-plugin/plugin.json +14 -0
- deptime-0.1.0/integrations/claude-code/.mcp.json +8 -0
- deptime-0.1.0/integrations/claude-code/README.md +39 -0
- deptime-0.1.0/integrations/claude-code/hooks/hooks.json +30 -0
- deptime-0.1.0/integrations/claude-code/scripts/suggest_deptime.py +88 -0
- deptime-0.1.0/integrations/claude-code/skills/deptime/SKILL.md +30 -0
- deptime-0.1.0/integrations/snippets/AGENTS.md +10 -0
- deptime-0.1.0/integrations/snippets/cursor-deptime.mdc +13 -0
- deptime-0.1.0/pyproject.toml +67 -0
- deptime-0.1.0/site/README.md +18 -0
- deptime-0.1.0/src/deptime/__init__.py +3 -0
- deptime-0.1.0/src/deptime/cli.py +284 -0
- deptime-0.1.0/src/deptime/config.py +160 -0
- deptime-0.1.0/src/deptime/coverage.toml +303 -0
- deptime-0.1.0/src/deptime/index/__init__.py +1 -0
- deptime-0.1.0/src/deptime/index/distribution.py +278 -0
- deptime-0.1.0/src/deptime/index/schema.sql +62 -0
- deptime-0.1.0/src/deptime/index/store.py +360 -0
- deptime-0.1.0/src/deptime/ingest/__init__.py +1 -0
- deptime-0.1.0/src/deptime/ingest/diff.py +141 -0
- deptime-0.1.0/src/deptime/ingest/pipeline.py +226 -0
- deptime-0.1.0/src/deptime/ingest/pypi.py +205 -0
- deptime-0.1.0/src/deptime/ingest/replacements.py +95 -0
- deptime-0.1.0/src/deptime/ingest/snapshot.py +277 -0
- deptime-0.1.0/src/deptime/models.py +179 -0
- deptime-0.1.0/src/deptime/query.py +798 -0
- deptime-0.1.0/src/deptime/server/__init__.py +1 -0
- deptime-0.1.0/src/deptime/server/http_app.py +107 -0
- deptime-0.1.0/src/deptime/server/mcp_app.py +154 -0
- deptime-0.1.0/src/deptime/server/metering.py +154 -0
- deptime-0.1.0/src/deptime/tracebacks.py +205 -0
- deptime-0.1.0/tests/__init__.py +0 -0
- deptime-0.1.0/tests/conftest.py +135 -0
- deptime-0.1.0/tests/test_diff.py +79 -0
- deptime-0.1.0/tests/test_distribution.py +123 -0
- deptime-0.1.0/tests/test_network.py +30 -0
- deptime-0.1.0/tests/test_pipeline.py +302 -0
- deptime-0.1.0/tests/test_plugin_hook.py +58 -0
- deptime-0.1.0/tests/test_query.py +296 -0
- deptime-0.1.0/tests/test_replacements.py +70 -0
- deptime-0.1.0/tests/test_server.py +110 -0
- deptime-0.1.0/tests/test_snapshot.py +158 -0
- deptime-0.1.0/tests/test_stdio.py +30 -0
- deptime-0.1.0/tests/test_tracebacks.py +112 -0
- deptime-0.1.0/tests/test_version_policy.py +85 -0
- deptime-0.1.0/uv.lock +887 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deptime",
|
|
3
|
+
"description": "DepTime for Claude Code: tells your agent what changed in a Python library, in which release, and what to use instead.",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "cschmertz",
|
|
6
|
+
"url": "https://github.com/cschmertz"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "deptime",
|
|
11
|
+
"source": "./integrations/claude-code",
|
|
12
|
+
"description": "Explains Python ImportError / AttributeError / TypeError caused by library API changes: what changed, in which release, and what to use instead. Runs locally; your code and errors never leave your machine."
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# DepTime reads configuration from environment variables. Everything is optional.
|
|
2
|
+
|
|
3
|
+
# --- Local mode (deptime mcp / CLI) ---
|
|
4
|
+
# DEPTIME_HOME=~/.cache/deptime # index + build cache (default: $XDG_CACHE_HOME/deptime or ~/.cache/deptime)
|
|
5
|
+
# DEPTIME_INDEX_PATH=~/.cache/deptime/index.sqlite
|
|
6
|
+
# DEPTIME_INDEX_URL=https://github.com/cschmertz/deptime/releases/download/index # where `index pull` downloads from
|
|
7
|
+
# DEPTIME_INDEX_MAX_AGE_HOURS=24 # refresh check interval for a downloaded index
|
|
8
|
+
# DEPTIME_OFFLINE=false # true = never touch the network
|
|
9
|
+
# DEPTIME_COVERAGE_FILE= # custom coverage list (default: the one packaged with deptime)
|
|
10
|
+
|
|
11
|
+
# --- Building the index yourself (deptime ingest) ---
|
|
12
|
+
# DEPTIME_CACHE_DIR=~/.cache/deptime/build # downloaded wheels, extracted sources, snapshot cache
|
|
13
|
+
|
|
14
|
+
# --- Optional hosted mode (deptime serve) ---
|
|
15
|
+
# DEPTIME_HOST=127.0.0.1
|
|
16
|
+
# DEPTIME_PORT=8000
|
|
17
|
+
# DEPTIME_PUBLIC_URL=http://127.0.0.1:8000
|
|
18
|
+
# DEPTIME_TRUST_PROXY_HEADERS=false # true behind Fly/Cloud Run so client IPs come from X-Forwarded-For
|
|
19
|
+
# DEPTIME_TRUSTED_PROXY_HOPS=1 # proxies you run that append to X-Forwarded-For (client = Nth from the right)
|
|
20
|
+
# DEPTIME_CLIENT_IP_HEADER= # e.g. Fly-Client-IP; set only if your platform's proxy always sets it
|
|
21
|
+
# DEPTIME_ANON_DAILY_LIMIT=25 # anonymous calls per IP per day on a public instance
|
|
22
|
+
# DEPTIME_DEV_API_KEYS= # "key1:pro,key2:free" lets trusted callers bypass anonymous limits
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something crashed or misbehaved (install, index download, MCP connection, CLI)
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: repro
|
|
13
|
+
attributes:
|
|
14
|
+
label: Steps to reproduce
|
|
15
|
+
placeholder: "uvx deptime mcp ... / claude mcp add ..."
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: input
|
|
19
|
+
id: env
|
|
20
|
+
attributes:
|
|
21
|
+
label: Environment
|
|
22
|
+
placeholder: "deptime 0.1.0, macOS 15, Python 3.12, Claude Code 2.1.281"
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: logs
|
|
27
|
+
attributes:
|
|
28
|
+
label: Logs (stderr)
|
|
29
|
+
render: text
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Index a package
|
|
2
|
+
description: Ask for a Python package to be added to DepTime's coverage
|
|
3
|
+
title: "[coverage] <package>"
|
|
4
|
+
labels: ["coverage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: input
|
|
7
|
+
id: package
|
|
8
|
+
attributes:
|
|
9
|
+
label: PyPI distribution name
|
|
10
|
+
placeholder: "langchain-anthropic"
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: input
|
|
14
|
+
id: import_names
|
|
15
|
+
attributes:
|
|
16
|
+
label: Import name(s)
|
|
17
|
+
placeholder: "langchain_anthropic"
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: why
|
|
22
|
+
attributes:
|
|
23
|
+
label: Why it changes often enough to need DepTime
|
|
24
|
+
description: Links to breaking-change notes or issues help prioritise.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Wrong answer
|
|
2
|
+
description: DepTime gave a wrong or unhelpful answer (these become benchmark cases)
|
|
3
|
+
title: "[wrong answer] <package>: <symbol>"
|
|
4
|
+
labels: ["wrong-answer"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks! Every report becomes a benchmark case. Please remove secrets and personal paths from the traceback.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: traceback
|
|
12
|
+
attributes:
|
|
13
|
+
label: Traceback (or the call you checked)
|
|
14
|
+
render: text
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: input
|
|
18
|
+
id: versions
|
|
19
|
+
attributes:
|
|
20
|
+
label: Installed versions
|
|
21
|
+
placeholder: "httpx==0.28.1, python 3.12"
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: got
|
|
26
|
+
attributes:
|
|
27
|
+
label: What DepTime returned
|
|
28
|
+
description: Paste the finding (issue, versions, replacements), or the whole JSON.
|
|
29
|
+
render: json
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: expected
|
|
34
|
+
attributes:
|
|
35
|
+
label: What is actually true
|
|
36
|
+
description: Link the changelog, migration guide, or commit if you can.
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: input
|
|
40
|
+
id: index
|
|
41
|
+
attributes:
|
|
42
|
+
label: Output of `deptime index status` (built_at)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## What and why
|
|
2
|
+
|
|
3
|
+
<!-- Backlog ID if any, e.g. DT-CORE-05 -->
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] `uv run ruff format src tests && uv run ruff check src tests && uv run pytest` passes
|
|
8
|
+
- [ ] New behaviour has a test (parser/diff changes: failing test first)
|
|
9
|
+
- [ ] No public field or tool name renamed (additions only)
|
|
10
|
+
- [ ] Nothing prints to stdout in `deptime mcp` code paths
|
|
11
|
+
- [ ] Docs/BACKLOG updated if behaviour or plans changed
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
name: build-index
|
|
2
|
+
|
|
3
|
+
# Nightly: analyse new PyPI releases and publish the prebuilt index to the rolling `index` pre-release.
|
|
4
|
+
# Local installs download <repo>/releases/download/index/{manifest.json,index.sqlite.gz} (see config.DEFAULT_INDEX_URL).
|
|
5
|
+
# Free on public repositories.
|
|
6
|
+
#
|
|
7
|
+
# One job per covered package builds that package's snapshots on its own runner, with its own snapshot cache and
|
|
8
|
+
# log, so a heavy package can only fail itself (DT-DATA-03). The publish job then assembles the index from those
|
|
9
|
+
# snapshots without downloading or analysing anything. It starts from the published index, so a package whose job
|
|
10
|
+
# failed tonight keeps the releases it already had (DT-DATA-12).
|
|
11
|
+
on:
|
|
12
|
+
schedule:
|
|
13
|
+
- cron: "17 4 * * *" # daily at 04:17 UTC
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: build-index
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
DEPTIME_HOME: ${{ github.workspace }}/.deptime
|
|
25
|
+
DEPTIME_OFFLINE: "1" # no background index download or refresh; `ingest` and the explicit `index pull` still run
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
plan:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
outputs:
|
|
31
|
+
packages: ${{ steps.list.outputs.packages }}
|
|
32
|
+
snapshot_format: ${{ steps.list.outputs.snapshot_format }}
|
|
33
|
+
steps:
|
|
34
|
+
# DT-OSS-07: pin actions to commit SHAs.
|
|
35
|
+
- uses: actions/checkout@v5
|
|
36
|
+
- uses: astral-sh/setup-uv@v6
|
|
37
|
+
- name: List the covered packages
|
|
38
|
+
id: list
|
|
39
|
+
run: |
|
|
40
|
+
packages=$(uv run --no-dev python -c 'import json; from deptime.config import Settings, load_coverage; print(json.dumps([p.name for p in load_coverage(Settings.from_env().coverage_file).packages]))')
|
|
41
|
+
echo "packages=$packages" >> "$GITHUB_OUTPUT"
|
|
42
|
+
echo "$packages"
|
|
43
|
+
echo "snapshot_format=$(uv run --no-dev python -c 'from deptime.ingest.snapshot import SNAPSHOT_FORMAT; print(SNAPSHOT_FORMAT)')" >> "$GITHUB_OUTPUT"
|
|
44
|
+
|
|
45
|
+
snapshots:
|
|
46
|
+
name: snapshots (${{ matrix.package }})
|
|
47
|
+
needs: plan
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
timeout-minutes: 350
|
|
50
|
+
strategy:
|
|
51
|
+
fail-fast: false
|
|
52
|
+
matrix:
|
|
53
|
+
package: ${{ fromJSON(needs.plan.outputs.packages) }}
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v5
|
|
56
|
+
- uses: astral-sh/setup-uv@v6
|
|
57
|
+
- run: uv sync --locked --no-dev
|
|
58
|
+
|
|
59
|
+
# `|` can't occur in a package name, so one package's prefix never matches another's (langchain vs langchain-core).
|
|
60
|
+
# The snapshot format is in the key: snapshots from an older extractor would only be rebuilt.
|
|
61
|
+
- name: Restore this package's snapshot cache
|
|
62
|
+
id: restore
|
|
63
|
+
uses: actions/cache/restore@v4
|
|
64
|
+
with:
|
|
65
|
+
path: .deptime/build/snapshots/${{ matrix.package }}
|
|
66
|
+
key: snapshots|${{ needs.plan.outputs.snapshot_format }}|${{ matrix.package }}|latest
|
|
67
|
+
restore-keys: snapshots|${{ needs.plan.outputs.snapshot_format }}|${{ matrix.package }}|
|
|
68
|
+
|
|
69
|
+
- name: Build the snapshots that aren't cached yet
|
|
70
|
+
timeout-minutes: 320
|
|
71
|
+
continue-on-error: true # a timed-out cold build still saves its progress below; the next run carries on
|
|
72
|
+
run: |
|
|
73
|
+
# Memory use every minute, so a runner that dies mid-build still leaves a trace in the log.
|
|
74
|
+
( while sleep 60; do free -m | awk 'NR==2 {print "[memory] " $3 " MB used of " $2}'; done ) &
|
|
75
|
+
trap "kill $!" EXIT
|
|
76
|
+
uv run deptime ingest "${{ matrix.package }}"
|
|
77
|
+
|
|
78
|
+
- name: Resources used
|
|
79
|
+
if: always()
|
|
80
|
+
run: |
|
|
81
|
+
free -m
|
|
82
|
+
df -h .
|
|
83
|
+
du -sh .deptime/build/snapshots 2>/dev/null || true
|
|
84
|
+
|
|
85
|
+
- name: Snapshot cache key
|
|
86
|
+
id: key
|
|
87
|
+
if: always()
|
|
88
|
+
run: echo "key=snapshots|${{ needs.plan.outputs.snapshot_format }}|${{ matrix.package }}|${{ hashFiles(format('.deptime/build/snapshots/{0}/**', matrix.package)) }}" >> "$GITHUB_OUTPUT"
|
|
89
|
+
|
|
90
|
+
- name: Save this package's snapshot cache (also after a timeout; skipped when nothing changed)
|
|
91
|
+
if: always() && !endsWith(steps.key.outputs.key, '|') && steps.key.outputs.key != steps.restore.outputs.cache-matched-key
|
|
92
|
+
uses: actions/cache/save@v4
|
|
93
|
+
with:
|
|
94
|
+
path: .deptime/build/snapshots/${{ matrix.package }}
|
|
95
|
+
key: ${{ steps.key.outputs.key }}
|
|
96
|
+
|
|
97
|
+
- name: Hand the snapshots to the publish job
|
|
98
|
+
if: always()
|
|
99
|
+
uses: actions/upload-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: snapshots-${{ matrix.package }}
|
|
102
|
+
path: .deptime/build/snapshots/
|
|
103
|
+
include-hidden-files: true # the path is under .deptime/
|
|
104
|
+
if-no-files-found: warn
|
|
105
|
+
retention-days: 1
|
|
106
|
+
compression-level: 0 # already gzipped
|
|
107
|
+
|
|
108
|
+
publish:
|
|
109
|
+
needs: [plan, snapshots]
|
|
110
|
+
# Runs even when some package jobs failed: those packages keep their published releases.
|
|
111
|
+
if: ${{ !cancelled() && needs.plan.result == 'success' }}
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
timeout-minutes: 120
|
|
114
|
+
permissions:
|
|
115
|
+
contents: write # upload release assets
|
|
116
|
+
env:
|
|
117
|
+
GH_TOKEN: ${{ github.token }}
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@v5
|
|
120
|
+
- uses: astral-sh/setup-uv@v6
|
|
121
|
+
- run: uv sync --locked --no-dev
|
|
122
|
+
|
|
123
|
+
- name: Collect every package's snapshots
|
|
124
|
+
continue-on-error: true # a package without snapshots keeps its published releases
|
|
125
|
+
uses: actions/download-artifact@v4
|
|
126
|
+
with:
|
|
127
|
+
pattern: snapshots-*
|
|
128
|
+
path: .deptime/build/snapshots
|
|
129
|
+
merge-multiple: true
|
|
130
|
+
|
|
131
|
+
# Ingesting into last night's index keeps a release that has no snapshot tonight (DT-DATA-12).
|
|
132
|
+
# sha256 and schema are checked as for users.
|
|
133
|
+
- name: Start from the published index
|
|
134
|
+
run: uv run deptime index pull || echo "::notice::no compatible published index; building from snapshots only"
|
|
135
|
+
|
|
136
|
+
- name: Assemble the index from the snapshots (never downloads or analyses a release)
|
|
137
|
+
run: |
|
|
138
|
+
uv run deptime ingest --all --into-downloaded --cached-only \
|
|
139
|
+
|| echo "::warning::some releases have no snapshot tonight; see the log above"
|
|
140
|
+
|
|
141
|
+
- name: Resources used
|
|
142
|
+
if: always()
|
|
143
|
+
run: |
|
|
144
|
+
free -m
|
|
145
|
+
df -h .
|
|
146
|
+
du -sh .deptime/build/snapshots .deptime/*.sqlite 2>/dev/null || true
|
|
147
|
+
|
|
148
|
+
- name: Pack
|
|
149
|
+
run: uv run deptime index pack --out dist
|
|
150
|
+
|
|
151
|
+
- name: Guard against publishing a shrunken index
|
|
152
|
+
run: |
|
|
153
|
+
new=$(jq .packages dist/manifest.json)
|
|
154
|
+
if gh release download index --pattern manifest.json --dir prev 2>/dev/null; then
|
|
155
|
+
old=$(jq .packages prev/manifest.json)
|
|
156
|
+
echo "packages: previous=$old new=$new"
|
|
157
|
+
if [ "$new" -lt $(( old * 9 / 10 )) ]; then
|
|
158
|
+
echo "::error::new index has $new packages vs $old published; refusing to publish"
|
|
159
|
+
exit 1
|
|
160
|
+
fi
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
- name: Publish to the rolling `index` release
|
|
164
|
+
run: |
|
|
165
|
+
gh release view index >/dev/null 2>&1 || gh release create index --prerelease \
|
|
166
|
+
--title "DepTime index (rolling)" \
|
|
167
|
+
--notes "Nightly prebuilt index, downloaded automatically by \`deptime mcp\` and \`deptime index pull\`."
|
|
168
|
+
gh release upload index dist/index.sqlite.gz dist/manifest.json --clobber
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
# DT-OSS-07: pin these to commit SHAs.
|
|
15
|
+
- uses: actions/checkout@v5
|
|
16
|
+
- uses: astral-sh/setup-uv@v6
|
|
17
|
+
- run: uv sync --locked
|
|
18
|
+
- run: uv run ruff format --check src tests
|
|
19
|
+
- run: uv run ruff check src tests
|
|
20
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a version tag is pushed (git tag v0.1.0 && git push --tags).
|
|
4
|
+
# One-time setup: on pypi.org, add a "trusted publisher" for this repo + workflow + environment `pypi`.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
pypi:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment: pypi
|
|
16
|
+
permissions:
|
|
17
|
+
id-token: write # PyPI trusted publishing (no API token stored anywhere)
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
- uses: astral-sh/setup-uv@v6
|
|
21
|
+
# A PyPI version can never be reused, so refuse to publish when the tag and the package disagree (audit C-01).
|
|
22
|
+
- name: Check the tag matches the package version
|
|
23
|
+
run: |
|
|
24
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
25
|
+
pyproject="$(uv version --short)"
|
|
26
|
+
init="$(sed -n 's/^__version__ = "\(.*\)"$/\1/p' src/deptime/__init__.py)"
|
|
27
|
+
plugin="$(jq -r .version integrations/claude-code/.claude-plugin/plugin.json)"
|
|
28
|
+
echo "tag=$tag pyproject=$pyproject __init__=$init plugin.json=$plugin"
|
|
29
|
+
if [ "$tag" != "$pyproject" ] || [ "$tag" != "$init" ] || [ "$tag" != "$plugin" ]; then
|
|
30
|
+
echo "::error::tag $GITHUB_REF_NAME does not match the package version"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
- run: uv sync --locked && uv run pytest
|
|
34
|
+
- run: uv build
|
|
35
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
deptime-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
|
|
11
|
+
# DepTime local artifacts
|
|
12
|
+
.cache/
|
|
13
|
+
data/*.sqlite
|
|
14
|
+
data/*.sqlite-*
|
|
15
|
+
data/snapshots/
|
|
16
|
+
!data/.gitkeep
|
|
17
|
+
|
|
18
|
+
# Env / secrets
|
|
19
|
+
.env
|
|
20
|
+
.env.*
|
|
21
|
+
!.env.example
|
|
22
|
+
|
|
23
|
+
# OS / editors
|
|
24
|
+
.DS_Store
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
|
|
28
|
+
# CI / local DepTime home
|
|
29
|
+
.deptime/
|
|
30
|
+
|
|
31
|
+
# Private audit notes (also keeps them out of the Hatch sdist)
|
|
32
|
+
/audit-2026-10-20/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
deptime-0.1.0/BACKLOG.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# DepTime backlog
|
|
2
|
+
|
|
3
|
+
**How to read this**
|
|
4
|
+
- **IDs** look like `DT-<EPIC>-NN` and are referenced from the docs and code. Put the ID in commit messages and PR titles.
|
|
5
|
+
- **Priority:**
|
|
6
|
+
- `P0`: blocks the milestone.
|
|
7
|
+
- `P1`: needed for the milestone's goal.
|
|
8
|
+
- `P2`: nice to have.
|
|
9
|
+
- **Size:** `S` ≤ ½ day · `M` 1–2 days · `L` 3–5 days.
|
|
10
|
+
- **Direction:** free, open source (MIT), local-first ([ADR 0007](docs/adr/0007-open-source-local-first.md)). Success means adoption plus accuracy ([docs/06](docs/06-launch-and-adoption.md)).
|
|
11
|
+
|
|
12
|
+
| Milestone | Window | Exit criterion |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **M0 Spikes** | Days 1–7 | S1 go/no-go (false-absent ≤ 10%); S2–S7 answered |
|
|
15
|
+
| **M1 Local alpha** | Days 7–14 | Public repo; nightly index published; `uvx deptime mcp` works from PyPI; benchmark ≥ 70% |
|
|
16
|
+
| **M2 Public launch** | Days ~14–21 | Registries, plugin, snippets, demo GIF, benchmark post, 5 rename-map pages |
|
|
17
|
+
| **M3 Optional hosted** | When wanted | Public endpoint for web clients and demos, with limits and a privacy notice |
|
|
18
|
+
| **M4 Review** | Days 60 and 90 | Review criteria in [docs/06](docs/06-launch-and-adoption.md) |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Current state: private staging (since 2026-10-18)
|
|
23
|
+
|
|
24
|
+
The repo lives at `github.com/cschmertz/deptime` as **private** while setup and the spikes happen.
|
|
25
|
+
|
|
26
|
+
**Works while private**
|
|
27
|
+
- CI on every push (about 2 Actions minutes per run).
|
|
28
|
+
- All local development: `uv run deptime …`.
|
|
29
|
+
- Building your own index (`deptime ingest`) and running `deptime mcp` against it.
|
|
30
|
+
|
|
31
|
+
**Doesn't work until public**
|
|
32
|
+
- `deptime index pull` and the automatic download: private release assets need auth, so clients get a 404.
|
|
33
|
+
- `uvx deptime` from PyPI.
|
|
34
|
+
- **Note:** publishing to PyPI makes the source public on PyPI, so reserve the name (DT-OSS-03) when you're ready for that.
|
|
35
|
+
|
|
36
|
+
**Suggested order for the next sessions**
|
|
37
|
+
1. **M0 spikes locally**, S1 first since it's the go/no-go. No GitHub needed: `uv run deptime ingest <pkg>`.
|
|
38
|
+
2. *(Optional)* Run `build-index` once by hand (Actions → build-index → Run workflow) to measure the S4 cold-build time. It costs private minutes and creates a private `index` release.
|
|
39
|
+
3. **Go public:**
|
|
40
|
+
1. Flip the visibility.
|
|
41
|
+
2. Enable private vulnerability reporting.
|
|
42
|
+
3. **Uncomment the `schedule:` in `.github/workflows/build-index.yml`.**
|
|
43
|
+
4. Run `build-index`.
|
|
44
|
+
5. Verify `deptime index pull` works on a clean machine (DT-OSS-01, DT-OSS-04).
|
|
45
|
+
4. **PyPI:** add the trusted publisher on pypi.org, then `git tag v0.1.0 && git push --tags` (DT-OSS-03, DT-OSS-05).
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## ✅ Done (2026-10-17)
|
|
50
|
+
|
|
51
|
+
- [x] Problem and prior-art research, specs, architecture, hosting and sustainability, launch, risks, privacy/security docs, and ADRs
|
|
52
|
+
- [x] Ingestion: PEP 691 client, version policy, sha256-verified download, safe extraction, griffe public-path snapshots, diffs, replacement mining, span-encoded SQLite index
|
|
53
|
+
- [x] Resilience: a failed run never wipes an index; a PyPI outage rebuilds from cached snapshots; per-package failure isolation
|
|
54
|
+
- [x] Query layer: 5 tools, confidence semantics, `<=X` deprecations, unindexed-version windows, `never_existed`
|
|
55
|
+
- [x] **Local mode:** `deptime mcp` (stdio); first-run background download + daily refresh check + hot swap; `deptime index pull|status|pack`; offline mode
|
|
56
|
+
- [x] **Index distribution:** `pack` → `manifest.json` + `index.sqlite.gz`; nightly `build-index.yml` publishing to a rolling `index` release, with a shrink guard
|
|
57
|
+
- [x] Hosted mode (optional): `/mcp` (stateless, spec 2026-07-28) + `/v1/*` + anonymous limits
|
|
58
|
+
- [x] OSS hygiene: MIT LICENSE, PyPI metadata, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, issue forms (wrong answer / coverage / bug), PR template, `release.yml` (trusted publishing)
|
|
59
|
+
- [x] Claude Code plugin (stdio `uvx deptime mcp` + skill + hook), validated with `claude plugin validate`
|
|
60
|
+
- [x] 53 offline tests, including a real stdio launch, distribution and pipeline end to end. Verified the built wheel via `uvx` over stdio on real httpx wheels.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## M0 — Spikes
|
|
65
|
+
|
|
66
|
+
Method and pass bars: [docs/07](docs/07-risks-and-spikes.md).
|
|
67
|
+
|
|
68
|
+
- [ ] **DT-SPIKE-01**: S1 static-analysis accuracy on dynamic packages · `P0` `M` · **go/no-go**
|
|
69
|
+
- AC: a false-absent rate measured on 10 packages × 5 versions × 50 runtime-sampled symbols, with the script in `bench/s1/`. Pass at ≤ 10%; otherwise build the sandboxed dynamic fallback and re-measure; stop if it's still above 10%.
|
|
70
|
+
- [ ] **DT-SPIKE-02**: S2 replacement precision on 50 known migrations · `P0` `S`
|
|
71
|
+
- AC: precision ≥ 80% at confidence ≥ 0.75; misses triaged.
|
|
72
|
+
- [ ] **DT-SPIKE-03**: S3 traceback mapping (Python 3.10–3.14, pytest, library-specific exceptions) · `P0` `S`
|
|
73
|
+
- AC: 100 cases at ≥ 90% kind + package accuracy.
|
|
74
|
+
- [ ] **DT-SPIKE-04**: S4 index size, build time, download size · `P0` `S`
|
|
75
|
+
- AC: `.gz` under 100 MB; nightly incremental under 30 min; p95 under 20 ms; cold build fits Actions limits (or a matrix plan).
|
|
76
|
+
- Measured 2026-10-28 (52 packages, 3,371 releases): `.gz` 78.9 MB (773 MB unpacked); cold build 35–61 min as one job per package. Nightly incremental and p95 not measured yet.
|
|
77
|
+
- [ ] **DT-SPIKE-05**: S5 client compatibility matrix (local and hosted) · `P0` `M`
|
|
78
|
+
- AC: Claude Code, Cursor, Codex CLI, VS Code and Claude Desktop with `uvx deptime mcp`; handshake-era clients against hosted mode; the matrix published in the README.
|
|
79
|
+
- [ ] **DT-SPIKE-06**: S6 do agents call it unprompted (plugin vs. no plugin)? · `P1` `M`
|
|
80
|
+
- [ ] **DT-SPIKE-07**: S7 first-run UX on macOS, Linux and Windows · `P1` `S`
|
|
81
|
+
- AC: a useful answer within 60 s of first launch; Windows behaviour documented (feeds OSS-08).
|
|
82
|
+
|
|
83
|
+
## M1 — Local alpha
|
|
84
|
+
|
|
85
|
+
### Open source and release (DT-OSS)
|
|
86
|
+
- [ ] **DT-OSS-01**: Publish the repo as `github.com/cschmertz/deptime` · `P0` `S`
|
|
87
|
+
- AC: public repo; description and topics (`mcp`, `python`, `coding-agents`, `deprecation`); private vulnerability reporting enabled; CI green. (`config.DEFAULT_INDEX_URL` assumes this name.)
|
|
88
|
+
- [ ] **DT-OSS-02**: README proof · `P0` `M` · deps: QA-02, SPIKE-05
|
|
89
|
+
- AC: a 10-second demo GIF (traceback → answer); benchmark table; compatibility matrix; prior-art section.
|
|
90
|
+
- [ ] **DT-OSS-03**: Reserve the name on PyPI · `P0` `S`
|
|
91
|
+
- AC: `deptime` 0.0.x published (also proves the packaging); name reserved.
|
|
92
|
+
- [ ] **DT-OSS-04**: First published index · `P0` `S` · deps: OSS-01, DATA-01
|
|
93
|
+
- AC: `build-index.yml` run manually, then on schedule; `deptime index pull` works from the public URL on a clean machine; release-asset download counts visible.
|
|
94
|
+
- [ ] **DT-OSS-05**: Tagged release through PyPI trusted publishing · `P0` `S` · deps: OSS-03
|
|
95
|
+
- AC: trusted publisher configured; `git tag v0.1.0` publishes; `uvx deptime mcp` works from PyPI.
|
|
96
|
+
- [ ] **DT-OSS-06**: CHANGELOG + versioning policy · `P2` `S`
|
|
97
|
+
- AC: Keep-a-Changelog file; semver for the CLI and tool contract; the index schema version is documented.
|
|
98
|
+
- [ ] **DT-OSS-07**: Supply chain · `P1` `S`
|
|
99
|
+
- AC: GitHub Actions pinned to SHAs; Dependabot for `uv.lock` and actions; `pip-audit` in CI.
|
|
100
|
+
- [ ] **DT-OSS-08**: Windows support for index replace and hot swap · `P1` `S` · deps: SPIKE-07
|
|
101
|
+
- AC: download and refresh succeed while the server holds the old file open (e.g. versioned filenames plus a pointer file).
|
|
102
|
+
- [ ] **DT-OSS-09**: Signed index provenance · `P2` `M`
|
|
103
|
+
- AC: `build-index.yml` produces GitHub artifact attestations; `deptime index pull --verify` checks them; documented in SECURITY.md.
|
|
104
|
+
- [ ] **DT-OSS-10**: A failed first download recovers without a restart (audit D-01) · `P0` `S`
|
|
105
|
+
- AC: an index that appears on disk is opened on the next call (done); the refresh thread retries with backoff while there is no index; the note names the real cause (failed download, offline).
|
|
106
|
+
|
|
107
|
+
### Data (DT-DATA)
|
|
108
|
+
- [ ] **DT-DATA-01**: Index Tier A with the coverage policy · `P0` `M` · deps: SPIKE-01, SPIKE-04
|
|
109
|
+
- AC: ≥ 90% of selected releases indexed for each package; failures listed in the workflow summary.
|
|
110
|
+
- [ ] **DT-DATA-02**: Index Tier B · `P1` `M` · deps: DATA-01
|
|
111
|
+
- AC: same bar as DATA-01; numpy indexed via its `.pyi` stubs; compiled-only gaps noted in `coverage.toml`.
|
|
112
|
+
- Done so far: names numpy's `__init__.py` imports and `__init__.pyi` defines (`add`, `float64`) are indexed for 2.0 and 2.1 too. `numpy.emath.sqrt` is still missing.
|
|
113
|
+
- [x] **DT-DATA-03**: Cold-build strategy for CI · `P1` `S` · deps: SPIKE-04
|
|
114
|
+
- AC: the first full build completes (split into a matrix if needed); the snapshot cache stays within Actions cache limits.
|
|
115
|
+
- Done: one job per package builds and caches its own snapshots, then a publish job assembles the index from them and from the published index; only snapshots stay on disk; a timed-out build still saves its cache. The first full builds (2026-10-28) took 35–61 min with every job green; the slowest is litellm (25 min, 290 releases). The snapshot cache is 2.3 GB of the 10 GB limit, including entries from older snapshot formats that expire unused.
|
|
116
|
+
- [ ] **DT-DATA-04**: Freshness SLO + yanked handling · `P1` `S`
|
|
117
|
+
- AC: a new release is indexed within 24 h (nightly); yanked releases dropped on rebuild; build date shown by `coverage` and `index status`.
|
|
118
|
+
- [ ] **DT-DATA-05**: Lazy-module support (`__getattr__` re-exports) · `P1` `L` · deps: SPIKE-01
|
|
119
|
+
- AC: langchain/transformers false-absent rate below 10%.
|
|
120
|
+
- [ ] **DT-DATA-06**: Stdlib module availability per Python version (typeshed `stdlib/VERSIONS`) · `P1` `S`
|
|
121
|
+
- [ ] **DT-DATA-07**: Cross-package replacement hints (`google.generativeai` → `google.genai`) · `P1` `S`
|
|
122
|
+
- [ ] **DT-DATA-08**: Curated migration map for the top 20 migrations (reviewed; `source="curated"`) · `P1` `M` · deps: SPIKE-02
|
|
123
|
+
- [ ] **DT-DATA-09**: Pydantic model fields treated as `__init__` kwargs · `P2` `M`
|
|
124
|
+
- [x] **DT-DATA-12**: Ingestion never drops an indexed release by accident (audit I-02) · `P0` `S`
|
|
125
|
+
- AC: a failed retry, `--versions` and a PyPI outage keep already-indexed releases (from the snapshot cache, else rebuilt from the index) (done); `ingest` refuses a downloaded index without `--into-downloaded` and marks it locally built only after a rebuild (done). CI still starts each night from an empty index, so carrying releases forward there needs the previous published index as a base (see DT-DATA-03).
|
|
126
|
+
- [ ] **DT-DATA-16**: Store inherited members once per class, then index transformers again · `P1` `M` · deps: SPIKE-04
|
|
127
|
+
- Why: transformers 5.21.0 has ~1.5M public paths, 87% of them inherited methods repeated across ~3,700 model classes (2026-10-28), so it was taken out of `coverage.toml`.
|
|
128
|
+
- AC: snapshots record each class's own members and its bases; queries resolve `Class.member` through the bases; transformers is back in coverage with the `.gz` still under 100 MB.
|
|
129
|
+
- [ ] **DT-DATA-17**: Follow a wrapper release to the distribution that holds its code · `P1` `S`
|
|
130
|
+
- Why: since 3.3.0, `fastmcp` is an empty wheel that pins `fastmcp-slim==<same version>`, so its 31 newest releases have no snapshot (2026-10-28). typer 0.12.0 (`typer-slim`) and pinecone 2.2.2–5.0.1 (`pinecone-client`) have the same shape.
|
|
131
|
+
- AC: when a release has no code for its import names and pins one distribution at the same version, ingest analyses that distribution's artifact and records it as the source file; fastmcp 3.3.0+ is indexed. A pin to a different version (dspy 0.1.5 → `dspy-ai==2.4.5`) is still reported as failed.
|
|
132
|
+
- [ ] **DT-DATA-18**: Snapshot builds keep memory flat across releases · `P2` `S`
|
|
133
|
+
- Why: building litellm's 290 releases in one process grows by ~45 MB per release and never gives it back, peaking at 11.9 GB of a 16 GB runner (2026-10-28). Only cold builds are affected; nightly runs build a few releases.
|
|
134
|
+
- AC: memory after each release returns to a fixed baseline (e.g. clear griffe's caches, or build each release in a subprocess); litellm's cold build stays under 4 GB.
|
|
135
|
+
|
|
136
|
+
### Core logic (DT-CORE)
|
|
137
|
+
- [ ] **DT-CORE-01**: Benchmark-driven tuning of candidate selection and ranking · `P0` `M` · deps: QA-01
|
|
138
|
+
- AC: root-cause accuracy ≥ 80% (M1 floor: 70%).
|
|
139
|
+
- [ ] **DT-CORE-02**: Instance-chain hints for `object_attribute` (prefer frame and referenced-name evidence; show ambiguity) · `P2` `M`
|
|
140
|
+
- [ ] **DT-CORE-03**: Import-name collision disambiguation (`agents`) via installed versions · `P1` `S`
|
|
141
|
+
- [ ] **DT-CORE-04**: Signature-similarity "moved" heuristic (only if S2 shows a gain) · `P2` `M`
|
|
142
|
+
- [ ] **DT-CORE-05**: Library-specific migration exceptions (openai `APIRemovedInV1`, pydantic `PydanticImportError`) · `P1` `S` · deps: SPIKE-03
|
|
143
|
+
- AC: bench cases `openai-v1-chatcompletion` and `pydantic-basesettings-moved` pass.
|
|
144
|
+
- [ ] **DT-CORE-06**: Mine replacement hints from the live error text (e.g. mcp 2.x's FastMCP → MCPServer hint), checked against the index · `P1` `S`
|
|
145
|
+
- [ ] **DT-CORE-07**: `check_symbols` from a code snippet (extract imports and attributes with `ast`) · `P2` `M`
|
|
146
|
+
- [ ] **DT-CORE-08**: Sanitize mined text (control characters, instruction-like content), with adversarial tests · `P0` `S`
|
|
147
|
+
- [ ] **DT-CORE-09**: Positional-argument changes (`too_many_positional` → `param_kind_changed`) · `P2` `S`
|
|
148
|
+
- [x] **DT-CORE-10**: `diff_versions` filters, sorts and counts in SQL, so `truncated` is truthful on large diffs (audit Q-01) · `P0` `S`
|
|
149
|
+
- [x] **DT-CORE-11**: Long tracebacks keep their tail; the MCP input limit is 200K characters (audit Q-02) · `P0` `S`
|
|
150
|
+
- [ ] **DT-CORE-12**: Replacement hints are trustworthy before they reach prose (audit Q-03) · `P0` `M`
|
|
151
|
+
- AC: only hints with confidence ≥ 0.75 appear in `explanation` (done); the generic `use X` pattern only takes identifier-shaped targets; targets are checked against the next indexed snapshot.
|
|
152
|
+
- [x] **DT-CORE-15**: Optional → required parameters: `param_now_required` / `param_now_optional` events, used for "missing required argument" and checked against the installed release (audit I-10, Q-17) · `P0` `S`
|
|
153
|
+
- [ ] **DT-CORE-16**: Errors raised inside a dependency consider the package being called (audit Q-18) · `P0` `S`
|
|
154
|
+
- AC: other indexed packages are searched, installed first, keeping only concrete changes (done; bench case `openai-httpx-proxies-internal`); candidates ranked by `Requires-Dist` once per-release dependency data exists.
|
|
155
|
+
|
|
156
|
+
### Quality (DT-QA)
|
|
157
|
+
- [ ] **DT-QA-01**: 200-traceback benchmark from real GitHub issues (`bench/cases/*.jsonl`) · `P0` `L`
|
|
158
|
+
- [ ] **DT-QA-02**: Benchmark runner + CI report (fail on a regression above 2 points) · `P0` `M` · deps: QA-01
|
|
159
|
+
- [ ] **DT-QA-03**: Golden tests per Tier A package against the published index (nightly, network-marked) · `P1` `M`
|
|
160
|
+
|
|
161
|
+
## M2 — Public launch (DT-GTM)
|
|
162
|
+
|
|
163
|
+
- [ ] **DT-GTM-01**: Generate the 5 rename-map pages from the index (`site/`) · `P0` `M` · deps: DATA-01
|
|
164
|
+
- [ ] **DT-GTM-02**: Landing page (or GitHub Pages) with install, demo, benchmark, privacy · `P1` `S`
|
|
165
|
+
- [ ] **DT-GTM-03**: Registry listings · `P0` `S` · deps: OSS-05
|
|
166
|
+
- AC: official MCP Registry `server.json` (PyPI package, stdio) under `io.github.cschmertz/deptime`; Smithery, Glama, PulseMCP, mcp.so, mcpservers.org, MCP Market; Glama quality score checked.
|
|
167
|
+
- [ ] **DT-GTM-04**: Claude Code plugin release (marketplace) · `P0` `S` · deps: SPIKE-06, OSS-05
|
|
168
|
+
- [ ] **DT-GTM-05**: Cursor rule + AGENTS.md snippet, tested in fresh projects · `P1` `S`
|
|
169
|
+
- [ ] **DT-GTM-06**: Benchmark-led launch post (Show HN, r/Python, r/LangChain, r/ClaudeAI, dev.to) · `P0` `M` · deps: QA-02
|
|
170
|
+
- [ ] **DT-GTM-07**: Outreach: since-cutoff (collaborate or share the backend), Context7, Ref, Tessl · `P1` `S`
|
|
171
|
+
|
|
172
|
+
## M3 — Optional hosted instance (DT-HOST)
|
|
173
|
+
|
|
174
|
+
Options and costs: [docs/05](docs/05-hosting-and-sustainability.md).
|
|
175
|
+
|
|
176
|
+
- [ ] **DT-HOST-01**: Deploy a public instance (Cloud Run free tier or Fly.io) · `P1` `S`
|
|
177
|
+
- AC: `/healthz` green; index downloaded at start-up and persisted (volume or baked into the image); works as a claude.ai custom connector.
|
|
178
|
+
- [ ] **DT-HOST-02**: Public-host hardening · `P0` `S` · before HOST-01 goes public
|
|
179
|
+
- AC: MCP transport allowed hosts and origins; proxy burst limits; body caps confirmed.
|
|
180
|
+
- [ ] **DT-HOST-03**: Persistent rate-limit store (replaces in-memory) · `P2` `S`
|
|
181
|
+
- [ ] **DT-HOST-04**: Privacy notice for the hosted instance ([docs/08](docs/08-privacy-and-security.md)) · `P0` `S` · before HOST-01 goes public
|
|
182
|
+
|
|
183
|
+
## M4 — Review
|
|
184
|
+
|
|
185
|
+
- [ ] **DT-REVIEW-60**: Accuracy ≥ 70%, and ≥ 50 stars or ≥ 100 index downloads/week · `P0`
|
|
186
|
+
- [ ] **DT-REVIEW-90**: Keep investing, or move to maintenance mode ([docs/06](docs/06-launch-and-adoption.md)) · `P0`
|
|
187
|
+
|
|
188
|
+
## Parked
|
|
189
|
+
|
|
190
|
+
- npm/TypeScript ecosystem (Augments covers npm).
|
|
191
|
+
- GitHub Action (checks a PR's dependency bumps against the index).
|
|
192
|
+
- A dataset export or licensing API for docs-context tools.
|
|
193
|
+
- MCP resources: rename maps as prefetchable context.
|