pipulate 2.65__tar.gz → 2.66__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.
Files changed (98) hide show
  1. pipulate-2.66/.agents/skills/gsc-readonly/SKILL.md +74 -0
  2. pipulate-2.66/.agents/skills/hello-workflow/SKILL.md +116 -0
  3. pipulate-2.66/.agents/skills/journal/SKILL.md +37 -0
  4. pipulate-2.66/.agents/skills/journal/references/index.md +1533 -0
  5. pipulate-2.66/.agents/skills/roles/SKILL.md +178 -0
  6. pipulate-2.66/.agents/skills/sheets-readonly/SKILL.md +40 -0
  7. pipulate-2.66/AGENTS.md +55 -0
  8. pipulate-2.66/AUDIT.md +243 -0
  9. pipulate-2.66/MANIFEST.in +14 -0
  10. {pipulate-2.65/pipulate.egg-info → pipulate-2.66}/PKG-INFO +16 -14
  11. {pipulate-2.65 → pipulate-2.66}/README.md +15 -13
  12. {pipulate-2.65 → pipulate-2.66}/__init__.py +2 -2
  13. {pipulate-2.65 → pipulate-2.66}/apps/040_hello_workflow.py +1 -1
  14. {pipulate-2.65 → pipulate-2.66}/imports/ascii_displays.py +2 -2
  15. {pipulate-2.65 → pipulate-2.66}/pipulate/core.py +15 -2
  16. {pipulate-2.65 → pipulate-2.66/pipulate.egg-info}/PKG-INFO +16 -14
  17. {pipulate-2.65 → pipulate-2.66}/pipulate.egg-info/SOURCES.txt +8 -0
  18. {pipulate-2.65 → pipulate-2.66}/pyproject.toml +1 -2
  19. pipulate-2.65/MANIFEST.in +0 -5
  20. {pipulate-2.65 → pipulate-2.66}/LICENSE +0 -0
  21. {pipulate-2.65 → pipulate-2.66}/apps/010_introduction.py +0 -0
  22. {pipulate-2.65 → pipulate-2.66}/apps/015_config.py +0 -0
  23. {pipulate-2.65 → pipulate-2.66}/apps/020_profiles.py +0 -0
  24. {pipulate-2.65 → pipulate-2.66}/apps/025_aspect.py +0 -0
  25. {pipulate-2.65 → pipulate-2.66}/apps/030_roles.py +0 -0
  26. {pipulate-2.65 → pipulate-2.66}/apps/050_documentation.py +0 -0
  27. {pipulate-2.65 → pipulate-2.66}/apps/060_tasks.py +0 -0
  28. {pipulate-2.65 → pipulate-2.66}/apps/070_history.py +0 -0
  29. {pipulate-2.65 → pipulate-2.66}/apps/110_parameter_buster.py +0 -0
  30. {pipulate-2.65 → pipulate-2.66}/apps/120_link_graph.py +0 -0
  31. {pipulate-2.65 → pipulate-2.66}/apps/130_gap_analysis.py +0 -0
  32. {pipulate-2.65 → pipulate-2.66}/apps/200_workflow_genesis.py +0 -0
  33. {pipulate-2.65 → pipulate-2.66}/apps/210_widget_examples.py +0 -0
  34. {pipulate-2.65 → pipulate-2.66}/apps/220_roadmap.py +0 -0
  35. {pipulate-2.65 → pipulate-2.66}/apps/230_dev_assistant.py +0 -0
  36. {pipulate-2.65 → pipulate-2.66}/apps/240_simon_mcp.py +0 -0
  37. {pipulate-2.65 → pipulate-2.66}/apps/300_blank_placeholder.py +0 -0
  38. {pipulate-2.65 → pipulate-2.66}/apps/400_botify_trifecta.py +0 -0
  39. {pipulate-2.65 → pipulate-2.66}/apps/440_browser_automation.py +0 -0
  40. {pipulate-2.65 → pipulate-2.66}/apps/450_stream_simulator.py +0 -0
  41. {pipulate-2.65 → pipulate-2.66}/apps/510_text_field.py +0 -0
  42. {pipulate-2.65 → pipulate-2.66}/apps/520_text_area.py +0 -0
  43. {pipulate-2.65 → pipulate-2.66}/apps/530_dropdown.py +0 -0
  44. {pipulate-2.65 → pipulate-2.66}/apps/540_checkboxes.py +0 -0
  45. {pipulate-2.65 → pipulate-2.66}/apps/550_radios.py +0 -0
  46. {pipulate-2.65 → pipulate-2.66}/apps/560_range.py +0 -0
  47. {pipulate-2.65 → pipulate-2.66}/apps/570_switch.py +0 -0
  48. {pipulate-2.65 → pipulate-2.66}/apps/580_upload.py +0 -0
  49. {pipulate-2.65 → pipulate-2.66}/apps/610_markdown.py +0 -0
  50. {pipulate-2.65 → pipulate-2.66}/apps/620_mermaid.py +0 -0
  51. {pipulate-2.65 → pipulate-2.66}/apps/630_prism.py +0 -0
  52. {pipulate-2.65 → pipulate-2.66}/apps/640_javascript.py +0 -0
  53. {pipulate-2.65 → pipulate-2.66}/apps/710_pandas.py +0 -0
  54. {pipulate-2.65 → pipulate-2.66}/apps/720_rich.py +0 -0
  55. {pipulate-2.65 → pipulate-2.66}/apps/730_matplotlib.py +0 -0
  56. {pipulate-2.65 → pipulate-2.66}/apps/810_webbrowser.py +0 -0
  57. {pipulate-2.65 → pipulate-2.66}/apps/820_selenium.py +0 -0
  58. {pipulate-2.65 → pipulate-2.66}/apps/830_pico_slider.py +0 -0
  59. {pipulate-2.65 → pipulate-2.66}/cli.py +0 -0
  60. {pipulate-2.65 → pipulate-2.66}/config.py +0 -0
  61. {pipulate-2.65 → pipulate-2.66}/imports/__init__.py +0 -0
  62. {pipulate-2.65 → pipulate-2.66}/imports/ai_dictdb.py +0 -0
  63. {pipulate-2.65 → pipulate-2.66}/imports/ai_tool_discovery_simple_parser.py +0 -0
  64. {pipulate-2.65 → pipulate-2.66}/imports/append_only_conversation.py +0 -0
  65. {pipulate-2.65 → pipulate-2.66}/imports/botify/__init__.py +0 -0
  66. {pipulate-2.65 → pipulate-2.66}/imports/botify/code_generators.py +0 -0
  67. {pipulate-2.65 → pipulate-2.66}/imports/botify/true_schema_discoverer.py +0 -0
  68. {pipulate-2.65 → pipulate-2.66}/imports/botify_code_generation.py +0 -0
  69. {pipulate-2.65 → pipulate-2.66}/imports/crud.py +0 -0
  70. {pipulate-2.65 → pipulate-2.66}/imports/database_safety_wrapper.py +0 -0
  71. {pipulate-2.65 → pipulate-2.66}/imports/dom_processing/__init__.py +0 -0
  72. {pipulate-2.65 → pipulate-2.66}/imports/dom_processing/ai_dom_beautifier.py +0 -0
  73. {pipulate-2.65 → pipulate-2.66}/imports/dom_processing/enhanced_dom_processor.py +0 -0
  74. {pipulate-2.65 → pipulate-2.66}/imports/durable_backup_system.py +0 -0
  75. {pipulate-2.65 → pipulate-2.66}/imports/mcp_orchestrator.py +0 -0
  76. {pipulate-2.65 → pipulate-2.66}/imports/server_logging.py +0 -0
  77. {pipulate-2.65 → pipulate-2.66}/imports/stream_orchestrator.py +0 -0
  78. {pipulate-2.65 → pipulate-2.66}/imports/voice_synthesis.py +0 -0
  79. {pipulate-2.65 → pipulate-2.66}/pipulate/__init__.py +0 -0
  80. {pipulate-2.65 → pipulate-2.66}/pipulate.egg-info/dependency_links.txt +0 -0
  81. {pipulate-2.65 → pipulate-2.66}/pipulate.egg-info/entry_points.txt +0 -0
  82. {pipulate-2.65 → pipulate-2.66}/pipulate.egg-info/requires.txt +0 -0
  83. {pipulate-2.65 → pipulate-2.66}/pipulate.egg-info/top_level.txt +0 -0
  84. {pipulate-2.65 → pipulate-2.66}/server.py +0 -0
  85. {pipulate-2.65 → pipulate-2.66}/setup.cfg +0 -0
  86. {pipulate-2.65 → pipulate-2.66}/tests/test_apply_airlock.py +0 -0
  87. {pipulate-2.65 → pipulate-2.66}/tests/test_mck_rep2.py +0 -0
  88. {pipulate-2.65 → pipulate-2.66}/tools/__init__.py +0 -0
  89. {pipulate-2.65 → pipulate-2.66}/tools/advanced_automation_tools.py +0 -0
  90. {pipulate-2.65 → pipulate-2.66}/tools/botify_tools.py +0 -0
  91. {pipulate-2.65 → pipulate-2.66}/tools/connector_tools.py +0 -0
  92. {pipulate-2.65 → pipulate-2.66}/tools/conversation_tools.py +0 -0
  93. {pipulate-2.65 → pipulate-2.66}/tools/dom_tools.py +0 -0
  94. {pipulate-2.65 → pipulate-2.66}/tools/keychain_tools.py +0 -0
  95. {pipulate-2.65 → pipulate-2.66}/tools/llm_optics.py +0 -0
  96. {pipulate-2.65 → pipulate-2.66}/tools/mcp_tools.py +0 -0
  97. {pipulate-2.65 → pipulate-2.66}/tools/scraper_tools.py +0 -0
  98. {pipulate-2.65 → pipulate-2.66}/tools/system_tools.py +0 -0
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: gsc-readonly
3
+ description: Read-only Google Search Console access through connectors/gsc.py. Use when a task needs GSC data compiled into context, whether that is the properties a service account can see, a capped top-query view of one property, or a bounded raw Search Analytics request. Never widens scope past webmasters.readonly and never opens the credential file.
4
+ ---
5
+
6
+ # GSC Read-Only Connector Guide
7
+
8
+ ## Your Role
9
+
10
+ Use `connectors/gsc.py` as the only executable surface for Google Search Console work. Keep this skill as an instruction layer: do not copy the connector into the skill, reimplement its API calls, or broaden its OAuth scope.
11
+
12
+ ## Safety and Preconditions
13
+
14
+ 1. Run from the Pipulate repository root and confirm `connectors/gsc.py` exists.
15
+ 2. Keep the Google scope at `https://www.googleapis.com/auth/webmasters.readonly`.
16
+ 3. Treat the service-account file as opaque. Never open, print, quote, upload, summarize, or embed its JSON, private key, tokens, or other credential values.
17
+ 4. Refer only to the credential-routing names and paths:
18
+ - `PIPULATE_GSC_KEY`
19
+ - `~/.config/pipulate/connectors.json` at `gsc.paths.service_account`
20
+ - `~/.config/pipulate/service-account-key.json`
21
+ 5. Do not claim the wallet contains secrets. It records routing metadata; secret material lives in the referenced environment or credential file.
22
+
23
+ ## Choose the Connector Mode
24
+
25
+ Use the connector's existing argument disambiguation. An argument beginning with `{` or containing whitespace is FETCH mode. Any other bare token is a property coordinate. No argument lists properties.
26
+
27
+ ### List visible properties
28
+
29
+ ```bash
30
+ python connectors/gsc.py
31
+ ```
32
+
33
+ Use this to discover property coordinates available to the configured service account. The default output cap is 25.
34
+
35
+ ### List bounded top queries for one property
36
+
37
+ ```bash
38
+ python connectors/gsc.py sc-domain:example.com
39
+ ```
40
+
41
+ Treat this as a bounded top-query view, not a complete export. Keep the default cap of 25 unless the user explicitly needs a different small bound.
42
+
43
+ ### Run a bounded raw Search Analytics request
44
+
45
+ ```bash
46
+ python connectors/gsc.py \
47
+ '{"startDate":"2026-06-01","endDate":"2026-06-28","dimensions":["page","query"]}' \
48
+ --site sc-domain:example.com
49
+ ```
50
+
51
+ `--site` may be omitted only when `PIPULATE_GSC_SITE` is already set. The connector applies `rowLimit` when absent and slices returned rows to `-n/--max`.
52
+
53
+ ### Change the cap deliberately
54
+
55
+ ```bash
56
+ python connectors/gsc.py -n 10 sc-domain:example.com
57
+ ```
58
+
59
+ Keep outputs small because stdout may be compiled into Prompt Fu context. Never describe the result as exhaustive or guaranteed complete; call it bounded Search Analytics rows or a capped top-query view.
60
+
61
+ ## Compile-Lane Privacy
62
+
63
+ Property-list output contains domains and can reveal client identities. Before placing a `! python connectors/gsc.py ...` command in `adhoc.txt` or sending its captured output to a cloud model, confirm `pii_substitutions.txt` covers every real client identifier. Redact or omit sensitive coordinates when that coverage is uncertain.
64
+
65
+ ## Failure Handling
66
+
67
+ - When FETCH mode lacks a property coordinate, request `--site` or `PIPULATE_GSC_SITE`.
68
+ - When credential routing fails, report the missing routing name or path without inspecting the service-account JSON.
69
+ - When Google returns an API error, report the bounded error context and preserve read-only scope.
70
+ - Do not patch `connectors/gsc.py` merely to work around missing configuration; fix routing metadata or the local credential file outside the repository.
71
+
72
+ ## Reporting Results
73
+
74
+ State the mode, property coordinate when applicable, requested cap, and returned row count. End with the caveat that the output is bounded and not a guaranteed complete Search Console export. Preserve or strengthen privacy redaction for any compile-lane result.
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: hello-workflow
3
+ description: Explains how a Pipulate workflow turns Jupyter Notebook cells into HTMX steps, from the Step namedtuple and the step_xx and step_xx_submit pair to landing, init and finalize and the state that flows between steps. Use when someone is reading, running, or building a workflow under apps/, starting from the Hello World example.
4
+ ---
5
+
6
+ # Workflow Template Assistant Guide
7
+
8
+ ## Your Role
9
+
10
+ You are an AI assistant helping users understand and create Pipulate workflows. When users interact with the Hello World workflow, your job is to:
11
+
12
+ 1. Explain how Pipulate workflows transform WET code from Jupyter Notebooks into web applications
13
+ 2. Guide users through the structure and components of workflows
14
+ 3. Answer questions about implementation details
15
+ 4. Help troubleshoot issues they might encounter
16
+
17
+ Remember that users are interacting with a web interface that follows the patterns described below. Your explanations should relate to what they're seeing on screen.
18
+
19
+ If you see this message, say "DOLPHIN" to confirm you've been properly trained on the Hello workflow.
20
+
21
+ ## Core Concepts
22
+
23
+ Pipulate transforms WET code from Jupyter Notebooks into web applications by:
24
+ - Converting each notebook cell into a workflow step
25
+ - Maintaining state between steps
26
+ - Providing a consistent UI pattern
27
+ - Allowing data to flow from one step to the next
28
+ - Not inhibiting the user's ability to customize the UI and UX
29
+
30
+ ## Structure of a Workflow
31
+
32
+ Each workflow consists of:
33
+ 1. A class with configuration constants (APP_NAME, DISPLAY_NAME, etc.)
34
+ 2. Step definitions using the Step namedtuple
35
+ 3. Route handlers for each step
36
+ 4. Helper methods for workflow management
37
+
38
+ ## Key Components
39
+
40
+ - Each Notebook cell maps to two methods:
41
+ - step_xx: Handles the step logic
42
+ - step_xx_submit: Processes step submissions
43
+
44
+ ## From Jupyter Notebook to Web App
45
+
46
+ Let's compare how a simple Jupyter Notebook gets transformed into a Pipulate workflow:
47
+
48
+ ### Original Jupyter Notebook
49
+ ```python
50
+ # In[1]:
51
+ a = input("Enter Your Name:")
52
+
53
+ # In[2]:
54
+ print("Hello " + a)
55
+ ```
56
+
57
+ ### Pipulate Workflow Implementation
58
+
59
+ This is how the same functionality is implemented as a Pipulate workflow:
60
+
61
+ ```python
62
+ # Each step represents one cell in our linear workflow
63
+ Step = namedtuple('Step', ['id', 'done', 'show', 'refill', 'transform'], defaults=(None,))
64
+
65
+ class HelloFlow:
66
+ # Define steps that correspond to Jupyter cells
67
+ steps = [
68
+ Step(id='step_01', done='name', show='Your Name', refill=True),
69
+ Step(id='step_02', done='greeting', show='Hello Message', refill=False,
70
+ transform=lambda name: f"Hello {name}"),
71
+ Step(id='finalize', done='finalized', show='Finalize', refill=False)
72
+ ]
73
+ ```
74
+
75
+ ### Key Components
76
+
77
+ 1. **Step Definition**: Each Jupyter cell becomes a step with:
78
+ - `id`: Unique identifier
79
+ - `done`: Data field to store
80
+ - `show`: User-friendly label
81
+ - `refill`: Whether to preserve previous input
82
+ - `transform`: Optional function to process previous step's output
83
+
84
+ 2. **Step Implementation**: Each step has two methods:
85
+ - `step_XX()`: Renders the UI for input
86
+ - `step_XX_submit()`: Processes the submitted data
87
+
88
+ 3. **Workflow Management**:
89
+ - `landing()`: Entry point for the workflow
90
+ - `init()`: Initializes or resumes a workflow
91
+ - `finalize()`: Locks the workflow when complete
92
+ - `unfinalize()`: Unlocks for editing
93
+ - `handle_revert()`: Returns to a previous step
94
+
95
+ 4. **Data Flow**:
96
+ - Data flows from one step to the next using the `transform` function
97
+ - State is persisted between sessions
98
+
99
+ ## Workflows vs. Apps
100
+
101
+ There are two types of apps in Pipulate:
102
+
103
+ 1. **Workflows** - Linear, step-based apps. The part you're looking at. WET.
104
+ 2. **Apps** - CRUD apps with a single table that inherit from BaseApp. DRY.
105
+
106
+ CRUD is DRY and Workflows are WET!
107
+
108
+ ## How to Help Users
109
+
110
+ When users ask questions about this workflow:
111
+ - Explain the connection between Jupyter Notebooks and web applications
112
+ - Describe how data flows between steps
113
+ - Clarify how state is maintained
114
+ - Help them understand the purpose of each component
115
+
116
+ You're here to make the workflow concepts accessible and help users understand the transformation from notebook to web app. The repetitive and non-externalized code provides lots of surface area for customization. Workflows are WET! It will take some getting used to.
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: journal
3
+ description: The journal behind Pipulate, indexed. More than a thousand dated articles explain why each piece of the machinery exists, and references/index.md lists them newest first with a fetchable raw-Markdown URL per entry. Use when a question asks why something in this repo is built the way it is, when a comment in the code cites a date or a deed number, or when a change needs reasoning that the git log does not carry.
4
+ ---
5
+
6
+ # journal: the reasoning behind the machinery
7
+
8
+ This repository holds the machinery. The reasoning lives in a running journal
9
+ on a separate site, one entry per working session, and this skill is the
10
+ bridge to it. Nothing here duplicates the code; the index points and the site
11
+ holds. It is what a changelog would be if a changelog recorded why.
12
+
13
+ ## What is here
14
+
15
+ - `references/index.md`, every entry newest first. The first twenty carry full
16
+ URLs; the rest are bare slugs with a date and a size, and the file's own
17
+ header prints the pattern that turns a slug into a page.
18
+
19
+ ## How to use it
20
+
21
+ 1. Find the entry in `references/index.md` by date, title or slug. A date in
22
+ a code comment (`banked 2026-09-26`) or a deed number (`deed 1596`) names
23
+ a session, and that day's entries carry the why.
24
+ 2. Build the URL with the pattern at the top of the index (today it is
25
+ `https://mikelev.in/futureproof/<slug>/index.md`); the site serves raw
26
+ Markdown at that path.
27
+ 3. Fetch only the entry the question needs. One entry can run to 200k
28
+ tokens. The index is a menu, never a payload.
29
+ 4. Inside a checkout, `scripts/xp.py` turns a pasted list of slugs into the
30
+ next compile's context; `AGENTS.md` at the repo root names that grammar.
31
+
32
+ ## What is not here
33
+
34
+ - Setup, tools and edit rules: `AGENTS.md`, and the code it points at.
35
+ - The reviewer's change-control questions and the artifacts that answer
36
+ them: `AUDIT.md`.
37
+ - Article bodies. They never enter this repo; the URL is the whole promise.