ideadump 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ideadump-0.0.2/.gitattributes +1 -0
- ideadump-0.0.2/.gitignore +119 -0
- ideadump-0.0.2/LICENSE +21 -0
- ideadump-0.0.2/PKG-INFO +97 -0
- ideadump-0.0.2/README.md +72 -0
- ideadump-0.0.2/ideadump/__init__.py +51 -0
- ideadump-0.0.2/ideadump/__main__.py +73 -0
- ideadump-0.0.2/ideadump/base.py +38 -0
- ideadump-0.0.2/ideadump/data/skills/ideadump/SKILL.md +81 -0
- ideadump-0.0.2/ideadump/render.py +125 -0
- ideadump-0.0.2/ideadump/search.py +99 -0
- ideadump-0.0.2/ideadump/store.py +148 -0
- ideadump-0.0.2/ideadump/sync.py +172 -0
- ideadump-0.0.2/ideadump/tools.py +507 -0
- ideadump-0.0.2/pyproject.toml +186 -0
- ideadump-0.0.2/tests/test_smoke.py +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.ipynb linguist-documentation
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
.claude/handoffs/
|
|
2
|
+
.claude/scratch/
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
.DS_Store
|
|
11
|
+
# C extensions
|
|
12
|
+
*.so
|
|
13
|
+
|
|
14
|
+
# TLS certificates
|
|
15
|
+
## Ignore all PEM files anywhere
|
|
16
|
+
*.pem
|
|
17
|
+
## Also ignore any certs directory
|
|
18
|
+
certs/
|
|
19
|
+
|
|
20
|
+
# Distribution / packaging
|
|
21
|
+
.Python
|
|
22
|
+
build/
|
|
23
|
+
develop-eggs/
|
|
24
|
+
dist/
|
|
25
|
+
downloads/
|
|
26
|
+
eggs/
|
|
27
|
+
.eggs/
|
|
28
|
+
lib/
|
|
29
|
+
lib64/
|
|
30
|
+
parts/
|
|
31
|
+
sdist/
|
|
32
|
+
var/
|
|
33
|
+
wheels/
|
|
34
|
+
*.egg-info/
|
|
35
|
+
.installed.cfg
|
|
36
|
+
*.egg
|
|
37
|
+
MANIFEST
|
|
38
|
+
_build
|
|
39
|
+
|
|
40
|
+
# PyInstaller
|
|
41
|
+
# Usually these files are written by a python script from a template
|
|
42
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
43
|
+
*.manifest
|
|
44
|
+
*.spec
|
|
45
|
+
|
|
46
|
+
# Installer logs
|
|
47
|
+
pip-log.txt
|
|
48
|
+
pip-delete-this-directory.txt
|
|
49
|
+
|
|
50
|
+
# Unit test / coverage reports
|
|
51
|
+
htmlcov/
|
|
52
|
+
.tox/
|
|
53
|
+
.coverage
|
|
54
|
+
.coverage.*
|
|
55
|
+
.cache
|
|
56
|
+
nosetests.xml
|
|
57
|
+
coverage.xml
|
|
58
|
+
*.cover
|
|
59
|
+
.hypothesis/
|
|
60
|
+
.pytest_cache/
|
|
61
|
+
|
|
62
|
+
# Translations
|
|
63
|
+
*.mo
|
|
64
|
+
*.pot
|
|
65
|
+
|
|
66
|
+
# Django stuff:
|
|
67
|
+
*.log
|
|
68
|
+
local_settings.py
|
|
69
|
+
db.sqlite3
|
|
70
|
+
|
|
71
|
+
# Flask stuff:
|
|
72
|
+
instance/
|
|
73
|
+
.webassets-cache
|
|
74
|
+
|
|
75
|
+
# Scrapy stuff:
|
|
76
|
+
.scrapy
|
|
77
|
+
|
|
78
|
+
# Sphinx documentation
|
|
79
|
+
docs/_build/
|
|
80
|
+
|
|
81
|
+
# PyBuilder
|
|
82
|
+
target/
|
|
83
|
+
|
|
84
|
+
# Jupyter Notebook
|
|
85
|
+
.ipynb_checkpoints
|
|
86
|
+
|
|
87
|
+
# pyenv
|
|
88
|
+
.python-version
|
|
89
|
+
|
|
90
|
+
# celery beat schedule file
|
|
91
|
+
celerybeat-schedule
|
|
92
|
+
|
|
93
|
+
# SageMath parsed files
|
|
94
|
+
*.sage.py
|
|
95
|
+
|
|
96
|
+
# Environments
|
|
97
|
+
.env
|
|
98
|
+
.venv
|
|
99
|
+
env/
|
|
100
|
+
venv/
|
|
101
|
+
ENV/
|
|
102
|
+
env.bak/
|
|
103
|
+
venv.bak/
|
|
104
|
+
|
|
105
|
+
# Spyder project settings
|
|
106
|
+
.spyderproject
|
|
107
|
+
.spyproject
|
|
108
|
+
|
|
109
|
+
# Rope project settings
|
|
110
|
+
.ropeproject
|
|
111
|
+
|
|
112
|
+
# mkdocs documentation
|
|
113
|
+
/site
|
|
114
|
+
|
|
115
|
+
# mypy
|
|
116
|
+
.mypy_cache/
|
|
117
|
+
|
|
118
|
+
# PyCharm
|
|
119
|
+
.idea
|
ideadump-0.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 thorwhalen
|
|
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.
|
ideadump-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ideadump
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: A place to dump ideas: capture them in your own words, research them a little, index and relate them, and find them again
|
|
5
|
+
Project-URL: Homepage, https://github.com/thorwhalen/ideadump
|
|
6
|
+
Project-URL: Repository, https://github.com/thorwhalen/ideadump
|
|
7
|
+
Project-URL: Documentation, https://thorwhalen.github.io/ideadump
|
|
8
|
+
Author: Thor Whalen
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent-skills,claude-code,dol,ideas,knowledge-management,notes,research
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Requires-Dist: cw<0.2,>=0.1.1
|
|
14
|
+
Requires-Dist: dol
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
19
|
+
Provides-Extra: docs
|
|
20
|
+
Requires-Dist: sphinx-rtd-theme>=1.0; extra == 'docs'
|
|
21
|
+
Requires-Dist: sphinx>=6.0; extra == 'docs'
|
|
22
|
+
Provides-Extra: git
|
|
23
|
+
Requires-Dist: acquaint>=0.0.18; extra == 'git'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# ideadump
|
|
27
|
+
|
|
28
|
+
A place to dump ideas: capture them in your own words, research them a little, index and relate them, and find them again.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install ideadump
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
You tell an agent an idea in passing; it runs one command to keep it, verbatim, and a light research pass to see what it is called, what already exists and whether it is promising. Later you ask what ideas you have about something, or whether anything you have been working on relates to them.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ideadump add "a place to dump ideas, and do a bit of research on them" --title "Idea dump" --tags "tools, notes" --source my-session
|
|
38
|
+
ideadump note idea-dump --file light-research.md --depth light # attach research notes
|
|
39
|
+
ideadump find "note taking research" # ranked, with the shared words
|
|
40
|
+
ideadump find --file recent-work.md # which ideas relate to this page of recent work?
|
|
41
|
+
ideadump ls --status promising
|
|
42
|
+
ideadump show idea-dump
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Research is done by the agent with whatever search tools it has, so it sends queries (generic terms, not your notes) to outside services; the ideas themselves stay in your store.
|
|
46
|
+
|
|
47
|
+
The primary user is an agent: the package ships a skill, `ideadump`, that tells it when and how to use these verbs (capture, light and deep research, linking, the "is my recent work related to my ideas" pass). See [Agent skill](#agent-skill).
|
|
48
|
+
|
|
49
|
+
## Where ideas live
|
|
50
|
+
|
|
51
|
+
Ideas are kept in a [dol](https://github.com/i2mint/dol) store, a `MutableMapping` of path to text. By default it is a local folder, `~/.local/share/ideadump` (or `$IDEADUMP_DATA_DIR`). Each idea is a folder:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
README.md # the index: newest first, then by tag (generated)
|
|
55
|
+
ideas/2026-11-14-idea-dump/
|
|
56
|
+
idea.json # the record: words (verbatim), title, summary, tags, status, research, links
|
|
57
|
+
README.md # the idea's page (generated)
|
|
58
|
+
research/2026-11-14-light.md # research notes, never overwritten
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The pages are generated from the records on every write, so the folder reads well in a file browser or on GitHub.
|
|
62
|
+
|
|
63
|
+
### Syncing to a private git repository
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install 'ideadump[git]'
|
|
67
|
+
ideadump sync-init you/my-ideas # creates the repository PRIVATE if missing, and makes the data folder its checkout
|
|
68
|
+
ideadump sync # pull, commit everything, push
|
|
69
|
+
ideadump sync-status
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The git work is [acquaint](https://github.com/thorwhalen/acquaint)'s guarded sync: it refuses a repository that is not private, and a pre-push hook re-checks the remote and its visibility on every push. `sync-init` adopts an existing ideas folder (and refuses one that is a checkout of another repository); on a second machine, clone the repository into the data folder first. Generated pages are marked in `.gitattributes` so they never conflict: `sync` rebuilds them from the merged records after each rebase. A private repository is access control, not encryption.
|
|
73
|
+
|
|
74
|
+
## Python
|
|
75
|
+
|
|
76
|
+
Every verb is a plain function returning a JSON-able dict, and takes the store as `files`, so any `MutableMapping` works (a `dict` in tests, another `dol` store elsewhere):
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from ideadump import add, find, note
|
|
80
|
+
|
|
81
|
+
files = {}
|
|
82
|
+
r = add("offline speech to text on the phone", tags="audio", files=files)
|
|
83
|
+
note(r["id"], text="# Prior art\n\nWhisper.cpp, Vosk.", files=files)
|
|
84
|
+
find("speech recognition", files=files)["hits"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`find` ranks with BM25 (standard library); pass `score=` to plug in another scorer, such as a semantic one.
|
|
88
|
+
|
|
89
|
+
## Agent skill
|
|
90
|
+
|
|
91
|
+
The skill lives in the package at `ideadump/data/skills/ideadump/SKILL.md`. For Claude Code, with the package installed, link it into your skills folder:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
ln -s "$(python -c 'import ideadump, pathlib; print(pathlib.Path(ideadump.__file__).parent / "data/skills/ideadump")')" ~/.claude/skills/ideadump
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Then tell any session "idea for later: ..." and it captures it. Other agent hosts read the same file; point yours at that folder (with the `gh skill` extension, `gh skill install thorwhalen/ideadump ideadump`).
|
ideadump-0.0.2/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# ideadump
|
|
2
|
+
|
|
3
|
+
A place to dump ideas: capture them in your own words, research them a little, index and relate them, and find them again.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install ideadump
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
You tell an agent an idea in passing; it runs one command to keep it, verbatim, and a light research pass to see what it is called, what already exists and whether it is promising. Later you ask what ideas you have about something, or whether anything you have been working on relates to them.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
ideadump add "a place to dump ideas, and do a bit of research on them" --title "Idea dump" --tags "tools, notes" --source my-session
|
|
13
|
+
ideadump note idea-dump --file light-research.md --depth light # attach research notes
|
|
14
|
+
ideadump find "note taking research" # ranked, with the shared words
|
|
15
|
+
ideadump find --file recent-work.md # which ideas relate to this page of recent work?
|
|
16
|
+
ideadump ls --status promising
|
|
17
|
+
ideadump show idea-dump
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Research is done by the agent with whatever search tools it has, so it sends queries (generic terms, not your notes) to outside services; the ideas themselves stay in your store.
|
|
21
|
+
|
|
22
|
+
The primary user is an agent: the package ships a skill, `ideadump`, that tells it when and how to use these verbs (capture, light and deep research, linking, the "is my recent work related to my ideas" pass). See [Agent skill](#agent-skill).
|
|
23
|
+
|
|
24
|
+
## Where ideas live
|
|
25
|
+
|
|
26
|
+
Ideas are kept in a [dol](https://github.com/i2mint/dol) store, a `MutableMapping` of path to text. By default it is a local folder, `~/.local/share/ideadump` (or `$IDEADUMP_DATA_DIR`). Each idea is a folder:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
README.md # the index: newest first, then by tag (generated)
|
|
30
|
+
ideas/2026-11-14-idea-dump/
|
|
31
|
+
idea.json # the record: words (verbatim), title, summary, tags, status, research, links
|
|
32
|
+
README.md # the idea's page (generated)
|
|
33
|
+
research/2026-11-14-light.md # research notes, never overwritten
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The pages are generated from the records on every write, so the folder reads well in a file browser or on GitHub.
|
|
37
|
+
|
|
38
|
+
### Syncing to a private git repository
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install 'ideadump[git]'
|
|
42
|
+
ideadump sync-init you/my-ideas # creates the repository PRIVATE if missing, and makes the data folder its checkout
|
|
43
|
+
ideadump sync # pull, commit everything, push
|
|
44
|
+
ideadump sync-status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The git work is [acquaint](https://github.com/thorwhalen/acquaint)'s guarded sync: it refuses a repository that is not private, and a pre-push hook re-checks the remote and its visibility on every push. `sync-init` adopts an existing ideas folder (and refuses one that is a checkout of another repository); on a second machine, clone the repository into the data folder first. Generated pages are marked in `.gitattributes` so they never conflict: `sync` rebuilds them from the merged records after each rebase. A private repository is access control, not encryption.
|
|
48
|
+
|
|
49
|
+
## Python
|
|
50
|
+
|
|
51
|
+
Every verb is a plain function returning a JSON-able dict, and takes the store as `files`, so any `MutableMapping` works (a `dict` in tests, another `dol` store elsewhere):
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from ideadump import add, find, note
|
|
55
|
+
|
|
56
|
+
files = {}
|
|
57
|
+
r = add("offline speech to text on the phone", tags="audio", files=files)
|
|
58
|
+
note(r["id"], text="# Prior art\n\nWhisper.cpp, Vosk.", files=files)
|
|
59
|
+
find("speech recognition", files=files)["hits"]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`find` ranks with BM25 (standard library); pass `score=` to plug in another scorer, such as a semantic one.
|
|
63
|
+
|
|
64
|
+
## Agent skill
|
|
65
|
+
|
|
66
|
+
The skill lives in the package at `ideadump/data/skills/ideadump/SKILL.md`. For Claude Code, with the package installed, link it into your skills folder:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
ln -s "$(python -c 'import ideadump, pathlib; print(pathlib.Path(ideadump.__file__).parent / "data/skills/ideadump")')" ~/.claude/skills/ideadump
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then tell any session "idea for later: ..." and it captures it. Other agent hosts read the same file; point yours at that folder (with the `gh skill` extension, `gh skill install thorwhalen/ideadump ideadump`).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""ideadump: a place to dump ideas, research them a little, and find them again.
|
|
2
|
+
|
|
3
|
+
Capture an idea in the owner's own words, attach research notes (a light pass at
|
|
4
|
+
capture, a deep one when it looks promising), tag and link ideas, and ask which ideas
|
|
5
|
+
relate to a query or to a page describing recent work. Ideas live in a ``dol`` store,
|
|
6
|
+
by default a local folder, optionally a checkout of a private git repository.
|
|
7
|
+
|
|
8
|
+
>>> from ideadump import add, find
|
|
9
|
+
>>> files = {}
|
|
10
|
+
>>> _ = add("Offline speech to text on the phone", tags="audio", files=files)
|
|
11
|
+
>>> find("speech recognition", files=files)["hits"][0]["tags"]
|
|
12
|
+
['audio']
|
|
13
|
+
|
|
14
|
+
The command line (``ideadump --help``) and the agent skill shipped in
|
|
15
|
+
``ideadump/data/skills/ideadump`` drive the same verbs.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from ideadump.base import IdeadumpError
|
|
19
|
+
from ideadump.store import data_dir, text_files
|
|
20
|
+
from ideadump.sync import sync, sync_init, sync_status
|
|
21
|
+
from ideadump.tools import (
|
|
22
|
+
TOOLS,
|
|
23
|
+
add,
|
|
24
|
+
find,
|
|
25
|
+
link,
|
|
26
|
+
ls,
|
|
27
|
+
note,
|
|
28
|
+
reindex,
|
|
29
|
+
show,
|
|
30
|
+
update,
|
|
31
|
+
where,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"IdeadumpError",
|
|
36
|
+
"TOOLS",
|
|
37
|
+
"add",
|
|
38
|
+
"data_dir",
|
|
39
|
+
"find",
|
|
40
|
+
"link",
|
|
41
|
+
"ls",
|
|
42
|
+
"note",
|
|
43
|
+
"reindex",
|
|
44
|
+
"show",
|
|
45
|
+
"sync",
|
|
46
|
+
"sync_init",
|
|
47
|
+
"sync_status",
|
|
48
|
+
"text_files",
|
|
49
|
+
"update",
|
|
50
|
+
"where",
|
|
51
|
+
]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# PYTHON_ARGCOMPLETE_OK
|
|
2
|
+
"""``ideadump`` on the command line: every verb of :data:`ideadump.tools.TOOLS`.
|
|
3
|
+
|
|
4
|
+
ideadump add "the owner's words, verbatim" --title "Short title" --tags "a, b" --source my-session
|
|
5
|
+
ideadump note <id> --file research.md --depth light
|
|
6
|
+
ideadump find "offline speech to text" # or --file recent-work.md
|
|
7
|
+
ideadump ls --status promising
|
|
8
|
+
ideadump show <id>
|
|
9
|
+
ideadump sync
|
|
10
|
+
|
|
11
|
+
``--json`` as the last argument prints the whole result instead of its text. Exit status is 0 on
|
|
12
|
+
success and 1 on an error, whose message says what to do next.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import functools
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
import cw
|
|
22
|
+
|
|
23
|
+
from ideadump import tools
|
|
24
|
+
from ideadump.base import IdeadumpError
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _command(func):
|
|
28
|
+
func = tools.without(func)
|
|
29
|
+
|
|
30
|
+
@functools.wraps(func)
|
|
31
|
+
def command(*args, **kwargs):
|
|
32
|
+
try:
|
|
33
|
+
return func(*args, **kwargs)
|
|
34
|
+
except IdeadumpError as error:
|
|
35
|
+
raise cw.CommandError(str(error)) from error
|
|
36
|
+
|
|
37
|
+
return command
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _egress(as_json):
|
|
41
|
+
def egress(result, *, out, err):
|
|
42
|
+
if as_json or not isinstance(result, dict):
|
|
43
|
+
print(
|
|
44
|
+
json.dumps(result, indent=2, ensure_ascii=False, default=str), file=out
|
|
45
|
+
)
|
|
46
|
+
else:
|
|
47
|
+
print(result.get("text", ""), file=out)
|
|
48
|
+
return 0
|
|
49
|
+
|
|
50
|
+
return egress
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main(argv=None):
|
|
54
|
+
"""Run the command line. The ``ideadump`` console script."""
|
|
55
|
+
for stream in (sys.stdout, sys.stderr):
|
|
56
|
+
getattr(stream, "reconfigure", lambda **_: None)(errors="backslashreplace")
|
|
57
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
58
|
+
as_json = bool(argv) and argv[-1] == "--json"
|
|
59
|
+
if as_json:
|
|
60
|
+
argv = argv[:-1]
|
|
61
|
+
commands = {f.__name__.replace("_", "-"): _command(f) for f in tools.TOOLS}
|
|
62
|
+
code = cw.dispatch(
|
|
63
|
+
commands,
|
|
64
|
+
argv,
|
|
65
|
+
prog="ideadump",
|
|
66
|
+
convention=cw.MODERN,
|
|
67
|
+
egress=_egress(as_json),
|
|
68
|
+
)
|
|
69
|
+
raise SystemExit(code)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Errors and constants shared across ideadump.
|
|
2
|
+
|
|
3
|
+
An idea is one folder in the store, ``ideas/<id>/``, holding its record
|
|
4
|
+
(``idea.json``, the single source of truth), a rendered ``README.md`` that a person
|
|
5
|
+
reads on GitHub or a phone, and its research notes under ``research/``. Nothing here
|
|
6
|
+
depends on any other module.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
APP_NAME = "ideadump"
|
|
12
|
+
DATA_DIR_ENVVAR = "IDEADUMP_DATA_DIR"
|
|
13
|
+
|
|
14
|
+
IDEAS_DIR = "ideas"
|
|
15
|
+
RECORD_FILE = "idea.json"
|
|
16
|
+
README_FILE = "README.md"
|
|
17
|
+
RESEARCH_DIR = "research"
|
|
18
|
+
|
|
19
|
+
#: Where an idea stands. ``new`` on capture; the owner (or an agent relaying the
|
|
20
|
+
#: owner's words) moves it on. ``promising`` is the cue for a deeper research pass.
|
|
21
|
+
STATUSES = ("new", "promising", "parked", "pursued", "dropped")
|
|
22
|
+
|
|
23
|
+
#: How deep a research note went. ``light`` is the pass made at capture (minutes, a
|
|
24
|
+
#: few sources); ``deep`` is a full ``do-research``-style report.
|
|
25
|
+
DEPTHS = ("light", "deep")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class IdeadumpError(Exception):
|
|
29
|
+
"""An error whose message says what to do next."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def record_key(idea_id: str) -> str:
|
|
33
|
+
"""The store key of an idea's record.
|
|
34
|
+
|
|
35
|
+
>>> record_key("2026-11-14-an-idea")
|
|
36
|
+
'ideas/2026-11-14-an-idea/idea.json'
|
|
37
|
+
"""
|
|
38
|
+
return f"{IDEAS_DIR}/{idea_id}/{RECORD_FILE}"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ideadump
|
|
3
|
+
description: Capture an idea the owner tells you, in their own words, research it a little (more if it looks promising), tag and link it, and find it again later, with the ideadump command. Use whenever the owner shares an idea unrelated to the current task or asks you to keep one ("I have an idea", "idea:", "jot this down", "dump this idea", "note this idea for later", "remind me of this idea"), asks about their ideas ("what ideas do I have about X", "list my ideas", "show the idea about Y", "research that idea deeper", "that one is promising", "park that idea"), or asks whether anything they have been working on relates to their ideas ("is any of my recent work related to my ideas", "anything in my ideas worth doing now"), typically during spare token budget. Ideas are stored in a local folder or a private git repository, never in the current project.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
audience: users
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ideadump: a place to dump ideas, and find them again
|
|
10
|
+
|
|
11
|
+
The owner tells you an idea in passing, often in a session that has nothing to do with it, often dictated. Your job: keep it **in their words**, make it findable, give it a first look, and get out of the way. One command captures it; everything else is optional and cheap.
|
|
12
|
+
|
|
13
|
+
**First, is it for the current task?** An idea about the work in front of you ("I have an idea: do X this way") is an instruction: act on it, do not dump it. Dump only ideas meant for later or for something else, or when the owner says to keep it.
|
|
14
|
+
|
|
15
|
+
Ideas live in ideadump's data folder (`ideadump where`), never in the project you are working in. If that folder is a checkout of a private repository, `ideadump sync` pushes; otherwise it is local only, which is fine.
|
|
16
|
+
|
|
17
|
+
## Capture (always)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
ideadump add "<the owner's words, verbatim>" --title "<short title>" --summary "<your clean reading>" --tags "<tag>, <tag>" --source "<this session's name>"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- **Words verbatim**, dictation slips included. Never "fix" them in `words`; put your reading in `--summary`, and when you resolved a slip say so there ("'attic system' read as 'agentic system'"). If a slip changes the meaning and you cannot tell, ask one short question.
|
|
24
|
+
- **Title**: five words or fewer, the thing itself ("Idea dump tool", not "An idea about ideas").
|
|
25
|
+
- **Tags**: two to four, lowercase, reused from existing ones where they fit: `ideadump ls` shows the tags in use. Prefer the domain (`audio`, `fleet`, `writing`) and the kind (`tool`, `essay`, `research-question`, `business`).
|
|
26
|
+
- Then `ideadump find "<title and summary>"` (the new idea is among the hits; ignore its own id): if an earlier idea is the same or close, `ideadump link <id> <other> --why "<one line>"` (or tell the owner it is a duplicate and ask whether to merge).
|
|
27
|
+
- Reply to the owner in two lines at most: the id and title, and that a light look follows (or what it found).
|
|
28
|
+
|
|
29
|
+
**In a session that must keep its context small** (a lookout or switchboard session, or the middle of an unrelated task): run the `add` yourself, then hand the light research to a subagent with the id and these instructions, and carry on with what you were doing.
|
|
30
|
+
|
|
31
|
+
## Light research (at capture, a few minutes)
|
|
32
|
+
|
|
33
|
+
Search with the field's generic terms, not the owner's sentences: their words stay in the store, and outside search services see only queries.
|
|
34
|
+
|
|
35
|
+
Answer four questions, with sources, in a short Markdown note:
|
|
36
|
+
|
|
37
|
+
1. **What is this called?** The standard name for the idea or its field, if there is one.
|
|
38
|
+
2. **What exists already?** Prior art: tools, libraries, papers, products; one line each with a link. If you can search the owner's own packages and skills (in their fleet: `ir discover packages "<two phrasings>"`, `ir discover skills ...`), say what they already have.
|
|
39
|
+
3. **What is the crux?** The one thing that would make it hard, or the one thing that makes it easy.
|
|
40
|
+
4. **Verdict**: `promising`, `worth a deeper look`, `exists already (use X)`, or `park`, with one sentence of why.
|
|
41
|
+
|
|
42
|
+
References Vancouver style (`[1]`, `[2]` with a REFERENCES list, `[name](url)` links). Then:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ideadump note <id> --file <note.md> --depth light
|
|
46
|
+
ideadump update <id> --status promising # only if the verdict says so; parked/dropped likewise
|
|
47
|
+
ideadump sync
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Write the note in a temporary folder, not in the current project.
|
|
51
|
+
|
|
52
|
+
## Deep research (on request, or when the owner agrees an idea is promising)
|
|
53
|
+
|
|
54
|
+
Load the `do-research` skill and run it on the idea at deep depth (its report shape, its Vancouver references). Store the report with `ideadump note <id> --file <report.md> --depth deep`, then `ideadump sync`. The report is as private as the idea. If the owner reads on a phone, give them a link only to a destination that is private and access-controlled (in their fleet, `annals publish`, whose links are private; or the idea's page in the private data repository). Never publish it anywhere public.
|
|
55
|
+
|
|
56
|
+
## Finding ideas
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
ideadump ls # newest first; --tag, --status, --limit
|
|
60
|
+
ideadump show <id or part of it> # the idea's page: words, summary, research, links
|
|
61
|
+
ideadump find "offline speech recognition" # ranked, with the words each hit shares with the query
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The data folder is browsable as it is: `README.md` at its root is the index (newest first, then by tag), and each `ideas/<id>/README.md` is an idea's page, so on GitHub the owner can read it from a phone.
|
|
65
|
+
|
|
66
|
+
## "Is anything I have been working on related to my ideas?"
|
|
67
|
+
|
|
68
|
+
1. Gather a page of text describing recent work into a temporary file: what the owner's sessions did lately (in their fleet: `crowsnest ledger` for the per-session ledgers, `ol` for open loops), recent issue and PR titles, recent commit subjects (`git log --since=7.days --format=%s` in the active repositories). A few hundred lines is fine.
|
|
69
|
+
2. `ideadump find --file <that file> --limit 15`.
|
|
70
|
+
3. The ranking is lexical, so **judge it**: read the top hits' pages (`ideadump show`), keep only those that really relate, and tell the owner, for each, which idea, which work, and the one thing the work could do for the idea (or the idea for the work). Say plainly when nothing relates.
|
|
71
|
+
4. Record a real connection: `ideadump update <id> --add-tags <project>` or a line in a research note.
|
|
72
|
+
|
|
73
|
+
## Other verbs
|
|
74
|
+
|
|
75
|
+
`ideadump update <id> --title/--summary/--tags/--add-tags/--status`, `ideadump link <a> <b> --why ...`, `ideadump reindex` (regenerate the pages), `ideadump sync-status`, `ideadump sync-init <owner>/<name>` (make the data folder a checkout of a private repository, created private if missing; an existing ideas folder is adopted). `--json` as the last argument of any verb prints the full result. Statuses: `new`, `promising`, `parked`, `pursued`, `dropped`.
|
|
76
|
+
|
|
77
|
+
## Never
|
|
78
|
+
|
|
79
|
+
- Never edit `words`; never delete an idea or a note the owner did not ask you to delete.
|
|
80
|
+
- Never put idea text in the current project, an issue, or anywhere public. If ideadump refuses because the data folder is inside another git work tree, tell the owner; never set `IDEADUMP_ALLOW_INSIDE_WORK_TREE` yourself.
|
|
81
|
+
- Never run deep research unasked on every idea: a light look at capture, deeper only on request or agreement.
|