deepcell-cli 0.6.1__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.
- deepcell_cli/__init__.py +12 -0
- deepcell_cli/__main__.py +5 -0
- deepcell_cli/_findings.py +84 -0
- deepcell_cli/capabilities.py +560 -0
- deepcell_cli/capability-contract.json +15622 -0
- deepcell_cli/client.py +503 -0
- deepcell_cli/commands/__init__.py +1 -0
- deepcell_cli/commands/_batch_input.py +29 -0
- deepcell_cli/commands/_datatypes.py +56 -0
- deepcell_cli/commands/_negative_args.py +133 -0
- deepcell_cli/commands/_swapped_args.py +153 -0
- deepcell_cli/commands/_version_display.py +40 -0
- deepcell_cli/commands/_write_opts.py +139 -0
- deepcell_cli/commands/account.py +123 -0
- deepcell_cli/commands/auth.py +610 -0
- deepcell_cli/commands/changes.py +307 -0
- deepcell_cli/commands/deck.py +594 -0
- deepcell_cli/commands/defs.py +3890 -0
- deepcell_cli/commands/describe.py +902 -0
- deepcell_cli/commands/doc.py +529 -0
- deepcell_cli/commands/doctor.py +257 -0
- deepcell_cli/commands/download.py +36 -0
- deepcell_cli/commands/edit.py +384 -0
- deepcell_cli/commands/example.py +161 -0
- deepcell_cli/commands/export.py +81 -0
- deepcell_cli/commands/export_docx.py +57 -0
- deepcell_cli/commands/export_pdf.py +66 -0
- deepcell_cli/commands/export_pptx.py +45 -0
- deepcell_cli/commands/files.py +386 -0
- deepcell_cli/commands/grep.py +90 -0
- deepcell_cli/commands/guide.py +431 -0
- deepcell_cli/commands/help_cmd.py +348 -0
- deepcell_cli/commands/impact.py +382 -0
- deepcell_cli/commands/import_cmd.py +208 -0
- deepcell_cli/commands/ingest.py +110 -0
- deepcell_cli/commands/merge.py +399 -0
- deepcell_cli/commands/query.py +718 -0
- deepcell_cli/commands/reasoning.py +2981 -0
- deepcell_cli/commands/ref.py +279 -0
- deepcell_cli/commands/replace.py +326 -0
- deepcell_cli/commands/rules.py +206 -0
- deepcell_cli/commands/share.py +186 -0
- deepcell_cli/commands/sync.py +804 -0
- deepcell_cli/commands/upgrade.py +185 -0
- deepcell_cli/commands/variant.py +353 -0
- deepcell_cli/commands/version.py +445 -0
- deepcell_cli/commands/viewer.py +54 -0
- deepcell_cli/commands/workspace.py +101 -0
- deepcell_cli/config.py +352 -0
- deepcell_cli/context.py +187 -0
- deepcell_cli/errors.py +141 -0
- deepcell_cli/logging_setup.py +161 -0
- deepcell_cli/main.py +518 -0
- deepcell_cli/mcp_server.py +906 -0
- deepcell_cli/oauth_provider.py +580 -0
- deepcell_cli/output.py +503 -0
- deepcell_cli/revision.py +164 -0
- deepcell_cli/stages.py +223 -0
- deepcell_cli/surface.py +628 -0
- deepcell_cli/sync_state.py +120 -0
- deepcell_cli/upgrade_check.py +399 -0
- deepcell_cli/xml_replace.py +89 -0
- deepcell_cli-0.6.1.dist-info/METADATA +264 -0
- deepcell_cli-0.6.1.dist-info/RECORD +67 -0
- deepcell_cli-0.6.1.dist-info/WHEEL +5 -0
- deepcell_cli-0.6.1.dist-info/entry_points.txt +3 -0
- deepcell_cli-0.6.1.dist-info/top_level.txt +1 -0
deepcell_cli/stages.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""The one authored place a command's stage lives.
|
|
2
|
+
|
|
3
|
+
The root help carried 51 commands in 13 subsystem sections ordered by nothing,
|
|
4
|
+
plus an ``Other`` catch-all that ``docs/cli-help-review.md`` dimension 6
|
|
5
|
+
forbids by name. Three more hand-maintained groupings of the same command set
|
|
6
|
+
existed alongside it — the MCP tool description, ``docs/cli-commands.md``, and
|
|
7
|
+
the generated manifest, which carried no grouping at all — and they disagreed:
|
|
8
|
+
``changes`` was Version Control in one, Sync in another, and uncategorized in
|
|
9
|
+
``--help``. Nothing tested any of them.
|
|
10
|
+
|
|
11
|
+
This module is the fix. A command's stage is declared here once; ``main.py``
|
|
12
|
+
renders the index from it, ``surface.py`` emits it into the manifest, and the
|
|
13
|
+
other catalogs derive rather than restate. :func:`assert_fully_staged` turns an
|
|
14
|
+
unstaged command into a loud failure instead of an ``Other`` row.
|
|
15
|
+
|
|
16
|
+
**The stages are guide's stages**, in guide's order — see
|
|
17
|
+
``backend/src/core/guide/staged.py``. That is the point: an agent that just
|
|
18
|
+
read ``guide generate/calcs`` should already know where ``defs add-calc``
|
|
19
|
+
lives. Two vocabularies for one workflow is the problem this removes.
|
|
20
|
+
|
|
21
|
+
**Three tiers are deliberately not stages.** Signing in, syncing, and looking
|
|
22
|
+
something up are not steps in building a piece of work — they surround it. A
|
|
23
|
+
seventh "stage" for them would be a lie about the shape of the work, so they
|
|
24
|
+
render as collapsed name runs under their own heading instead.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
#: Display order. Not alphabetical — it is the order the work happens in, and
|
|
30
|
+
#: an index listing `generate` after `present` would teach the wrong shape.
|
|
31
|
+
STAGE_ORDER: list[str] = [
|
|
32
|
+
"orient",
|
|
33
|
+
"ingest",
|
|
34
|
+
"generate",
|
|
35
|
+
"revise",
|
|
36
|
+
"verify",
|
|
37
|
+
"present",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
#: One line per stage, shown as the section header. Kept in step with
|
|
41
|
+
#: ``guide``'s own stage summaries — the wording differs only where a command
|
|
42
|
+
#: index needs to say something a topic index does not.
|
|
43
|
+
STAGE_SUMMARY: dict[str, str] = {
|
|
44
|
+
"orient": "look at what exists before adding to it",
|
|
45
|
+
"ingest": "external data in (skip for from-scratch work)",
|
|
46
|
+
"generate": "create one file, then build only the surfaces the work needs",
|
|
47
|
+
"revise": "change a premise and reassess what depends on it",
|
|
48
|
+
"verify": "change one thing, see everything it affects",
|
|
49
|
+
"present": "deliver the work to someone else",
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#: The non-stage tiers, in display order.
|
|
53
|
+
TAIL_ORDER: list[str] = ["session", "sync", "learn"]
|
|
54
|
+
|
|
55
|
+
TAIL_SUMMARY: dict[str, str] = {
|
|
56
|
+
"session": "who you are and where your work lands",
|
|
57
|
+
"sync": "local <-> cloud",
|
|
58
|
+
"learn": "the five reference surfaces",
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#: Every top-level command, and the tier it renders under. A command missing
|
|
62
|
+
#: from this table fails :func:`assert_fully_staged` — which is the whole
|
|
63
|
+
#: reason the table exists, since the old catch-all made "unassigned" invisible.
|
|
64
|
+
#:
|
|
65
|
+
#: Placement notes for the ones that are genuinely arguable:
|
|
66
|
+
#:
|
|
67
|
+
#: * ``cell-meta`` is orient, not verify. It answers "what does this cell rest
|
|
68
|
+
#: on", which is inspection; ``relationships`` answers "what rests on this",
|
|
69
|
+
#: which is the impact question verify owns.
|
|
70
|
+
#: * ``download`` is sync, not present. It moves a file to local disk, which is
|
|
71
|
+
#: what ``clone`` and ``pull`` do; ``share`` and the exports hand work to a
|
|
72
|
+
#: person.
|
|
73
|
+
#: * ``rm`` is revise, not generate. Deleting is a change to existing work.
|
|
74
|
+
COMMAND_TIER: dict[str, str] = {
|
|
75
|
+
# ORIENT — look first.
|
|
76
|
+
"ls": "orient",
|
|
77
|
+
"cat": "orient",
|
|
78
|
+
"describe": "orient",
|
|
79
|
+
"query": "orient",
|
|
80
|
+
"cell-meta": "orient",
|
|
81
|
+
"grep": "orient",
|
|
82
|
+
# INGEST — external data in.
|
|
83
|
+
"import": "ingest",
|
|
84
|
+
"ingest": "ingest",
|
|
85
|
+
# GENERATE — one file, then the surfaces the work needs. The four
|
|
86
|
+
# surfaces of a .deepcell file each have their authoring command here:
|
|
87
|
+
# reasoning (ideas), defs/edit (calculations), doc (documents),
|
|
88
|
+
# deck (slides).
|
|
89
|
+
"write": "generate",
|
|
90
|
+
"reasoning": "generate",
|
|
91
|
+
"defs": "generate",
|
|
92
|
+
"edit": "generate",
|
|
93
|
+
"doc": "generate",
|
|
94
|
+
"deck": "generate",
|
|
95
|
+
# REVISE — change a premise, reassess what depends on it.
|
|
96
|
+
"replace": "revise",
|
|
97
|
+
"variant": "revise",
|
|
98
|
+
"changes": "revise",
|
|
99
|
+
"log": "revise",
|
|
100
|
+
"diff": "revise",
|
|
101
|
+
"restore": "revise",
|
|
102
|
+
"rm": "revise",
|
|
103
|
+
# VERIFY — the connectedness story: change one thing, see what it affects.
|
|
104
|
+
"relationships": "verify",
|
|
105
|
+
"claim": "verify",
|
|
106
|
+
"assumption": "verify",
|
|
107
|
+
"reasoning-diff": "verify",
|
|
108
|
+
# `impact` is the whole of that story in one call. The four above each
|
|
109
|
+
# answer a narrower question and still do; this one is the only one that
|
|
110
|
+
# carries a change through to the Document sections and Deck slides
|
|
111
|
+
# instead of stopping at the reasoning node.
|
|
112
|
+
"impact": "verify",
|
|
113
|
+
# PRESENT — deliver.
|
|
114
|
+
"viewer": "present",
|
|
115
|
+
"share": "present",
|
|
116
|
+
"to-excel": "present",
|
|
117
|
+
"to-docx": "present",
|
|
118
|
+
"to-pptx": "present",
|
|
119
|
+
"to-pdf": "present",
|
|
120
|
+
# SESSION — surrounds the work rather than being a step in it.
|
|
121
|
+
"login": "session",
|
|
122
|
+
"register": "session",
|
|
123
|
+
"logout": "session",
|
|
124
|
+
"whoami": "session",
|
|
125
|
+
"verify-email": "session",
|
|
126
|
+
"account": "session",
|
|
127
|
+
"project": "session",
|
|
128
|
+
"doctor": "session",
|
|
129
|
+
"upgrade": "session",
|
|
130
|
+
# SYNC — local <-> cloud.
|
|
131
|
+
"clone": "sync",
|
|
132
|
+
"status": "sync",
|
|
133
|
+
"pull": "sync",
|
|
134
|
+
"push": "sync",
|
|
135
|
+
"commit": "sync",
|
|
136
|
+
"merge": "sync",
|
|
137
|
+
"download": "sync",
|
|
138
|
+
# LEARN — the five reference surfaces.
|
|
139
|
+
"help": "learn",
|
|
140
|
+
"guide": "learn",
|
|
141
|
+
"rules": "learn",
|
|
142
|
+
"ref": "learn",
|
|
143
|
+
"example": "learn",
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#: Commands whose one-line summary is worth the vertical space in the index,
|
|
147
|
+
#: because a reader choosing between them picks the wrong *tool* otherwise —
|
|
148
|
+
#: ``docs/cli-help-review.md`` dimension 6. Everything else collapses to a name
|
|
149
|
+
#: run, which is what buys the index its one-screen budget back.
|
|
150
|
+
#:
|
|
151
|
+
#: The sets are the sibling groups themselves: inspect-a-file, write-a-value,
|
|
152
|
+
#: and hand-it-over.
|
|
153
|
+
DISAMBIGUATED: frozenset[str] = frozenset(
|
|
154
|
+
{
|
|
155
|
+
"describe",
|
|
156
|
+
"query",
|
|
157
|
+
"grep",
|
|
158
|
+
"cell-meta",
|
|
159
|
+
"edit",
|
|
160
|
+
"defs",
|
|
161
|
+
"replace",
|
|
162
|
+
"write",
|
|
163
|
+
"reasoning",
|
|
164
|
+
"doc",
|
|
165
|
+
"deck",
|
|
166
|
+
"viewer",
|
|
167
|
+
"share",
|
|
168
|
+
"relationships",
|
|
169
|
+
"changes",
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
ALL_TIERS: list[str] = STAGE_ORDER + TAIL_ORDER
|
|
174
|
+
|
|
175
|
+
TIER_SUMMARY: dict[str, str] = {**STAGE_SUMMARY, **TAIL_SUMMARY}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def tier_for(command: str) -> str | None:
|
|
179
|
+
"""The tier ``command`` renders under, or ``None`` if it is unstaged."""
|
|
180
|
+
return COMMAND_TIER.get(command)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def commands_in(tier: str) -> list[str]:
|
|
184
|
+
"""Every command in ``tier``, in declaration order.
|
|
185
|
+
|
|
186
|
+
Declaration order, not alphabetical: within a stage the commands are
|
|
187
|
+
listed in the order the work uses them, so ``write`` precedes the surface
|
|
188
|
+
authoring commands rather than sorting after ``reasoning``.
|
|
189
|
+
"""
|
|
190
|
+
return [name for name, t in COMMAND_TIER.items() if t == tier]
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def assert_fully_staged(command_names: object) -> None:
|
|
194
|
+
"""Raise if any live command has no tier, or any tier names a dead command.
|
|
195
|
+
|
|
196
|
+
Both directions matter. An unstaged command used to fall into an ``Other``
|
|
197
|
+
bucket and nobody noticed for two releases; a stale entry here would keep
|
|
198
|
+
a deleted command in the index just as quietly.
|
|
199
|
+
"""
|
|
200
|
+
live = {str(n) for n in command_names} # type: ignore[union-attr]
|
|
201
|
+
declared = set(COMMAND_TIER)
|
|
202
|
+
|
|
203
|
+
unstaged = sorted(live - declared)
|
|
204
|
+
if unstaged:
|
|
205
|
+
raise AssertionError(
|
|
206
|
+
"Commands with no tier in stages.COMMAND_TIER: "
|
|
207
|
+
f"{', '.join(unstaged)}. Add each to a stage — there is no "
|
|
208
|
+
"catch-all bucket to fall into."
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
stale = sorted(declared - live)
|
|
212
|
+
if stale:
|
|
213
|
+
raise AssertionError(
|
|
214
|
+
"stages.COMMAND_TIER names commands that no longer exist: "
|
|
215
|
+
f"{', '.join(stale)}."
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
bad_tier = sorted(n for n, t in COMMAND_TIER.items() if t not in ALL_TIERS)
|
|
219
|
+
if bad_tier:
|
|
220
|
+
raise AssertionError(
|
|
221
|
+
f"Commands assigned to an unknown tier: {', '.join(bad_tier)}. "
|
|
222
|
+
f"Valid tiers: {', '.join(ALL_TIERS)}."
|
|
223
|
+
)
|