pipulate 2.77__tar.gz → 2.79__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.
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/journal/references/index.md +8 -5
- {pipulate-2.77 → pipulate-2.79}/PKG-INFO +1 -1
- {pipulate-2.77 → pipulate-2.79}/__init__.py +2 -2
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/PKG-INFO +1 -1
- {pipulate-2.77 → pipulate-2.79}/pyproject.toml +1 -1
- {pipulate-2.77 → pipulate-2.79}/tools/scraper_tools.py +28 -5
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/gsc-readonly/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/hello-workflow/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/journal/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/pipulate/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/roles/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/.agents/skills/sheets-readonly/SKILL.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/AGENTS.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/AUDIT.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/LICENSE +0 -0
- {pipulate-2.77 → pipulate-2.79}/MANIFEST.in +0 -0
- {pipulate-2.77 → pipulate-2.79}/README.md +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/010_introduction.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/015_config.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/020_profiles.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/025_aspect.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/030_roles.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/040_hello_workflow.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/050_documentation.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/060_tasks.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/070_history.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/110_parameter_buster.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/120_link_graph.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/130_gap_analysis.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/200_workflow_genesis.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/210_widget_examples.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/220_roadmap.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/230_dev_assistant.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/240_simon_mcp.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/300_blank_placeholder.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/400_botify_trifecta.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/440_browser_automation.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/450_stream_simulator.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/510_text_field.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/520_text_area.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/530_dropdown.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/540_checkboxes.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/550_radios.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/560_range.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/570_switch.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/580_upload.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/610_markdown.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/620_mermaid.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/630_prism.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/640_javascript.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/710_pandas.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/720_rich.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/730_matplotlib.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/810_webbrowser.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/820_selenium.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/apps/830_pico_slider.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/cli.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/config.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/__init__.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/ai_dictdb.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/ai_tool_discovery_simple_parser.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/append_only_conversation.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/ascii_displays.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/botify/__init__.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/botify/code_generators.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/botify/true_schema_discoverer.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/botify_code_generation.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/crud.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/database_safety_wrapper.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/dom_processing/__init__.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/dom_processing/ai_dom_beautifier.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/dom_processing/enhanced_dom_processor.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/durable_backup_system.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/mcp_orchestrator.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/server_logging.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/stream_orchestrator.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/imports/voice_synthesis.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate/__init__.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate/core.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/SOURCES.txt +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/dependency_links.txt +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/entry_points.txt +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/requires.txt +0 -0
- {pipulate-2.77 → pipulate-2.79}/pipulate.egg-info/top_level.txt +0 -0
- {pipulate-2.77 → pipulate-2.79}/server.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/setup.cfg +0 -0
- {pipulate-2.77 → pipulate-2.79}/tests/test_apply_airlock.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tests/test_mck_rep2.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/__init__.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/advanced_automation_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/botify_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/connector_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/conversation_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/dom_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/keychain_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/llm_optics.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/mcp_tools.py +0 -0
- {pipulate-2.77 → pipulate-2.79}/tools/system_tools.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# The Pipulate journal, indexed
|
|
2
2
|
|
|
3
|
-
> Auto-generated on 2026-10-
|
|
3
|
+
> Auto-generated on 2026-10-06 by `scripts/articles/generate_ai_context.py` and
|
|
4
4
|
> rewritten from scratch on every release. If this date looks stale, assume
|
|
5
|
-
> the rest of the repo is newer than this map.
|
|
5
|
+
> the rest of the repo is newer than this map. 1518 entries indexed.
|
|
6
6
|
|
|
7
7
|
This repository holds the *machinery*. The *reasoning*, the running journal
|
|
8
8
|
that explains why every piece exists, lives on a separate website and not in
|
|
@@ -27,6 +27,9 @@ The first 20 entries include full `index.md` URLs to establish
|
|
|
27
27
|
the link pattern. All remaining entries are bare slugs. Reconstruct any full
|
|
28
28
|
URL as: `https://mikelev.in/futureproof/{slug}/index.md`
|
|
29
29
|
|
|
30
|
+
- [2026-10-06] [Declarative Editorial Context: Decoupling Publishing Targets in the AI Era](https://mikelev.in/futureproof/declarative-editorial-framing-pipeline/index.md)
|
|
31
|
+
- [2026-10-04] [The Digital Thunk and Shannon's Codebook: Engineering Replayable Workflows in the Age of AI](https://mikelev.in/futureproof/digital-thunk-shannons-codebook-replayable-workflows/index.md)
|
|
32
|
+
- [2026-10-04] [Learning to Walk: YAML Trails and the Quiet Skip](https://mikelev.in/futureproof/learning-to-walk-yaml-trails-and-the-quiet-skip/index.md)
|
|
30
33
|
- [2026-10-04] [The Terminal House Style: Quieting the Console Without Silencing the Evidence](https://mikelev.in/futureproof/terminal-house-style-quiet-console-evidence/index.md)
|
|
31
34
|
- [2026-10-03] [Mechanical Advantage and the Active Root: Authoritative Prefixes for Replayable AI Pipelines](https://mikelev.in/futureproof/mechanical-advantage-and-the-active-root/index.md)
|
|
32
35
|
- [2026-10-03] [The Single-Owner Rule and the Verifiable Deed: Quieting Pipeline Noise in the Age of AI](https://mikelev.in/futureproof/single-owner-rule-and-verifiable-deeds/index.md)
|
|
@@ -44,14 +47,14 @@ URL as: `https://mikelev.in/futureproof/{slug}/index.md`
|
|
|
44
47
|
- [2026-09-28] [The Forward-Slash Test: Bridging Agent Skills to Claude Code with Verifiable Receipts](https://mikelev.in/futureproof/the-forward-slash-test-claude-skills-bridge/index.md)
|
|
45
48
|
- [2026-09-28] [AGENTS.md and Agent Skills: Refactoring Pipulate for a Checkable PyPI Release](https://mikelev.in/futureproof/agents-md-agent-skills-pypi-receipts/index.md)
|
|
46
49
|
- [2026-09-28] [The Cost of Forgetting: The Epistemic Price List and the Art of the Lean Codebase](https://mikelev.in/futureproof/the-forgetting-kata-and-the-epistemic-price-list/index.md)
|
|
47
|
-
- [2026-09-28] [Pinball, Pachinko, and the Art of Replayable AI Workflows](https://mikelev.in/futureproof/pinball-pachinko-replayable-ai-workflows/index.md)
|
|
48
|
-
- [2026-09-28] [The Three-Folder Boundary: Ergonomic Workspaces and the Blank Stare in the Age of AI](https://mikelev.in/futureproof/three-folder-boundary-and-the-blank-stare/index.md)
|
|
49
|
-
- [2026-09-26] [Closing the Loop: Fixing Patch Parser Failures and Actuator Surprises](https://mikelev.in/futureproof/fixing-patch-parser-failures-and-actuator-surprises/index.md)
|
|
50
50
|
|
|
51
51
|
## Compact slug index -- pattern: https://mikelev.in/futureproof/{slug}/index.md
|
|
52
52
|
|
|
53
53
|
Format: `[date] [size] slug` -- fetch any entry as `https://mikelev.in/futureproof/{slug}/index.md`
|
|
54
54
|
|
|
55
|
+
- [2026-09-28] [24k] pinball-pachinko-replayable-ai-workflows
|
|
56
|
+
- [2026-09-28] [454k] three-folder-boundary-and-the-blank-stare
|
|
57
|
+
- [2026-09-26] [65k] fixing-patch-parser-failures-and-actuator-surprises
|
|
55
58
|
- [2026-09-26] [460k] plain-words-verifiable-ai-context
|
|
56
59
|
- [2026-09-24] [88k] when-the-power-returns-verifiable-git-resync
|
|
57
60
|
- [2026-09-24] [159k] local-chrome-profile-inventory-and-typed-matrix-resolution
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipulate
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.79
|
|
4
4
|
Summary: The context compiler that helps you prompt well -- local-first, Nix-reproducible, replayable. The successor to AI SEO software.
|
|
5
5
|
Author-email: Mike Levin <pipulate@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -12,7 +12,7 @@ Usage:
|
|
|
12
12
|
pipulate
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
__version__ = "2.
|
|
15
|
+
__version__ = "2.79"
|
|
16
16
|
# APOSTROPHES RESTORED (2026-08-04). They were stripped as a workaround for
|
|
17
17
|
# flake.nix's descMatch regex, whose character class excluded ' from the
|
|
18
18
|
# CAPTURE and truncated the banner to "(So)". That regex was fixed in the same
|
|
@@ -23,7 +23,7 @@ __version__ = "2.77"
|
|
|
23
23
|
# is not a property of the system; the regex is. Blast radius is one banner:
|
|
24
24
|
# nothing but flake.nix reads this name -- version_sync.py syncs __version__
|
|
25
25
|
# and __description__, never this. So'wI' chu' -- "engage the cloaking device."
|
|
26
|
-
__version_description__ = "
|
|
26
|
+
__version_description__ = "CVR vs FDR"
|
|
27
27
|
# SPDX expression, single source of truth, synced into pyproject.toml by
|
|
28
28
|
# scripts/release/version_sync.py. "-or-later" (not bare AGPL-3.0, which is
|
|
29
29
|
# deprecated SPDX) because the header below grants "any later version".
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipulate
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.79
|
|
4
4
|
Summary: The context compiler that helps you prompt well -- local-first, Nix-reproducible, replayable. The successor to AI SEO software.
|
|
5
5
|
Author-email: Mike Levin <pipulate@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pipulate"
|
|
7
7
|
# VERSION NOTE: Synced from pipulate/__init__.py.__version__ via python version_sync.py
|
|
8
|
-
version = "2.
|
|
8
|
+
version = "2.79"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name="Mike Levin", email="pipulate@gmail.com" },
|
|
11
11
|
]
|
|
@@ -267,7 +267,12 @@ def _document_candidates(cdp_events: list, domain: str, final_url: str = "") ->
|
|
|
267
267
|
return on_host
|
|
268
268
|
|
|
269
269
|
|
|
270
|
-
def _capture_checkpoint(
|
|
270
|
+
def _capture_checkpoint(
|
|
271
|
+
stdin=None,
|
|
272
|
+
stdout=None,
|
|
273
|
+
before_prompt=None,
|
|
274
|
+
prompt="Press Enter to save the page. ",
|
|
275
|
+
) -> dict:
|
|
271
276
|
"""Wait for Enter from the human's keyboard: the page has settled.
|
|
272
277
|
|
|
273
278
|
ENTER, NOT A WORD (2026-10-02, the operator's ruling). The fence used to
|
|
@@ -328,7 +333,7 @@ def _capture_checkpoint(stdin=None, stdout=None, before_prompt=None) -> dict:
|
|
|
328
333
|
# A CALLER'S HOOK OWNS EVERYTHING BEFORE THE PROMPT (2026-10-02):
|
|
329
334
|
# the default sentences print only when no hook was given, and
|
|
330
335
|
# the prompt itself says what Enter does.
|
|
331
|
-
output_stream.write(
|
|
336
|
+
output_stream.write(prompt)
|
|
332
337
|
output_stream.flush()
|
|
333
338
|
# TYPE-AHEAD IS NOT THE SIGNAL (2026-10-02, read off a walk whose
|
|
334
339
|
# third page printed "Press Enter to save the page. Saved." on one
|
|
@@ -370,7 +375,7 @@ def _capture_checkpoint(stdin=None, stdout=None, before_prompt=None) -> dict:
|
|
|
370
375
|
pass
|
|
371
376
|
|
|
372
377
|
|
|
373
|
-
async def _selenium_capture(params: dict, checkpoint=None) -> dict:
|
|
378
|
+
async def _selenium_capture(params: dict, checkpoint=None, capture_artifacts=True) -> dict:
|
|
374
379
|
"""
|
|
375
380
|
Performs an advanced browser automation scrape of a single URL using undetected-chromedriver.
|
|
376
381
|
Checks for cached data before initiating a new scrape.
|
|
@@ -731,6 +736,16 @@ async def _selenium_capture(params: dict, checkpoint=None) -> dict:
|
|
|
731
736
|
):
|
|
732
737
|
return failure(f"browser final URL is not absolute http(s): {final_url!r}")
|
|
733
738
|
|
|
739
|
+
if interactive and not capture_artifacts:
|
|
740
|
+
return {
|
|
741
|
+
"success": True,
|
|
742
|
+
"looking_at_files": {},
|
|
743
|
+
"cached": False,
|
|
744
|
+
"requested_url": url,
|
|
745
|
+
"final_url": final_url,
|
|
746
|
+
"interactive": True,
|
|
747
|
+
}
|
|
748
|
+
|
|
734
749
|
if interactive:
|
|
735
750
|
final_domain, final_slug = _guided_path_component(final_url)
|
|
736
751
|
output_dir = base_dir / final_domain / final_slug
|
|
@@ -1147,8 +1162,10 @@ async def selenium_automation(params: dict) -> dict:
|
|
|
1147
1162
|
return await _selenium_capture(params)
|
|
1148
1163
|
|
|
1149
1164
|
|
|
1150
|
-
async def guided_browser_capture(
|
|
1151
|
-
|
|
1165
|
+
async def guided_browser_capture(
|
|
1166
|
+
params: dict, stdin=None, stdout=None, before_prompt=None, capture=True
|
|
1167
|
+
) -> dict:
|
|
1168
|
+
"""Guide one visible persistent page; capture artifacts unless capture=False."""
|
|
1152
1169
|
if not isinstance(params, dict):
|
|
1153
1170
|
return {
|
|
1154
1171
|
"success": False,
|
|
@@ -1221,5 +1238,11 @@ async def guided_browser_capture(params: dict, stdin=None, stdout=None, before_p
|
|
|
1221
1238
|
stdin=input_stream,
|
|
1222
1239
|
stdout=stdout,
|
|
1223
1240
|
before_prompt=before_prompt,
|
|
1241
|
+
prompt=(
|
|
1242
|
+
"Press Enter to save the page. "
|
|
1243
|
+
if capture
|
|
1244
|
+
else "Press Enter to continue without saving. "
|
|
1245
|
+
),
|
|
1224
1246
|
),
|
|
1247
|
+
capture_artifacts=capture,
|
|
1225
1248
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|