sift-cli 1.0.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.
- sift/__init__.py +18 -0
- sift/answers.py +175 -0
- sift/background.py +444 -0
- sift/capture.py +240 -0
- sift/cli.py +820 -0
- sift/digest.py +101 -0
- sift/distill.py +670 -0
- sift/fallback.py +98 -0
- sift/hook.py +275 -0
- sift/lines.py +37 -0
- sift/many.py +51 -0
- sift/memory.py +94 -0
- sift/model.py +433 -0
- sift/outline.py +117 -0
- sift/peek.py +161 -0
- sift/privacy.py +145 -0
- sift/records.py +95 -0
- sift/server.py +552 -0
- sift/store.py +499 -0
- sift/tools.py +76 -0
- sift/view.py +317 -0
- sift/watch.py +166 -0
- sift_cli-1.0.0.dist-info/METADATA +326 -0
- sift_cli-1.0.0.dist-info/RECORD +27 -0
- sift_cli-1.0.0.dist-info/WHEEL +4 -0
- sift_cli-1.0.0.dist-info/entry_points.txt +3 -0
- sift_cli-1.0.0.dist-info/licenses/LICENSE +21 -0
sift/digest.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""A file someone already has, read for what happened in it.
|
|
2
|
+
|
|
3
|
+
Three questions now go to the same machinery. `distill` asks what mattered in a
|
|
4
|
+
command this tool just ran. `outline` asks what a source file declares. This
|
|
5
|
+
asks the third, and it is the one a caller reaches for most often without
|
|
6
|
+
noticing: *here is a file I did not produce and cannot afford to read whole --
|
|
7
|
+
what is in it?*
|
|
8
|
+
|
|
9
|
+
A build log written by CI last night. A test report attached to an issue. A
|
|
10
|
+
crash dump, a 40,000-line JSON export, the output of something that ran on
|
|
11
|
+
another machine entirely. None of these can be `run` again, and none of them are
|
|
12
|
+
source code, so neither of the first two questions fits.
|
|
13
|
+
|
|
14
|
+
The distinction from `outline` is not the file, it is the question. Asked of a
|
|
15
|
+
log, *what does this declare* returns nothing useful; asked of a Python module,
|
|
16
|
+
*what happened here* returns its imports. The caller knows which they are
|
|
17
|
+
holding, and the command word is where they say so -- exactly as it is for `run`
|
|
18
|
+
and `outline`.
|
|
19
|
+
|
|
20
|
+
What does not change: the file is opened here and its contents never enter the
|
|
21
|
+
conversation, the model answers with line numbers only, and every line shown is
|
|
22
|
+
printed from the file byte for byte. A 40,000-line log costs a screenful, and
|
|
23
|
+
the other 39,900 lines are one `sift peek` away because nothing was touched.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
from sift import lines as text_lines
|
|
31
|
+
from sift import records
|
|
32
|
+
from sift.distill import BUDGET, RECORDS, View, select
|
|
33
|
+
from sift.fallback import from_lines
|
|
34
|
+
from sift.model import Bridge
|
|
35
|
+
from sift.outline import text_of
|
|
36
|
+
|
|
37
|
+
QUESTION = (
|
|
38
|
+
"You are given a file, numbered by line. It is something that was already "
|
|
39
|
+
"produced and saved -- a log, a build or test transcript, a crash dump, a "
|
|
40
|
+
"report, an export -- and it is too long to read whole.\n"
|
|
41
|
+
"Choose the lines someone would need to understand what is in it: what "
|
|
42
|
+
"failed, what warned, what changed, what it concluded, the headings and "
|
|
43
|
+
"boundaries that say where one part ends and the next begins, and the few "
|
|
44
|
+
"lines around those that make them readable.\n"
|
|
45
|
+
"Leave out repetition, progress that only says work happened, and lines that "
|
|
46
|
+
"carry no information on their own.\n"
|
|
47
|
+
"Nothing here is guaranteed to be at the end: a saved file may stop in the "
|
|
48
|
+
"middle of whatever was writing it, so do not assume the last lines are the "
|
|
49
|
+
"conclusion.\n"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def digest(
|
|
54
|
+
path: str | Path,
|
|
55
|
+
bridge: Bridge | None = None,
|
|
56
|
+
budget: int | None = None,
|
|
57
|
+
keep: str | None = None,
|
|
58
|
+
) -> View | None:
|
|
59
|
+
"""What is in `path`, chosen by a model and printed from the file.
|
|
60
|
+
|
|
61
|
+
Handled by the path, like an outline, so the gap marker names the way back
|
|
62
|
+
and `sift peek` takes it unchanged. Returns nothing when there was no usable
|
|
63
|
+
judgement -- the same contract `distill` and `outline` keep, for the same
|
|
64
|
+
reason: a view that pretended to have been chosen would be worse than one
|
|
65
|
+
that admits it was not.
|
|
66
|
+
"""
|
|
67
|
+
text = text_of(path)
|
|
68
|
+
found = records.of(text)
|
|
69
|
+
ceiling = BUDGET if budget is None else budget
|
|
70
|
+
if found is not None:
|
|
71
|
+
return select(
|
|
72
|
+
found,
|
|
73
|
+
RECORDS,
|
|
74
|
+
str(path),
|
|
75
|
+
bridge,
|
|
76
|
+
budget=ceiling,
|
|
77
|
+
keep=keep,
|
|
78
|
+
unit="record",
|
|
79
|
+
)
|
|
80
|
+
return select(
|
|
81
|
+
text_lines.of(text),
|
|
82
|
+
QUESTION,
|
|
83
|
+
str(path),
|
|
84
|
+
bridge,
|
|
85
|
+
budget=ceiling,
|
|
86
|
+
keep=keep,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def ends_of(path: str | Path) -> View:
|
|
91
|
+
"""What to show when nobody could be asked.
|
|
92
|
+
|
|
93
|
+
The beginning of a log says what was being attempted and the end says how it
|
|
94
|
+
came out, which is a better guess here than it is for source code and still
|
|
95
|
+
only a guess. Every line it skips is counted and named.
|
|
96
|
+
"""
|
|
97
|
+
text = text_of(path)
|
|
98
|
+
found = records.of(text)
|
|
99
|
+
if found is not None:
|
|
100
|
+
return from_lines(found, str(path), unit="record")
|
|
101
|
+
return from_lines(text_lines.of(text), str(path))
|