ashlr-plugin 1.36.4
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.
- package/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +39 -0
- package/.claude-plugin/plugin.json +36 -0
- package/.codex/agents/README.md +9 -0
- package/.codex/agents/ashlr-explorer.md +36 -0
- package/.codex/agents/ashlr-worker.md +38 -0
- package/.codex-plugin/plugin.json +45 -0
- package/.mcp.json +14 -0
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/agents/ashlr-code.md +69 -0
- package/agents/ashlr-explore.md +44 -0
- package/agents/ashlr-plan.md +54 -0
- package/bench/fixtures/notebook-large.ipynb +660 -0
- package/bench/fixtures/notebook-small.ipynb +39 -0
- package/bench/fixtures/tasklist-closed.json +62 -0
- package/bench/fixtures/tasklist-large-mixed.json +27 -0
- package/bench/fixtures/tasklist-sprint-open.json +79 -0
- package/bench/fixtures/websearch-bun-runtime.json +32 -0
- package/bench/fixtures/websearch-react-hooks-patterns.json +32 -0
- package/bench/fixtures/websearch-typescript-generics.json +38 -0
- package/bench/refs/node-sdk/.refrev +1 -0
- package/bench/refs/node-sdk/README.md +17 -0
- package/bench/refs/node-sdk/src/agent/agent.ts +163 -0
- package/bench/refs/node-sdk/src/agent/create-agent-ui-stream.ts +83 -0
- package/bench/refs/node-sdk/src/agent/tool-loop-agent.ts +238 -0
- package/bench/refs/node-sdk/src/embed/embed-many.ts +409 -0
- package/bench/refs/node-sdk/src/embed/embed-result.ts +50 -0
- package/bench/refs/node-sdk/src/embed/embed.ts +257 -0
- package/bench/refs/node-sdk/src/error/invalid-argument-error.ts +34 -0
- package/bench/refs/node-sdk/src/error/invalid-tool-input-error.ts +33 -0
- package/bench/refs/node-sdk/src/error/no-object-generated-error.ts +70 -0
- package/bench/refs/node-sdk/src/generate-image/generate-image-result.ts +42 -0
- package/bench/refs/node-sdk/src/generate-image/generate-image.ts +362 -0
- package/bench/refs/node-sdk/src/generate-object/generate-object-result.ts +67 -0
- package/bench/refs/node-sdk/src/generate-object/generate-object.ts +501 -0
- package/bench/refs/node-sdk/src/generate-object/inject-json-instruction.ts +30 -0
- package/bench/refs/node-sdk/src/generate-object/output-strategy.ts +415 -0
- package/bench/refs/node-sdk/src/generate-object/repair-text.ts +12 -0
- package/bench/refs/node-sdk/src/generate-object/stream-object.ts +960 -0
- package/bench/refs/node-sdk/src/generate-speech/generate-speech.ts +191 -0
- package/bench/refs/node-sdk/src/generate-text/generate-text.ts +1484 -0
- package/bench/refs/node-sdk/src/generate-text/stream-text.ts +2708 -0
- package/bench/refs/node-sdk/src/generate-text/tool-call.ts +59 -0
- package/bench/refs/node-sdk/src/generate-text/tool-result.ts +36 -0
- package/bench/refs/node-sdk/src/telemetry/create-telemetry-dispatcher.ts +146 -0
- package/bench/refs/node-sdk/src/telemetry/telemetry-registry.ts +15 -0
- package/bench/refs/node-sdk/src/telemetry/telemetry.ts +223 -0
- package/bench/refs/node-sdk/src/util/async-iterable-stream.ts +94 -0
- package/bench/refs/node-sdk/src/util/consume-stream.ts +31 -0
- package/bench/refs/node-sdk/src/util/create-stitchable-stream.ts +112 -0
- package/bench/refs/node-sdk/src/util/download/download.ts +74 -0
- package/bench/refs/node-sdk/src/util/error-handler.ts +1 -0
- package/bench/refs/node-sdk/src/util/fix-json.ts +401 -0
- package/bench/refs/node-sdk/src/util/merge-objects.ts +79 -0
- package/bench/refs/python-lib/.refrev +1 -0
- package/bench/refs/python-lib/README.md +18 -0
- package/bench/refs/python-lib/pandas/core/_numba/executor.py +249 -0
- package/bench/refs/python-lib/pandas/core/_numba/extensions.py +586 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/mean_.py +198 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/min_max_.py +178 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/sum_.py +255 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/var_.py +251 -0
- package/bench/refs/python-lib/pandas/core/accessor.py +520 -0
- package/bench/refs/python-lib/pandas/core/api.py +138 -0
- package/bench/refs/python-lib/pandas/core/array_algos/masked_accumulations.py +97 -0
- package/bench/refs/python-lib/pandas/core/array_algos/masked_reductions.py +252 -0
- package/bench/refs/python-lib/pandas/core/array_algos/putmask.py +150 -0
- package/bench/refs/python-lib/pandas/core/array_algos/quantile.py +232 -0
- package/bench/refs/python-lib/pandas/core/array_algos/replace.py +159 -0
- package/bench/refs/python-lib/pandas/core/array_algos/take.py +609 -0
- package/bench/refs/python-lib/pandas/core/arraylike.py +534 -0
- package/bench/refs/python-lib/pandas/core/arrays/_arrow_string_mixins.py +434 -0
- package/bench/refs/python-lib/pandas/core/arrays/_mixins.py +630 -0
- package/bench/refs/python-lib/pandas/core/arrays/_ranges.py +276 -0
- package/bench/refs/python-lib/pandas/core/arrays/_utils.py +77 -0
- package/bench/refs/python-lib/pandas/core/arrays/arrow/accessors.py +521 -0
- package/bench/refs/python-lib/pandas/core/arrays/arrow/extension_types.py +174 -0
- package/bench/refs/python-lib/pandas/core/arrays/boolean.py +454 -0
- package/bench/refs/python-lib/pandas/core/arrays/floating.py +192 -0
- package/bench/refs/python-lib/pandas/core/arrays/integer.py +296 -0
- package/bench/refs/python-lib/pandas/core/arrays/masked.py +2140 -0
- package/bench/refs/python-lib/pandas/core/arrays/numeric.py +305 -0
- package/bench/refs/python-lib/pandas/core/arrays/numpy_.py +701 -0
- package/bench/refs/python-lib/pandas/core/arrays/period.py +1586 -0
- package/bench/refs/python-lib/pandas/core/arrays/sparse/accessor.py +505 -0
- package/bench/refs/python-lib/pandas/core/arrays/sparse/scipy_sparse.py +208 -0
- package/bench/refs/rust-project/.refrev +1 -0
- package/bench/refs/rust-project/README.md +17 -0
- package/bench/refs/rust-project/tokio/src/doc/os.rs +68 -0
- package/bench/refs/rust-project/tokio/src/fs/dir_builder.rs +129 -0
- package/bench/refs/rust-project/tokio/src/fs/file.rs +1113 -0
- package/bench/refs/rust-project/tokio/src/fs/mocks.rs +176 -0
- package/bench/refs/rust-project/tokio/src/fs/mod.rs +324 -0
- package/bench/refs/rust-project/tokio/src/fs/open_options.rs +856 -0
- package/bench/refs/rust-project/tokio/src/fs/read.rs +80 -0
- package/bench/refs/rust-project/tokio/src/fs/read_dir.rs +357 -0
- package/bench/refs/rust-project/tokio/src/fs/write.rs +99 -0
- package/bench/refs/rust-project/tokio/src/future/maybe_done.rs +123 -0
- package/bench/refs/rust-project/tokio/src/future/try_join.rs +82 -0
- package/bench/refs/rust-project/tokio/src/io/async_buf_read.rs +117 -0
- package/bench/refs/rust-project/tokio/src/io/async_read.rs +133 -0
- package/bench/refs/rust-project/tokio/src/io/async_seek.rs +96 -0
- package/bench/refs/rust-project/tokio/src/io/async_write.rs +402 -0
- package/bench/refs/rust-project/tokio/src/io/blocking.rs +339 -0
- package/bench/refs/rust-project/tokio/src/io/interest.rs +345 -0
- package/bench/refs/rust-project/tokio/src/io/join.rs +130 -0
- package/bench/refs/rust-project/tokio/src/io/mod.rs +308 -0
- package/bench/refs/rust-project/tokio/src/io/poll_evented.rs +319 -0
- package/bench/refs/rust-project/tokio/src/io/read_buf.rs +344 -0
- package/bench/refs/rust-project/tokio/src/io/ready.rs +322 -0
- package/bench/refs/rust-project/tokio/src/io/split.rs +166 -0
- package/bench/refs/rust-project/tokio/src/io/stderr.rs +148 -0
- package/bench/refs/rust-project/tokio/src/io/stdin.rs +98 -0
- package/bench/refs/rust-project/tokio/src/io/stdio_common.rs +222 -0
- package/bench/refs/rust-project/tokio/src/io/stdout.rs +197 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_reader.rs +311 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_stream.rs +207 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_writer.rs +310 -0
- package/bench/refs/rust-project/tokio/src/io/util/chain.rs +144 -0
- package/commands/_spawn-patterns.json +32 -0
- package/commands/ashlr-allow.md +21 -0
- package/commands/ashlr-benchmark.md +53 -0
- package/commands/ashlr-brief.md +97 -0
- package/commands/ashlr-budget.md +76 -0
- package/commands/ashlr-compact.md +54 -0
- package/commands/ashlr-dashboard.md +37 -0
- package/commands/ashlr-doctor.md +56 -0
- package/commands/ashlr-eco-mode.md +92 -0
- package/commands/ashlr-genome-init.md +24 -0
- package/commands/ashlr-genome-keygen.md +36 -0
- package/commands/ashlr-genome-loop.md +118 -0
- package/commands/ashlr-genome-push.md +36 -0
- package/commands/ashlr-genome-rewrap.md +48 -0
- package/commands/ashlr-genome-team-init.md +67 -0
- package/commands/ashlr-handoff.md +23 -0
- package/commands/ashlr-help.md +86 -0
- package/commands/ashlr-hook-timings.md +30 -0
- package/commands/ashlr-leaderboard.md +50 -0
- package/commands/ashlr-ollama-setup.md +39 -0
- package/commands/ashlr-orchestrate-status.md +72 -0
- package/commands/ashlr-orchestrate.md +83 -0
- package/commands/ashlr-parallelize.md +63 -0
- package/commands/ashlr-report-crash.md +33 -0
- package/commands/ashlr-resume.md +72 -0
- package/commands/ashlr-savings.md +24 -0
- package/commands/ashlr-settings.md +50 -0
- package/commands/ashlr-spawn.md +61 -0
- package/commands/ashlr-start.md +60 -0
- package/commands/ashlr-status.md +64 -0
- package/commands/ashlr-team-invite.md +47 -0
- package/commands/ashlr-tier.md +122 -0
- package/commands/ashlr-tour.md +60 -0
- package/commands/ashlr-update.md +155 -0
- package/commands/ashlr-upgrade.md +96 -0
- package/commands/goal.md +58 -0
- package/commands/loop.md +40 -0
- package/docs/CNAME +1 -0
- package/docs/PRO_TIER.md +104 -0
- package/docs/README.md +21 -0
- package/docs/architecture.md +415 -0
- package/docs/ashlr-pipe.md +161 -0
- package/docs/assets/logo.svg +19 -0
- package/docs/assets/og.png +0 -0
- package/docs/assets/og.svg +41 -0
- package/docs/benchmarks-v2.json +355 -0
- package/docs/benchmarks.json +102 -0
- package/docs/benchmarks.md +211 -0
- package/docs/billing.md +185 -0
- package/docs/cloud-genome.md +155 -0
- package/docs/competitive-wozcode.md +92 -0
- package/docs/deploy.md +325 -0
- package/docs/email-templates.md +113 -0
- package/docs/embed-tuning.md +103 -0
- package/docs/genome.md +120 -0
- package/docs/github-oauth-onboarding.md +127 -0
- package/docs/hero-video-script.md +129 -0
- package/docs/index.html +2262 -0
- package/docs/install-prompt.md +78 -0
- package/docs/install-windows.md +132 -0
- package/docs/install.ps1 +171 -0
- package/docs/install.sh +146 -0
- package/docs/launch/README.md +114 -0
- package/docs/launch/hn.md +49 -0
- package/docs/launch/reddit.md +45 -0
- package/docs/launch/x.md +65 -0
- package/docs/launch-post.md +112 -0
- package/docs/legal.md +78 -0
- package/docs/llm-providers.md +99 -0
- package/docs/multi-host-mcp.md +217 -0
- package/docs/multi-turn-architecture.md +108 -0
- package/docs/operations/deployment.md +108 -0
- package/docs/operations/error-monitoring.md +70 -0
- package/docs/operations/weekly-digest.md +70 -0
- package/docs/operations.md +494 -0
- package/docs/platform-support.md +133 -0
- package/docs/policy-packs.md +188 -0
- package/docs/press-kit/fact-sheet.md +78 -0
- package/docs/press-kit/founder-bio.md +3 -0
- package/docs/press-kit/logo.svg +33 -0
- package/docs/press-kit/screenshots.md +146 -0
- package/docs/pricing.md +251 -0
- package/docs/pro-backend-architecture.md +523 -0
- package/docs/producthunt.md +52 -0
- package/docs/router-migration.md +110 -0
- package/docs/session-log-schema.md +68 -0
- package/docs/social.md +95 -0
- package/docs/team-genome.md +528 -0
- package/docs/telemetry.md +194 -0
- package/docs/test-isolation.md +100 -0
- package/docs/upgrade.md +159 -0
- package/hooks/_hook-errors.ts +87 -0
- package/hooks/_hook-perf-emit.ts +113 -0
- package/hooks/_hook-timing-ledger.ts +1133 -0
- package/hooks/_nudge-throttle.ts +127 -0
- package/hooks/_recent-blocks.ts +127 -0
- package/hooks/audit-upload.ts +86 -0
- package/hooks/codex-hooks.json +171 -0
- package/hooks/commit-attribution.ts +179 -0
- package/hooks/edit-batching-nudge.ts +154 -0
- package/hooks/genome-scribe-hook.ts +219 -0
- package/hooks/hooks.json +294 -0
- package/hooks/orient-nudge-hook.ts +242 -0
- package/hooks/policy-enforce.ts +214 -0
- package/hooks/post-tool-use-embedding.ts +93 -0
- package/hooks/post-tool-use-genome.sh +37 -0
- package/hooks/post-tool-use-genome.ts +69 -0
- package/hooks/posttooluse-correlate.ts +122 -0
- package/hooks/posttooluse-dedupe-output.ts +241 -0
- package/hooks/posttooluse-genome-refresh.ts +223 -0
- package/hooks/posttooluse-native-nudge.ts +205 -0
- package/hooks/posttooluse-stale-result.ts +277 -0
- package/hooks/pretooluse-bash.ts +63 -0
- package/hooks/pretooluse-budget-guard.ts +318 -0
- package/hooks/pretooluse-common.ts +985 -0
- package/hooks/pretooluse-eco-router.ts +196 -0
- package/hooks/pretooluse-edit.sh +93 -0
- package/hooks/pretooluse-edit.ts +197 -0
- package/hooks/pretooluse-glob.ts +70 -0
- package/hooks/pretooluse-grep.sh +85 -0
- package/hooks/pretooluse-grep.ts +96 -0
- package/hooks/pretooluse-notebookedit.ts +121 -0
- package/hooks/pretooluse-read.sh +118 -0
- package/hooks/pretooluse-read.ts +118 -0
- package/hooks/pretooluse-task.ts +130 -0
- package/hooks/pretooluse-webfetch.ts +66 -0
- package/hooks/pretooluse-websearch.ts +85 -0
- package/hooks/pretooluse-write.ts +128 -0
- package/hooks/pulse-emit.ts +197 -0
- package/hooks/session-end-consolidate.sh +35 -0
- package/hooks/session-end-consolidate.ts +188 -0
- package/hooks/session-end-stats-gc.ts +80 -0
- package/hooks/session-log-append.sh +94 -0
- package/hooks/session-log-append.ts +116 -0
- package/hooks/session-start.ts +993 -0
- package/hooks/sessionend-hook-health-nudge.ts +451 -0
- package/hooks/sessionend-savings-nudge.ts +318 -0
- package/hooks/sessionend-status-line-nudge.ts +296 -0
- package/hooks/sessionstart-brief.ts +140 -0
- package/hooks/sessionstart-cost-refactor.ts +95 -0
- package/hooks/sessionstart-efficient.ts +110 -0
- package/hooks/sessionstart-genome-author.ts +93 -0
- package/hooks/sessionstart-lean-tools.ts +98 -0
- package/hooks/sessionstart-search.ts +97 -0
- package/hooks/stop-accounting.ts +152 -0
- package/hooks/subagent-stop-rollup.ts +162 -0
- package/hooks/userpromptsubmit-brief-trigger.ts +156 -0
- package/package.json +56 -0
- package/ports/README.md +108 -0
- package/ports/cursor/mcp.json +11 -0
- package/ports/goose/recipe.yaml +26 -0
- package/scripts/ashlr-mcp.ts +40 -0
- package/scripts/auto-update.ts +177 -0
- package/scripts/baseline-scan.ts +831 -0
- package/scripts/bench-orchestrate.ts +377 -0
- package/scripts/benchmark-refs.ts +292 -0
- package/scripts/bootstrap.mjs +100 -0
- package/scripts/brief-eval.ts +234 -0
- package/scripts/bump-version.ts +82 -0
- package/scripts/bun-resolve.d.mts +11 -0
- package/scripts/bun-resolve.mjs +59 -0
- package/scripts/calibrate-grep.ts +467 -0
- package/scripts/capture-grep-workload.ts +260 -0
- package/scripts/check-tier.ts +61 -0
- package/scripts/check-version-sync.ts +97 -0
- package/scripts/cli-orchestrate-status.ts +386 -0
- package/scripts/cli-orchestrate.ts +303 -0
- package/scripts/cli.ts +478 -0
- package/scripts/cloud-smoke-test.ts +313 -0
- package/scripts/coach-report.ts +373 -0
- package/scripts/context-db-migrate.ts +137 -0
- package/scripts/context-status.ts +43 -0
- package/scripts/demo-run.ts +255 -0
- package/scripts/deploy-smoke.sh +140 -0
- package/scripts/doctor.ts +992 -0
- package/scripts/embed-file-worker.ts +104 -0
- package/scripts/embed-tune.ts +308 -0
- package/scripts/errors-report.ts +428 -0
- package/scripts/find-test-leak.ts +69 -0
- package/scripts/generate-badge.ts +357 -0
- package/scripts/genome-auto-consolidate.ts +533 -0
- package/scripts/genome-auto-propose.ts +578 -0
- package/scripts/genome-cloud-pull.ts +363 -0
- package/scripts/genome-cloud-push.ts +382 -0
- package/scripts/genome-cloud-sync.ts +587 -0
- package/scripts/genome-commit-watcher.ts +295 -0
- package/scripts/genome-init.ts +986 -0
- package/scripts/genome-key.ts +233 -0
- package/scripts/genome-keygen.ts +168 -0
- package/scripts/genome-link.ts +59 -0
- package/scripts/genome-refresh-worker.ts +364 -0
- package/scripts/genome-rewrap.ts +90 -0
- package/scripts/genome-synthesizer.ts +679 -0
- package/scripts/genome-team-init.ts +312 -0
- package/scripts/handoff-pack.ts +438 -0
- package/scripts/hook-bootstrap.mjs +75 -0
- package/scripts/hook-timing-reader.ts +371 -0
- package/scripts/hook-timings-report.ts +554 -0
- package/scripts/install-genome-hooks.ts +196 -0
- package/scripts/install-onnx-model.ts +154 -0
- package/scripts/install-permissions.ts +276 -0
- package/scripts/install-status-line.ts +150 -0
- package/scripts/mcp-entrypoint.sh +78 -0
- package/scripts/mcp-entrypoint.ts +130 -0
- package/scripts/mdx-angle-bracket-lint.ts +152 -0
- package/scripts/measure-cold-start.ts +126 -0
- package/scripts/migrate-stats-to-sqlite.ts +86 -0
- package/scripts/ollama-setup.ts +498 -0
- package/scripts/onboarding-wizard.ts +1691 -0
- package/scripts/orchestrate-emit-telemetry.ts +177 -0
- package/scripts/orchestrate-expand.ts +517 -0
- package/scripts/orchestrate-run.ts +744 -0
- package/scripts/print-legend.ts +50 -0
- package/scripts/product-metadata.ts +38 -0
- package/scripts/prune-old-memories.ts +208 -0
- package/scripts/publish.sh +88 -0
- package/scripts/read-calibration.ts +122 -0
- package/scripts/report-crash.ts +226 -0
- package/scripts/run-benchmark.ts +750 -0
- package/scripts/run-root-tests.ts +28 -0
- package/scripts/savings-dashboard.ts +1258 -0
- package/scripts/savings-report-extras.ts +447 -0
- package/scripts/savings-status-line.ts +873 -0
- package/scripts/session-event-emit.ts +266 -0
- package/scripts/session-greet.ts +686 -0
- package/scripts/session-log-report.ts +551 -0
- package/scripts/session-resume.ts +614 -0
- package/scripts/set-hook-mode.ts +83 -0
- package/scripts/smoke-cross-platform.ts +117 -0
- package/scripts/smoke-realtime.ts +257 -0
- package/scripts/smoke-tools.ts +21 -0
- package/scripts/stats-cloud-pull.ts +213 -0
- package/scripts/stats-cloud-sync.ts +261 -0
- package/scripts/telemetry-flush.ts +160 -0
- package/scripts/telemetry-status.ts +266 -0
- package/scripts/timing-budget.ts +35 -0
- package/scripts/ui-animation.ts +120 -0
- package/scripts/ui.ts +431 -0
- package/scripts/upgrade-flow.ts +775 -0
- package/scripts/weekly-digest.ts +394 -0
- package/servers/_accounting.ts +78 -0
- package/servers/_ask-router.ts +84 -0
- package/servers/_ast-chunker.ts +434 -0
- package/servers/_ast-helpers.ts +183 -0
- package/servers/_ast-languages.ts +153 -0
- package/servers/_ast-refactor/_shared.ts +221 -0
- package/servers/_ast-refactor/cross-file-rename.ts +560 -0
- package/servers/_ast-refactor/extract-function.ts +357 -0
- package/servers/_ast-refactor/file-local-rename.ts +172 -0
- package/servers/_ast-refactor.ts +41 -0
- package/servers/_ast-skeleton.ts +107 -0
- package/servers/_bash-summarizers-registry.ts +1096 -0
- package/servers/_crash-dump.ts +210 -0
- package/servers/_cwd-clamp.ts +342 -0
- package/servers/_edit-log.ts +28 -0
- package/servers/_edit-match.ts +236 -0
- package/servers/_edit-validate.ts +196 -0
- package/servers/_embed-calibration.ts +123 -0
- package/servers/_embedding-cache.ts +401 -0
- package/servers/_embedding-model.ts +329 -0
- package/servers/_events.ts +113 -0
- package/servers/_genome-cache.ts +154 -0
- package/servers/_genome-commits.ts +172 -0
- package/servers/_genome-crypto-v2.ts +242 -0
- package/servers/_genome-crypto.ts +259 -0
- package/servers/_genome-discoveries.ts +140 -0
- package/servers/_genome-embed-populator.ts +216 -0
- package/servers/_genome-freshness.ts +134 -0
- package/servers/_genome-issues.ts +171 -0
- package/servers/_genome-live.ts +263 -0
- package/servers/_genome-prs.ts +188 -0
- package/servers/_genome-search.ts +479 -0
- package/servers/_genome-sync.ts +297 -0
- package/servers/_history-tracker.ts +279 -0
- package/servers/_http-helpers.ts +151 -0
- package/servers/_identity-hash.ts +151 -0
- package/servers/_llm-providers/anthropic.ts +132 -0
- package/servers/_llm-providers/cloud.ts +195 -0
- package/servers/_llm-providers/index.ts +350 -0
- package/servers/_llm-providers/local.ts +127 -0
- package/servers/_llm-providers/onnx.ts +393 -0
- package/servers/_llm-providers/types.ts +27 -0
- package/servers/_manifest-v2.ts +447 -0
- package/servers/_mcp-host.ts +93 -0
- package/servers/_nudge-events.ts +451 -0
- package/servers/_orchestrate-executor.ts +316 -0
- package/servers/_prefetch.ts +435 -0
- package/servers/_pricing.ts +256 -0
- package/servers/_pro.ts +381 -0
- package/servers/_read-cache.ts +44 -0
- package/servers/_router-handlers.ts +46 -0
- package/servers/_router.ts +55 -0
- package/servers/_run-with-timeout.ts +173 -0
- package/servers/_savings-render.ts +214 -0
- package/servers/_stats-sqlite.ts +640 -0
- package/servers/_stats.ts +1183 -0
- package/servers/_status-line-cells.ts +469 -0
- package/servers/_streaks.ts +162 -0
- package/servers/_summarize.ts +208 -0
- package/servers/_task-graph-render.ts +217 -0
- package/servers/_task-graph.ts +545 -0
- package/servers/_telemetry.ts +719 -0
- package/servers/_test-parsers.ts +530 -0
- package/servers/_test-watch.ts +626 -0
- package/servers/_text-helpers.ts +37 -0
- package/servers/_token-measure.ts +160 -0
- package/servers/_tool-base.ts +248 -0
- package/servers/_weekly-digest.ts +391 -0
- package/servers/ask-server-handlers.ts +49 -0
- package/servers/ask-server.ts +174 -0
- package/servers/bash-server-handlers.ts +138 -0
- package/servers/bash-server.ts +1136 -0
- package/servers/bench.ts +186 -0
- package/servers/diff-semantic-server-handlers.ts +39 -0
- package/servers/diff-semantic-server.ts +566 -0
- package/servers/diff-server-handlers.ts +317 -0
- package/servers/diff-server.ts +20 -0
- package/servers/edit-server-handlers.ts +31 -0
- package/servers/edit-server.ts +209 -0
- package/servers/edit-structural-server-handlers.ts +322 -0
- package/servers/efficiency-server-handlers.ts +161 -0
- package/servers/efficiency-server.ts +1135 -0
- package/servers/flush-server-handlers.ts +21 -0
- package/servers/flush-server.ts +19 -0
- package/servers/genome-server-handlers.ts +118 -0
- package/servers/genome-server.ts +397 -0
- package/servers/github-server-handlers.ts +187 -0
- package/servers/github-server.ts +856 -0
- package/servers/glob-server-handlers.ts +233 -0
- package/servers/glob-server.ts +20 -0
- package/servers/grep-server-handlers.ts +61 -0
- package/servers/grep-server.ts +564 -0
- package/servers/http-server-handlers.ts +36 -0
- package/servers/http-server.ts +149 -0
- package/servers/logs-server-handlers.ts +42 -0
- package/servers/logs-server.ts +359 -0
- package/servers/ls-server-handlers.ts +166 -0
- package/servers/ls-server.ts +20 -0
- package/servers/multi-edit-server-handlers.ts +51 -0
- package/servers/multi-edit-server.ts +422 -0
- package/servers/notebook-edit-server-handlers.ts +34 -0
- package/servers/notebook-edit-server.ts +181 -0
- package/servers/orient-server-handlers.ts +52 -0
- package/servers/orient-server.ts +436 -0
- package/servers/pipe-server-handlers.ts +68 -0
- package/servers/pipe-server.ts +300 -0
- package/servers/read-server-handlers.ts +42 -0
- package/servers/read-server.ts +206 -0
- package/servers/rename-file-server-handlers.ts +67 -0
- package/servers/rename-file-server.ts +699 -0
- package/servers/savings-server-handlers.ts +27 -0
- package/servers/savings-server.ts +54 -0
- package/servers/search-replace-regex-server-handlers.ts +96 -0
- package/servers/search-replace-regex-server.ts +751 -0
- package/servers/sql-server-handlers.ts +58 -0
- package/servers/sql-server.ts +505 -0
- package/servers/task-server-handlers.ts +358 -0
- package/servers/task-server.ts +24 -0
- package/servers/test-server-handlers.ts +351 -0
- package/servers/test-server.ts +20 -0
- package/servers/tree-server-handlers.ts +503 -0
- package/servers/tree-server.ts +20 -0
- package/servers/webfetch-server-handlers.ts +166 -0
- package/servers/webfetch-server.ts +20 -0
- package/servers/websearch-server-handlers.ts +215 -0
- package/servers/websearch-server.ts +19 -0
- package/servers/write-server-handlers.ts +27 -0
- package/servers/write-server.ts +97 -0
- package/skills/ashlr-brief/SKILL.md +80 -0
- package/skills/ashlr-codex-doctor/SKILL.md +21 -0
- package/skills/ashlr-codex-efficient-tools/SKILL.md +17 -0
- package/skills/ashlr-codex-genome-refresh/SKILL.md +20 -0
- package/skills/ashlr-codex-parallel-explore/SKILL.md +20 -0
- package/skills/ashlr-codex-savings/SKILL.md +17 -0
- package/skills/ashlr-cost-refactor/SKILL.md +50 -0
- package/skills/ashlr-efficient/SKILL.md +64 -0
- package/skills/ashlr-genome-author/SKILL.md +43 -0
- package/skills/ashlr-lean-tools/SKILL.md +43 -0
- package/skills/ashlr-search/SKILL.md +46 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
"""Accessors for arrow-backed data."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import (
|
|
6
|
+
ABCMeta,
|
|
7
|
+
abstractmethod,
|
|
8
|
+
)
|
|
9
|
+
from typing import (
|
|
10
|
+
TYPE_CHECKING,
|
|
11
|
+
cast,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from pandas.compat import HAS_PYARROW
|
|
15
|
+
|
|
16
|
+
from pandas.core.dtypes.common import is_list_like
|
|
17
|
+
|
|
18
|
+
if HAS_PYARROW:
|
|
19
|
+
import pyarrow as pa
|
|
20
|
+
import pyarrow.compute as pc
|
|
21
|
+
|
|
22
|
+
from pandas.core.dtypes.dtypes import ArrowDtype
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from collections.abc import Iterator
|
|
26
|
+
|
|
27
|
+
from pandas import (
|
|
28
|
+
DataFrame,
|
|
29
|
+
Series,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ArrowAccessor(metaclass=ABCMeta):
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def __init__(self, data, validation_msg: str) -> None:
|
|
36
|
+
self._data = data
|
|
37
|
+
self._validation_msg = validation_msg
|
|
38
|
+
self._validate(data)
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def _validate(self, data) -> None:
|
|
45
|
+
dtype = data.dtype
|
|
46
|
+
if not HAS_PYARROW or not isinstance(dtype, ArrowDtype):
|
|
47
|
+
# Raise AttributeError so that inspect can handle non-struct Series.
|
|
48
|
+
raise AttributeError(self._validation_msg.format(dtype=dtype))
|
|
49
|
+
|
|
50
|
+
if not self._is_valid_pyarrow_dtype(dtype.pyarrow_dtype):
|
|
51
|
+
# Raise AttributeError so that inspect can handle invalid Series.
|
|
52
|
+
raise AttributeError(self._validation_msg.format(dtype=dtype))
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def _pa_array(self):
|
|
56
|
+
return self._data.array._pa_array
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ListAccessor(ArrowAccessor):
|
|
60
|
+
"""
|
|
61
|
+
Accessor object for list data properties of the Series values.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
data : Series
|
|
66
|
+
Series containing Arrow list data.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def __init__(self, data=None) -> None:
|
|
70
|
+
super().__init__(
|
|
71
|
+
data,
|
|
72
|
+
validation_msg="Can only use the '.list' accessor with "
|
|
73
|
+
"'list[pyarrow]' dtype, not {dtype}.",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:
|
|
77
|
+
return (
|
|
78
|
+
pa.types.is_list(pyarrow_dtype)
|
|
79
|
+
or pa.types.is_fixed_size_list(pyarrow_dtype)
|
|
80
|
+
or pa.types.is_large_list(pyarrow_dtype)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def len(self) -> Series:
|
|
84
|
+
"""
|
|
85
|
+
Return the length of each list in the Series.
|
|
86
|
+
|
|
87
|
+
Computes the number of elements in each list entry. The result is a
|
|
88
|
+
Series of integers with the same index as the original Series.
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
pandas.Series
|
|
93
|
+
The length of each list.
|
|
94
|
+
|
|
95
|
+
See Also
|
|
96
|
+
--------
|
|
97
|
+
str.len : Python built-in function returning the length of an object.
|
|
98
|
+
Series.size : Returns the length of the Series.
|
|
99
|
+
StringMethods.len : Compute the length of each element in the Series/Index.
|
|
100
|
+
|
|
101
|
+
Examples
|
|
102
|
+
--------
|
|
103
|
+
>>> import pyarrow as pa
|
|
104
|
+
>>> s = pd.Series(
|
|
105
|
+
... [
|
|
106
|
+
... [1, 2, 3],
|
|
107
|
+
... [3],
|
|
108
|
+
... ],
|
|
109
|
+
... dtype=pd.ArrowDtype(pa.list_(pa.int64())),
|
|
110
|
+
... )
|
|
111
|
+
>>> s.list.len()
|
|
112
|
+
0 3
|
|
113
|
+
1 1
|
|
114
|
+
dtype: int32[pyarrow]
|
|
115
|
+
"""
|
|
116
|
+
from pandas import Series
|
|
117
|
+
|
|
118
|
+
value_lengths = pc.list_value_length(self._pa_array)
|
|
119
|
+
return Series(
|
|
120
|
+
value_lengths,
|
|
121
|
+
dtype=ArrowDtype(value_lengths.type),
|
|
122
|
+
index=self._data.index,
|
|
123
|
+
name=self._data.name,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def __getitem__(self, key: int | slice) -> Series:
|
|
127
|
+
"""
|
|
128
|
+
Index or slice lists in the Series.
|
|
129
|
+
|
|
130
|
+
Retrieves elements at the given integer index or slice from each list
|
|
131
|
+
in the Series, returning a new Series with the selected values.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
key : int | slice
|
|
136
|
+
Index or slice of indices to access from each list.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
pandas.Series
|
|
141
|
+
The list at requested index.
|
|
142
|
+
|
|
143
|
+
See Also
|
|
144
|
+
--------
|
|
145
|
+
ListAccessor.flatten : Flatten list values.
|
|
146
|
+
|
|
147
|
+
Examples
|
|
148
|
+
--------
|
|
149
|
+
>>> import pyarrow as pa
|
|
150
|
+
>>> s = pd.Series(
|
|
151
|
+
... [
|
|
152
|
+
... [1, 2, 3],
|
|
153
|
+
... [3],
|
|
154
|
+
... ],
|
|
155
|
+
... dtype=pd.ArrowDtype(pa.list_(pa.int64())),
|
|
156
|
+
... )
|
|
157
|
+
>>> s.list[0]
|
|
158
|
+
0 1
|
|
159
|
+
1 3
|
|
160
|
+
dtype: int64[pyarrow]
|
|
161
|
+
"""
|
|
162
|
+
from pandas import Series
|
|
163
|
+
|
|
164
|
+
if isinstance(key, int):
|
|
165
|
+
# TODO: Support negative key but pyarrow does not allow
|
|
166
|
+
# element index to be an array.
|
|
167
|
+
# if key < 0:
|
|
168
|
+
# key = pc.add(key, pc.list_value_length(self._pa_array))
|
|
169
|
+
element = pc.list_element(self._pa_array, key)
|
|
170
|
+
return Series(
|
|
171
|
+
element,
|
|
172
|
+
dtype=ArrowDtype(element.type),
|
|
173
|
+
index=self._data.index,
|
|
174
|
+
name=self._data.name,
|
|
175
|
+
)
|
|
176
|
+
elif isinstance(key, slice):
|
|
177
|
+
# TODO: Support negative start/stop/step, ideally this would be added
|
|
178
|
+
# upstream in pyarrow.
|
|
179
|
+
start, stop, step = key.start, key.stop, key.step
|
|
180
|
+
if start is None:
|
|
181
|
+
# TODO: When adding negative step support
|
|
182
|
+
# this should be set to last element of array
|
|
183
|
+
# when step is negative.
|
|
184
|
+
start = 0
|
|
185
|
+
if step is None:
|
|
186
|
+
step = 1
|
|
187
|
+
sliced = pc.list_slice(self._pa_array, start, stop, step)
|
|
188
|
+
return Series(
|
|
189
|
+
sliced,
|
|
190
|
+
dtype=ArrowDtype(sliced.type),
|
|
191
|
+
index=self._data.index,
|
|
192
|
+
name=self._data.name,
|
|
193
|
+
)
|
|
194
|
+
else:
|
|
195
|
+
raise ValueError(f"key must be an int or slice, got {type(key).__name__}")
|
|
196
|
+
|
|
197
|
+
def __iter__(self) -> Iterator:
|
|
198
|
+
raise TypeError(f"'{type(self).__name__}' object is not iterable")
|
|
199
|
+
|
|
200
|
+
def flatten(self) -> Series:
|
|
201
|
+
"""
|
|
202
|
+
Flatten list values.
|
|
203
|
+
|
|
204
|
+
Each list element is expanded into separate rows, preserving the
|
|
205
|
+
original index. The resulting Series may have a longer length than
|
|
206
|
+
the original if lists contain more than one element.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
pandas.Series
|
|
211
|
+
The data from all lists in the series flattened.
|
|
212
|
+
|
|
213
|
+
See Also
|
|
214
|
+
--------
|
|
215
|
+
ListAccessor.__getitem__ : Index or slice values in the Series.
|
|
216
|
+
|
|
217
|
+
Examples
|
|
218
|
+
--------
|
|
219
|
+
>>> import pyarrow as pa
|
|
220
|
+
>>> s = pd.Series(
|
|
221
|
+
... [
|
|
222
|
+
... [1, 2, 3],
|
|
223
|
+
... [3],
|
|
224
|
+
... ],
|
|
225
|
+
... dtype=pd.ArrowDtype(pa.list_(pa.int64())),
|
|
226
|
+
... )
|
|
227
|
+
>>> s.list.flatten()
|
|
228
|
+
0 1
|
|
229
|
+
0 2
|
|
230
|
+
0 3
|
|
231
|
+
1 3
|
|
232
|
+
dtype: int64[pyarrow]
|
|
233
|
+
"""
|
|
234
|
+
from pandas import Series
|
|
235
|
+
|
|
236
|
+
counts = pa.compute.list_value_length(self._pa_array)
|
|
237
|
+
flattened = pa.compute.list_flatten(self._pa_array)
|
|
238
|
+
index = self._data.index.repeat(counts.fill_null(pa.scalar(0, counts.type)))
|
|
239
|
+
return Series(
|
|
240
|
+
flattened,
|
|
241
|
+
dtype=ArrowDtype(flattened.type),
|
|
242
|
+
index=index,
|
|
243
|
+
name=self._data.name,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class StructAccessor(ArrowAccessor):
|
|
248
|
+
"""
|
|
249
|
+
Accessor object for structured data properties of the Series values.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
data : Series
|
|
254
|
+
Series containing Arrow struct data.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
def __init__(self, data=None) -> None:
|
|
258
|
+
super().__init__(
|
|
259
|
+
data,
|
|
260
|
+
validation_msg=(
|
|
261
|
+
"Can only use the '.struct' accessor with 'struct[pyarrow]' "
|
|
262
|
+
"dtype, not {dtype}."
|
|
263
|
+
),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:
|
|
267
|
+
return pa.types.is_struct(pyarrow_dtype)
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def dtypes(self) -> Series:
|
|
271
|
+
"""
|
|
272
|
+
Return the dtype object of each child field of the struct.
|
|
273
|
+
|
|
274
|
+
The returned Series is indexed by the field names of the struct and
|
|
275
|
+
contains the corresponding :class:`ArrowDtype` for each field.
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
pandas.Series
|
|
280
|
+
The data type of each child field.
|
|
281
|
+
|
|
282
|
+
See Also
|
|
283
|
+
--------
|
|
284
|
+
Series.dtype: Return the dtype object of the underlying data.
|
|
285
|
+
|
|
286
|
+
Examples
|
|
287
|
+
--------
|
|
288
|
+
>>> import pyarrow as pa
|
|
289
|
+
>>> s = pd.Series(
|
|
290
|
+
... [
|
|
291
|
+
... {"version": 1, "project": "pandas"},
|
|
292
|
+
... {"version": 2, "project": "pandas"},
|
|
293
|
+
... {"version": 1, "project": "numpy"},
|
|
294
|
+
... ],
|
|
295
|
+
... dtype=pd.ArrowDtype(
|
|
296
|
+
... pa.struct([("version", pa.int64()), ("project", pa.string())])
|
|
297
|
+
... ),
|
|
298
|
+
... )
|
|
299
|
+
>>> s.struct.dtypes
|
|
300
|
+
version int64[pyarrow]
|
|
301
|
+
project string[pyarrow]
|
|
302
|
+
dtype: object
|
|
303
|
+
"""
|
|
304
|
+
from pandas import (
|
|
305
|
+
Index,
|
|
306
|
+
Series,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
pa_type = self._data.dtype.pyarrow_dtype
|
|
310
|
+
types = [ArrowDtype(struct.type) for struct in pa_type]
|
|
311
|
+
names = [struct.name for struct in pa_type]
|
|
312
|
+
return Series(types, index=Index(names))
|
|
313
|
+
|
|
314
|
+
def field(
|
|
315
|
+
self,
|
|
316
|
+
name_or_index: list[str]
|
|
317
|
+
| list[bytes]
|
|
318
|
+
| list[int]
|
|
319
|
+
| pc.Expression
|
|
320
|
+
| bytes
|
|
321
|
+
| str
|
|
322
|
+
| int,
|
|
323
|
+
) -> Series:
|
|
324
|
+
"""
|
|
325
|
+
Extract a child field of a struct as a Series.
|
|
326
|
+
|
|
327
|
+
This method accesses individual child fields of an Arrow struct
|
|
328
|
+
column by name, index, expression, or a list of those for nested
|
|
329
|
+
structs.
|
|
330
|
+
|
|
331
|
+
Parameters
|
|
332
|
+
----------
|
|
333
|
+
name_or_index : str | bytes | int | expression | list
|
|
334
|
+
Name or index of the child field to extract.
|
|
335
|
+
|
|
336
|
+
For list-like inputs, this will index into a nested
|
|
337
|
+
struct.
|
|
338
|
+
|
|
339
|
+
Returns
|
|
340
|
+
-------
|
|
341
|
+
pandas.Series
|
|
342
|
+
The data corresponding to the selected child field.
|
|
343
|
+
|
|
344
|
+
See Also
|
|
345
|
+
--------
|
|
346
|
+
Series.struct.explode : Return all child fields as a DataFrame.
|
|
347
|
+
|
|
348
|
+
Notes
|
|
349
|
+
-----
|
|
350
|
+
The name of the resulting Series will be set using the following
|
|
351
|
+
rules:
|
|
352
|
+
|
|
353
|
+
- For string, bytes, or integer `name_or_index` (or a list of these, for
|
|
354
|
+
a nested selection), the Series name is set to the selected
|
|
355
|
+
field's name.
|
|
356
|
+
- For a :class:`pyarrow.compute.Expression`, this is set to
|
|
357
|
+
the string form of the expression.
|
|
358
|
+
- For list-like `name_or_index`, the name will be set to the
|
|
359
|
+
name of the final field selected.
|
|
360
|
+
|
|
361
|
+
Examples
|
|
362
|
+
--------
|
|
363
|
+
>>> import pyarrow as pa
|
|
364
|
+
>>> s = pd.Series(
|
|
365
|
+
... [
|
|
366
|
+
... {"version": 1, "project": "pandas"},
|
|
367
|
+
... {"version": 2, "project": "pandas"},
|
|
368
|
+
... {"version": 1, "project": "numpy"},
|
|
369
|
+
... ],
|
|
370
|
+
... dtype=pd.ArrowDtype(
|
|
371
|
+
... pa.struct([("version", pa.int64()), ("project", pa.string())])
|
|
372
|
+
... ),
|
|
373
|
+
... )
|
|
374
|
+
|
|
375
|
+
Extract by field name.
|
|
376
|
+
|
|
377
|
+
>>> s.struct.field("project")
|
|
378
|
+
0 pandas
|
|
379
|
+
1 pandas
|
|
380
|
+
2 numpy
|
|
381
|
+
Name: project, dtype: string[pyarrow]
|
|
382
|
+
|
|
383
|
+
Extract by field index.
|
|
384
|
+
|
|
385
|
+
>>> s.struct.field(0)
|
|
386
|
+
0 1
|
|
387
|
+
1 2
|
|
388
|
+
2 1
|
|
389
|
+
Name: version, dtype: int64[pyarrow]
|
|
390
|
+
|
|
391
|
+
Or an expression
|
|
392
|
+
|
|
393
|
+
>>> import pyarrow.compute as pc
|
|
394
|
+
>>> s.struct.field(pc.field("project"))
|
|
395
|
+
0 pandas
|
|
396
|
+
1 pandas
|
|
397
|
+
2 numpy
|
|
398
|
+
Name: project, dtype: string[pyarrow]
|
|
399
|
+
|
|
400
|
+
For nested struct types, you can pass a list of values to index
|
|
401
|
+
multiple levels:
|
|
402
|
+
|
|
403
|
+
>>> version_type = pa.struct(
|
|
404
|
+
... [
|
|
405
|
+
... ("major", pa.int64()),
|
|
406
|
+
... ("minor", pa.int64()),
|
|
407
|
+
... ]
|
|
408
|
+
... )
|
|
409
|
+
>>> s = pd.Series(
|
|
410
|
+
... [
|
|
411
|
+
... {"version": {"major": 1, "minor": 5}, "project": "pandas"},
|
|
412
|
+
... {"version": {"major": 2, "minor": 1}, "project": "pandas"},
|
|
413
|
+
... {"version": {"major": 1, "minor": 26}, "project": "numpy"},
|
|
414
|
+
... ],
|
|
415
|
+
... dtype=pd.ArrowDtype(
|
|
416
|
+
... pa.struct([("version", version_type), ("project", pa.string())])
|
|
417
|
+
... ),
|
|
418
|
+
... )
|
|
419
|
+
>>> s.struct.field(["version", "minor"])
|
|
420
|
+
0 5
|
|
421
|
+
1 1
|
|
422
|
+
2 26
|
|
423
|
+
Name: minor, dtype: int64[pyarrow]
|
|
424
|
+
>>> s.struct.field([0, 0])
|
|
425
|
+
0 1
|
|
426
|
+
1 2
|
|
427
|
+
2 1
|
|
428
|
+
Name: major, dtype: int64[pyarrow]
|
|
429
|
+
"""
|
|
430
|
+
from pandas import Series
|
|
431
|
+
|
|
432
|
+
def get_name(
|
|
433
|
+
level_name_or_index: list[str]
|
|
434
|
+
| list[bytes]
|
|
435
|
+
| list[int]
|
|
436
|
+
| pc.Expression
|
|
437
|
+
| bytes
|
|
438
|
+
| str
|
|
439
|
+
| int,
|
|
440
|
+
data: pa.ChunkedArray,
|
|
441
|
+
):
|
|
442
|
+
if isinstance(level_name_or_index, int):
|
|
443
|
+
name = data.type.field(level_name_or_index).name
|
|
444
|
+
elif isinstance(level_name_or_index, (str, bytes)):
|
|
445
|
+
name = level_name_or_index
|
|
446
|
+
elif isinstance(level_name_or_index, pc.Expression):
|
|
447
|
+
name = str(level_name_or_index)
|
|
448
|
+
elif is_list_like(level_name_or_index):
|
|
449
|
+
# For nested input like [2, 1, 2]
|
|
450
|
+
# iteratively get the struct and field name. The last
|
|
451
|
+
# one is used for the name of the index.
|
|
452
|
+
level_name_or_index = list(reversed(level_name_or_index))
|
|
453
|
+
selected = data
|
|
454
|
+
while level_name_or_index:
|
|
455
|
+
# we need the cast, otherwise mypy complains about
|
|
456
|
+
# getting ints, bytes, or str here, which isn't possible.
|
|
457
|
+
level_name_or_index = cast("list", level_name_or_index)
|
|
458
|
+
name_or_index = level_name_or_index.pop()
|
|
459
|
+
name = get_name(name_or_index, selected)
|
|
460
|
+
selected = selected.type.field(selected.type.get_field_index(name))
|
|
461
|
+
name = selected.name
|
|
462
|
+
else:
|
|
463
|
+
raise ValueError(
|
|
464
|
+
"name_or_index must be an int, str, bytes, "
|
|
465
|
+
"pyarrow.compute.Expression, or list of those"
|
|
466
|
+
)
|
|
467
|
+
return name
|
|
468
|
+
|
|
469
|
+
pa_arr = self._data.array._pa_array
|
|
470
|
+
name = get_name(name_or_index, pa_arr)
|
|
471
|
+
field_arr = pc.struct_field(pa_arr, name_or_index)
|
|
472
|
+
|
|
473
|
+
return Series(
|
|
474
|
+
field_arr,
|
|
475
|
+
dtype=ArrowDtype(field_arr.type),
|
|
476
|
+
index=self._data.index,
|
|
477
|
+
name=name,
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
def explode(self) -> DataFrame:
|
|
481
|
+
"""
|
|
482
|
+
Extract all child fields of a struct as a DataFrame.
|
|
483
|
+
|
|
484
|
+
Each child field of the struct becomes a column in the resulting
|
|
485
|
+
DataFrame, with column names matching the struct field names.
|
|
486
|
+
|
|
487
|
+
Returns
|
|
488
|
+
-------
|
|
489
|
+
pandas.DataFrame
|
|
490
|
+
The data corresponding to all child fields.
|
|
491
|
+
|
|
492
|
+
See Also
|
|
493
|
+
--------
|
|
494
|
+
Series.struct.field : Return a single child field as a Series.
|
|
495
|
+
|
|
496
|
+
Examples
|
|
497
|
+
--------
|
|
498
|
+
>>> import pyarrow as pa
|
|
499
|
+
>>> s = pd.Series(
|
|
500
|
+
... [
|
|
501
|
+
... {"version": 1, "project": "pandas"},
|
|
502
|
+
... {"version": 2, "project": "pandas"},
|
|
503
|
+
... {"version": 1, "project": "numpy"},
|
|
504
|
+
... ],
|
|
505
|
+
... dtype=pd.ArrowDtype(
|
|
506
|
+
... pa.struct([("version", pa.int64()), ("project", pa.string())])
|
|
507
|
+
... ),
|
|
508
|
+
... )
|
|
509
|
+
|
|
510
|
+
>>> s.struct.explode()
|
|
511
|
+
version project
|
|
512
|
+
0 1 pandas
|
|
513
|
+
1 2 pandas
|
|
514
|
+
2 1 numpy
|
|
515
|
+
"""
|
|
516
|
+
from pandas import concat
|
|
517
|
+
|
|
518
|
+
pa_type = self._pa_array.type
|
|
519
|
+
return concat(
|
|
520
|
+
[self.field(i) for i in range(pa_type.num_fields)], axis="columns"
|
|
521
|
+
)
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
import pyarrow
|
|
7
|
+
|
|
8
|
+
from pandas.compat import pa_version_under14p1
|
|
9
|
+
|
|
10
|
+
from pandas.core.dtypes.dtypes import (
|
|
11
|
+
IntervalDtype,
|
|
12
|
+
PeriodDtype,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from pandas.core.arrays.interval import VALID_CLOSED
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from pandas._typing import IntervalClosedType
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ArrowPeriodType(pyarrow.ExtensionType):
|
|
22
|
+
def __init__(self, freq) -> None:
|
|
23
|
+
# attributes need to be set first before calling
|
|
24
|
+
# super init (as that calls serialize)
|
|
25
|
+
self._freq = freq
|
|
26
|
+
pyarrow.ExtensionType.__init__(self, pyarrow.int64(), "pandas.period")
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def freq(self):
|
|
30
|
+
return self._freq
|
|
31
|
+
|
|
32
|
+
def __arrow_ext_serialize__(self) -> bytes:
|
|
33
|
+
metadata = {"freq": self.freq}
|
|
34
|
+
return json.dumps(metadata).encode()
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def __arrow_ext_deserialize__(cls, storage_type, serialized) -> ArrowPeriodType:
|
|
38
|
+
metadata = json.loads(serialized.decode())
|
|
39
|
+
return ArrowPeriodType(metadata["freq"])
|
|
40
|
+
|
|
41
|
+
def __eq__(self, other):
|
|
42
|
+
if isinstance(other, pyarrow.BaseExtensionType):
|
|
43
|
+
return type(self) == type(other) and self.freq == other.freq
|
|
44
|
+
else:
|
|
45
|
+
return NotImplemented
|
|
46
|
+
|
|
47
|
+
def __ne__(self, other) -> bool:
|
|
48
|
+
return not self == other
|
|
49
|
+
|
|
50
|
+
def __hash__(self) -> int:
|
|
51
|
+
return hash((str(self), self.freq))
|
|
52
|
+
|
|
53
|
+
def to_pandas_dtype(self) -> PeriodDtype:
|
|
54
|
+
return PeriodDtype(freq=self.freq)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# register the type with a dummy instance
|
|
58
|
+
_period_type = ArrowPeriodType("D")
|
|
59
|
+
pyarrow.register_extension_type(_period_type)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ArrowIntervalType(pyarrow.ExtensionType):
|
|
63
|
+
def __init__(self, subtype, closed: IntervalClosedType) -> None:
|
|
64
|
+
# attributes need to be set first before calling
|
|
65
|
+
# super init (as that calls serialize)
|
|
66
|
+
assert closed in VALID_CLOSED
|
|
67
|
+
self._closed: IntervalClosedType = closed
|
|
68
|
+
if not isinstance(subtype, pyarrow.DataType):
|
|
69
|
+
subtype = pyarrow.type_for_alias(str(subtype))
|
|
70
|
+
self._subtype = subtype
|
|
71
|
+
|
|
72
|
+
storage_type = pyarrow.struct([("left", subtype), ("right", subtype)])
|
|
73
|
+
pyarrow.ExtensionType.__init__(self, storage_type, "pandas.interval")
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def subtype(self):
|
|
77
|
+
return self._subtype
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def closed(self) -> IntervalClosedType:
|
|
81
|
+
return self._closed
|
|
82
|
+
|
|
83
|
+
def __arrow_ext_serialize__(self) -> bytes:
|
|
84
|
+
metadata = {"subtype": str(self.subtype), "closed": self.closed}
|
|
85
|
+
return json.dumps(metadata).encode()
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def __arrow_ext_deserialize__(cls, storage_type, serialized) -> ArrowIntervalType:
|
|
89
|
+
metadata = json.loads(serialized.decode())
|
|
90
|
+
subtype = pyarrow.type_for_alias(metadata["subtype"])
|
|
91
|
+
closed = metadata["closed"]
|
|
92
|
+
return ArrowIntervalType(subtype, closed)
|
|
93
|
+
|
|
94
|
+
def __eq__(self, other):
|
|
95
|
+
if isinstance(other, pyarrow.BaseExtensionType):
|
|
96
|
+
return (
|
|
97
|
+
type(self) == type(other)
|
|
98
|
+
and self.subtype == other.subtype
|
|
99
|
+
and self.closed == other.closed
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
return NotImplemented
|
|
103
|
+
|
|
104
|
+
def __ne__(self, other) -> bool:
|
|
105
|
+
return not self == other
|
|
106
|
+
|
|
107
|
+
def __hash__(self) -> int:
|
|
108
|
+
return hash((str(self), str(self.subtype), self.closed))
|
|
109
|
+
|
|
110
|
+
def to_pandas_dtype(self) -> IntervalDtype:
|
|
111
|
+
return IntervalDtype(self.subtype.to_pandas_dtype(), self.closed)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# register the type with a dummy instance
|
|
115
|
+
_interval_type = ArrowIntervalType(pyarrow.int64(), "left")
|
|
116
|
+
pyarrow.register_extension_type(_interval_type)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
_ERROR_MSG = """\
|
|
120
|
+
Disallowed deserialization of 'arrow.py_extension_type':
|
|
121
|
+
storage_type = {storage_type}
|
|
122
|
+
serialized = {serialized}
|
|
123
|
+
pickle disassembly:\n{pickle_disassembly}
|
|
124
|
+
|
|
125
|
+
Reading of untrusted Parquet or Feather files with a PyExtensionType column
|
|
126
|
+
allows arbitrary code execution.
|
|
127
|
+
If you trust this file, you can enable reading the extension type by one of:
|
|
128
|
+
|
|
129
|
+
- upgrading to pyarrow >= 14.0.1, and call `pa.PyExtensionType.set_auto_load(True)`
|
|
130
|
+
- install pyarrow-hotfix (`pip install pyarrow-hotfix`) and disable it by running
|
|
131
|
+
`import pyarrow_hotfix; pyarrow_hotfix.uninstall()`
|
|
132
|
+
|
|
133
|
+
We strongly recommend updating your Parquet/Feather files to use extension types
|
|
134
|
+
derived from `pyarrow.ExtensionType` instead, and register this type explicitly.
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def patch_pyarrow() -> None:
|
|
139
|
+
# starting from pyarrow 14.0.1, it has its own mechanism
|
|
140
|
+
if not pa_version_under14p1:
|
|
141
|
+
return
|
|
142
|
+
|
|
143
|
+
# if https://github.com/pitrou/pyarrow-hotfix was installed and enabled
|
|
144
|
+
if getattr(pyarrow, "_hotfix_installed", False):
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
class ForbiddenExtensionType(pyarrow.ExtensionType):
|
|
148
|
+
def __arrow_ext_serialize__(self) -> bytes:
|
|
149
|
+
return b""
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def __arrow_ext_deserialize__(cls, storage_type, serialized):
|
|
153
|
+
import io
|
|
154
|
+
import pickletools
|
|
155
|
+
|
|
156
|
+
out = io.StringIO()
|
|
157
|
+
pickletools.dis(serialized, out)
|
|
158
|
+
raise RuntimeError(
|
|
159
|
+
_ERROR_MSG.format(
|
|
160
|
+
storage_type=storage_type,
|
|
161
|
+
serialized=serialized,
|
|
162
|
+
pickle_disassembly=out.getvalue(),
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
pyarrow.unregister_extension_type("arrow.py_extension_type")
|
|
167
|
+
pyarrow.register_extension_type(
|
|
168
|
+
ForbiddenExtensionType(pyarrow.null(), "arrow.py_extension_type")
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
pyarrow._hotfix_installed = True
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
patch_pyarrow()
|