dsh-compound-engineering 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +160 -2
- package/README.zh.md +161 -0
- package/cordis.patch.yml +6 -0
- package/lib/frontmatter.js +167 -0
- package/lib/index.js +46 -0
- package/lib/provider.js +201 -0
- package/package.json +62 -4
- package/skills/CODING_STANDARDS.md +68 -0
- package/skills/ce-babysit-pr/SKILL.md +59 -0
- package/skills/ce-babysit-pr/references/branch-currency.md +22 -0
- package/skills/ce-babysit-pr/references/envelope.md +44 -0
- package/skills/ce-babysit-pr/references/pipeline.md +15 -0
- package/skills/ce-babysit-pr/references/report.md +20 -0
- package/skills/ce-babysit-pr/references/settle.md +37 -0
- package/skills/ce-babysit-pr/references/setup.md +33 -0
- package/skills/ce-babysit-pr/references/stack-commands.md +39 -0
- package/skills/ce-babysit-pr/references/stack.md +43 -0
- package/skills/ce-babysit-pr/references/tick.md +102 -0
- package/skills/ce-babysit-pr/references/watch-loop.md +222 -0
- package/skills/ce-babysit-pr/scripts/pr-snapshot +3656 -0
- package/skills/ce-bakeoff/SKILL.md +48 -0
- package/skills/ce-bakeoff/references/candidates.md +37 -0
- package/skills/ce-bakeoff/references/judging.md +19 -0
- package/skills/ce-bakeoff/references/output.md +11 -0
- package/skills/ce-bakeoff/references/verification.md +15 -0
- package/skills/ce-brainstorm/SKILL.md +69 -0
- package/skills/ce-brainstorm/references/agents/slack-researcher.md +127 -0
- package/skills/ce-brainstorm/references/approaches.md +57 -0
- package/skills/ce-brainstorm/references/bakeoff.md +9 -0
- package/skills/ce-brainstorm/references/blindspot-pass.md +70 -0
- package/skills/ce-brainstorm/references/brainstorm-sections.md +458 -0
- package/skills/ce-brainstorm/references/dialogue.md +89 -0
- package/skills/ce-brainstorm/references/handoff.md +187 -0
- package/skills/ce-brainstorm/references/html-rendering.md +638 -0
- package/skills/ce-brainstorm/references/interaction-rules.md +33 -0
- package/skills/ce-brainstorm/references/markdown-rendering.md +242 -0
- package/skills/ce-brainstorm/references/model-tiers.md +13 -0
- package/skills/ce-brainstorm/references/output-mode.md +26 -0
- package/skills/ce-brainstorm/references/phase-0.md +104 -0
- package/skills/ce-brainstorm/references/plan-write.md +32 -0
- package/skills/ce-brainstorm/references/product-pressure-test.md +42 -0
- package/skills/ce-brainstorm/references/reasoning-elevation.md +124 -0
- package/skills/ce-brainstorm/references/settled-decisions.md +45 -0
- package/skills/ce-brainstorm/references/synthesis-summary.md +149 -0
- package/skills/ce-brainstorm/references/universal-brainstorming.md +72 -0
- package/skills/ce-brainstorm/references/verdict-routing.md +26 -0
- package/skills/ce-brainstorm/references/visual-probes.md +164 -0
- package/skills/ce-brainstorm/scripts/elevation-dispatch.sh +288 -0
- package/skills/ce-brainstorm/scripts/light-webserver.js +1275 -0
- package/skills/ce-brainstorm/scripts/packs-resolve.py +737 -0
- package/skills/ce-brainstorm/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-code-review/SKILL.md +40 -0
- package/skills/ce-code-review/references/action-class-rubric.md +67 -0
- package/skills/ce-code-review/references/cross-model-recovery.md +38 -0
- package/skills/ce-code-review/references/cross-model-review.md +191 -0
- package/skills/ce-code-review/references/depth-paths.md +32 -0
- package/skills/ce-code-review/references/diff-scope.md +59 -0
- package/skills/ce-code-review/references/dispatch-reviewers.md +135 -0
- package/skills/ce-code-review/references/findings-schema.json +125 -0
- package/skills/ce-code-review/references/finish-input.md +118 -0
- package/skills/ce-code-review/references/finish-review.md +202 -0
- package/skills/ce-code-review/references/intent-and-plan.md +73 -0
- package/skills/ce-code-review/references/modes-and-output.md +156 -0
- package/skills/ce-code-review/references/persona-catalog.md +66 -0
- package/skills/ce-code-review/references/personas/adversarial-reviewer.md +111 -0
- package/skills/ce-code-review/references/personas/agent-native-reviewer.md +173 -0
- package/skills/ce-code-review/references/personas/api-contract-reviewer.md +44 -0
- package/skills/ce-code-review/references/personas/correctness-reviewer.md +48 -0
- package/skills/ce-code-review/references/personas/data-migration-reviewer.md +111 -0
- package/skills/ce-code-review/references/personas/deployment-verification-agent.md +157 -0
- package/skills/ce-code-review/references/personas/julik-frontend-races-reviewer.md +45 -0
- package/skills/ce-code-review/references/personas/learnings-researcher.md +260 -0
- package/skills/ce-code-review/references/personas/maintainability-reviewer.md +85 -0
- package/skills/ce-code-review/references/personas/performance-reviewer.md +45 -0
- package/skills/ce-code-review/references/personas/previous-comments-reviewer.md +59 -0
- package/skills/ce-code-review/references/personas/project-standards-reviewer.md +77 -0
- package/skills/ce-code-review/references/personas/reliability-reviewer.md +49 -0
- package/skills/ce-code-review/references/personas/security-reviewer.md +50 -0
- package/skills/ce-code-review/references/personas/swift-ios-reviewer.md +99 -0
- package/skills/ce-code-review/references/personas/testing-reviewer.md +51 -0
- package/skills/ce-code-review/references/review-output-template.md +172 -0
- package/skills/ce-code-review/references/scope.md +176 -0
- package/skills/ce-code-review/references/select-and-route.md +93 -0
- package/skills/ce-code-review/references/subagent-template.md +206 -0
- package/skills/ce-code-review/references/validator-batch-template.md +67 -0
- package/skills/ce-code-review/scripts/cross-model-adversarial-review.sh +1275 -0
- package/skills/ce-code-review/scripts/findings-mechanics.py +274 -0
- package/skills/ce-code-review/scripts/packs-resolve.py +737 -0
- package/skills/ce-code-review/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-code-review/scripts/review-scope.py +419 -0
- package/skills/ce-code-review/scripts/run-log.py +280 -0
- package/skills/ce-commit/SKILL.md +60 -0
- package/skills/ce-commit-push-pr/SKILL.md +69 -0
- package/skills/ce-commit-push-pr/references/apply-and-handoff.md +79 -0
- package/skills/ce-commit-push-pr/references/branch-creation.md +47 -0
- package/skills/ce-commit-push-pr/references/commit-and-push.md +26 -0
- package/skills/ce-commit-push-pr/references/compose.md +29 -0
- package/skills/ce-commit-push-pr/references/context.md +42 -0
- package/skills/ce-commit-push-pr/references/gh-stack-cli.md +83 -0
- package/skills/ce-commit-push-pr/references/pr-description-writing.md +208 -0
- package/skills/ce-commit-push-pr/references/stack-submit.md +81 -0
- package/skills/ce-compound/SKILL.md +79 -0
- package/skills/ce-compound/assets/resolution-template.md +96 -0
- package/skills/ce-compound/references/agents/best-practices-researcher.md +115 -0
- package/skills/ce-compound/references/agents/data-integrity-guardian.md +68 -0
- package/skills/ce-compound/references/agents/framework-docs-researcher.md +93 -0
- package/skills/ce-compound/references/agents/pattern-recognition-specialist.md +55 -0
- package/skills/ce-compound/references/agents/performance-oracle.md +108 -0
- package/skills/ce-compound/references/agents/security-sentinel.md +91 -0
- package/skills/ce-compound/references/agents/session-historian.md +82 -0
- package/skills/ce-compound/references/assembly.md +127 -0
- package/skills/ce-compound/references/concepts-vocabulary.md +98 -0
- package/skills/ce-compound/references/enhancement.md +42 -0
- package/skills/ce-compound/references/grounding-validation.md +89 -0
- package/skills/ce-compound/references/lightweight.md +56 -0
- package/skills/ce-compound/references/modes.md +13 -0
- package/skills/ce-compound/references/refresh-and-discoverability.md +96 -0
- package/skills/ce-compound/references/report.md +115 -0
- package/skills/ce-compound/references/research.md +144 -0
- package/skills/ce-compound/references/schema.yaml +236 -0
- package/skills/ce-compound/references/session-history.md +73 -0
- package/skills/ce-compound/references/yaml-schema.md +130 -0
- package/skills/ce-compound/scripts/packs-resolve.py +737 -0
- package/skills/ce-compound/scripts/session-history/__pycache__/dsh_session.cpython-314.pyc +0 -0
- package/skills/ce-compound/scripts/session-history/discover-sessions.sh +290 -0
- package/skills/ce-compound/scripts/session-history/discover_dsh.py +123 -0
- package/skills/ce-compound/scripts/session-history/dsh_session.py +225 -0
- package/skills/ce-compound/scripts/session-history/extract-errors.py +178 -0
- package/skills/ce-compound/scripts/session-history/extract-metadata.py +301 -0
- package/skills/ce-compound/scripts/session-history/extract-skeleton.py +346 -0
- package/skills/ce-compound/scripts/validate-doc-claims.py +497 -0
- package/skills/ce-compound/scripts/validate-frontmatter.py +137 -0
- package/skills/ce-compound-refresh/SKILL.md +88 -0
- package/skills/ce-compound-refresh/assets/resolution-template.md +96 -0
- package/skills/ce-compound-refresh/references/classify.md +42 -0
- package/skills/ce-compound-refresh/references/commit.md +7 -0
- package/skills/ce-compound-refresh/references/concepts-vocabulary.md +116 -0
- package/skills/ce-compound-refresh/references/discoverability.md +15 -0
- package/skills/ce-compound-refresh/references/investigate.md +23 -0
- package/skills/ce-compound-refresh/references/modes.md +27 -0
- package/skills/ce-compound-refresh/references/per-action-flows.md +142 -0
- package/skills/ce-compound-refresh/references/report.md +23 -0
- package/skills/ce-compound-refresh/references/schema.yaml +236 -0
- package/skills/ce-compound-refresh/references/scope.md +18 -0
- package/skills/ce-compound-refresh/references/worth-audit.md +35 -0
- package/skills/ce-compound-refresh/references/yaml-schema.md +130 -0
- package/skills/ce-compound-refresh/scripts/validate-doc-claims.py +497 -0
- package/skills/ce-compound-refresh/scripts/validate-frontmatter.py +137 -0
- package/skills/ce-debug/SKILL.md +122 -0
- package/skills/ce-debug/references/anti-patterns.md +91 -0
- package/skills/ce-debug/references/defense-in-depth.md +39 -0
- package/skills/ce-debug/references/fix.md +21 -0
- package/skills/ce-debug/references/investigate.md +114 -0
- package/skills/ce-debug/references/investigation-techniques.md +384 -0
- package/skills/ce-debug/references/pipeline-mode.md +78 -0
- package/skills/ce-debug/references/post-fix-handoff.md +60 -0
- package/skills/ce-debug/references/return-to-caller.md +57 -0
- package/skills/ce-doc-review/SKILL.md +75 -0
- package/skills/ce-doc-review/references/bulk-preview.md +146 -0
- package/skills/ce-doc-review/references/cross-model-review.md +207 -0
- package/skills/ce-doc-review/references/decision-primer.md +47 -0
- package/skills/ce-doc-review/references/dispatch.md +56 -0
- package/skills/ce-doc-review/references/document-intake.md +44 -0
- package/skills/ce-doc-review/references/findings-schema.json +85 -0
- package/skills/ce-doc-review/references/modes.md +20 -0
- package/skills/ce-doc-review/references/open-questions-defer.md +158 -0
- package/skills/ce-doc-review/references/persona-selection.md +41 -0
- package/skills/ce-doc-review/references/personas/adversarial-document-reviewer.md +109 -0
- package/skills/ce-doc-review/references/personas/coherence-reviewer.md +69 -0
- package/skills/ce-doc-review/references/personas/design-lens-reviewer.md +48 -0
- package/skills/ce-doc-review/references/personas/feasibility-reviewer.md +50 -0
- package/skills/ce-doc-review/references/personas/product-lens-reviewer.md +85 -0
- package/skills/ce-doc-review/references/personas/scope-guardian-reviewer.md +83 -0
- package/skills/ce-doc-review/references/personas/security-lens-reviewer.md +41 -0
- package/skills/ce-doc-review/references/personas/whole-doc-reviewer.md +25 -0
- package/skills/ce-doc-review/references/rendering-floor.md +175 -0
- package/skills/ce-doc-review/references/review-output-template.md +123 -0
- package/skills/ce-doc-review/references/subagent-template.md +188 -0
- package/skills/ce-doc-review/references/synthesis-and-presentation.md +350 -0
- package/skills/ce-doc-review/references/walkthrough.md +347 -0
- package/skills/ce-doc-review/scripts/cross-model-doc-review.sh +1270 -0
- package/skills/ce-doc-review/scripts/packs-resolve.py +737 -0
- package/skills/ce-doc-review/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-dogfood/SKILL.md +66 -0
- package/skills/ce-dogfood/agents/openai.yaml +2 -0
- package/skills/ce-dogfood/references/dogfood-report-template.md +97 -0
- package/skills/ce-dogfood/references/phases.md +167 -0
- package/skills/ce-dogfood/references/test-matrix-taxonomy.md +62 -0
- package/skills/ce-dogfood/scripts/packs-resolve.py +737 -0
- package/skills/ce-explain/SKILL.md +81 -0
- package/skills/ce-explain/references/agents/behavior-trace-scout.md +19 -0
- package/skills/ce-explain/references/agents/work-recap-scout.md +23 -0
- package/skills/ce-explain/references/check-in.md +18 -0
- package/skills/ce-explain/references/destinations.md +35 -0
- package/skills/ce-explain/references/explainer-html.md +29 -0
- package/skills/ce-explain/references/explainer-markdown.md +24 -0
- package/skills/ce-explain/references/intake.md +50 -0
- package/skills/ce-explain/references/orchestration.md +46 -0
- package/skills/ce-handoff/SKILL.md +54 -0
- package/skills/ce-handoff/references/create.md +88 -0
- package/skills/ce-handoff/references/resume.md +46 -0
- package/skills/ce-ideate/SKILL.md +75 -0
- package/skills/ce-ideate/references/agents/issue-intelligence-analyst.md +166 -0
- package/skills/ce-ideate/references/agents/learnings-researcher.md +247 -0
- package/skills/ce-ideate/references/agents/slack-researcher.md +127 -0
- package/skills/ce-ideate/references/agents/web-researcher.md +121 -0
- package/skills/ce-ideate/references/decomposition.md +39 -0
- package/skills/ce-ideate/references/divergent-ideation.md +112 -0
- package/skills/ce-ideate/references/grounding.md +138 -0
- package/skills/ce-ideate/references/html-rendering.md +638 -0
- package/skills/ce-ideate/references/ideation-sections.md +191 -0
- package/skills/ce-ideate/references/issue-intelligence.md +44 -0
- package/skills/ce-ideate/references/markdown-rendering.md +242 -0
- package/skills/ce-ideate/references/output-mode.md +34 -0
- package/skills/ce-ideate/references/post-ideation-workflow.md +169 -0
- package/skills/ce-ideate/references/scope-gates.md +148 -0
- package/skills/ce-ideate/references/universal-ideation.md +119 -0
- package/skills/ce-ideate/references/user-research-artifacts.md +28 -0
- package/skills/ce-ideate/references/web-research-cache.md +56 -0
- package/skills/ce-noslop/SKILL.md +45 -0
- package/skills/ce-noslop/references/patterns.md +61 -0
- package/skills/ce-noslop/references/terminology.md +3 -0
- package/skills/ce-optimize/SKILL.md +64 -0
- package/skills/ce-optimize/references/agents/learnings-researcher.md +247 -0
- package/skills/ce-optimize/references/agents/repo-research-analyst.md +258 -0
- package/skills/ce-optimize/references/example-expensive-benchmark-spec.yaml +88 -0
- package/skills/ce-optimize/references/example-hard-spec.yaml +64 -0
- package/skills/ce-optimize/references/example-judge-spec.yaml +83 -0
- package/skills/ce-optimize/references/example-text-target-spec.yaml +80 -0
- package/skills/ce-optimize/references/experiment-log-schema.yaml +563 -0
- package/skills/ce-optimize/references/experiment-prompt-template.md +143 -0
- package/skills/ce-optimize/references/judge-prompt-template.md +117 -0
- package/skills/ce-optimize/references/loop.md +286 -0
- package/skills/ce-optimize/references/measurement.md +168 -0
- package/skills/ce-optimize/references/optimize-spec-schema.yaml +570 -0
- package/skills/ce-optimize/references/persistence.md +93 -0
- package/skills/ce-optimize/references/spec.md +107 -0
- package/skills/ce-optimize/references/text-targets.md +51 -0
- package/skills/ce-optimize/references/usage-guide.md +147 -0
- package/skills/ce-optimize/references/wrap-up.md +54 -0
- package/skills/ce-optimize/scripts/decide.mjs +676 -0
- package/skills/ce-optimize/scripts/experiment-worktree.sh +330 -0
- package/skills/ce-optimize/scripts/measure.sh +140 -0
- package/skills/ce-optimize/scripts/parallel-probe.sh +134 -0
- package/skills/ce-plan/SKILL.md +60 -0
- package/skills/ce-plan/references/agents/agent-native-planning-strategist.md +66 -0
- package/skills/ce-plan/references/agents/architecture-strategist.md +46 -0
- package/skills/ce-plan/references/agents/best-practices-researcher.md +118 -0
- package/skills/ce-plan/references/agents/data-integrity-guardian.md +68 -0
- package/skills/ce-plan/references/agents/framework-docs-researcher.md +97 -0
- package/skills/ce-plan/references/agents/git-history-analyzer.md +40 -0
- package/skills/ce-plan/references/agents/learnings-researcher.md +268 -0
- package/skills/ce-plan/references/agents/pattern-recognition-specialist.md +55 -0
- package/skills/ce-plan/references/agents/performance-oracle.md +108 -0
- package/skills/ce-plan/references/agents/repo-research-analyst.md +262 -0
- package/skills/ce-plan/references/agents/security-sentinel.md +91 -0
- package/skills/ce-plan/references/agents/slack-researcher.md +131 -0
- package/skills/ce-plan/references/agents/spec-flow-analyzer.md +84 -0
- package/skills/ce-plan/references/agents/web-researcher.md +125 -0
- package/skills/ce-plan/references/approach-altitude.md +55 -0
- package/skills/ce-plan/references/bakeoff.md +9 -0
- package/skills/ce-plan/references/deepening-workflow.md +263 -0
- package/skills/ce-plan/references/final-review.md +134 -0
- package/skills/ce-plan/references/html-rendering.md +638 -0
- package/skills/ce-plan/references/intake.md +158 -0
- package/skills/ce-plan/references/markdown-rendering.md +242 -0
- package/skills/ce-plan/references/output-contracts.md +29 -0
- package/skills/ce-plan/references/output-mode.md +45 -0
- package/skills/ce-plan/references/plan-handoff.md +116 -0
- package/skills/ce-plan/references/plan-sections.md +489 -0
- package/skills/ce-plan/references/reasoning-elevation.md +124 -0
- package/skills/ce-plan/references/research.md +211 -0
- package/skills/ce-plan/references/resume.md +61 -0
- package/skills/ce-plan/references/settled-decisions.md +45 -0
- package/skills/ce-plan/references/structure.md +207 -0
- package/skills/ce-plan/references/synthesis-summary.md +260 -0
- package/skills/ce-plan/references/universal-planning.md +170 -0
- package/skills/ce-plan/scripts/elevation-dispatch.sh +288 -0
- package/skills/ce-plan/scripts/packs-resolve.py +737 -0
- package/skills/ce-plan/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-polish/SKILL.md +22 -0
- package/skills/ce-polish/agents/openai.yaml +2 -0
- package/skills/ce-polish/references/dev-server-astro.md +58 -0
- package/skills/ce-polish/references/dev-server-detection.md +40 -0
- package/skills/ce-polish/references/dev-server-next.md +61 -0
- package/skills/ce-polish/references/dev-server-nuxt.md +58 -0
- package/skills/ce-polish/references/dev-server-procfile.md +59 -0
- package/skills/ce-polish/references/dev-server-rails.md +50 -0
- package/skills/ce-polish/references/dev-server-remix.md +58 -0
- package/skills/ce-polish/references/dev-server-sveltekit.md +58 -0
- package/skills/ce-polish/references/dev-server-vite.md +48 -0
- package/skills/ce-polish/references/install-riffrec.md +35 -0
- package/skills/ce-polish/references/launch-json-schema.md +177 -0
- package/skills/ce-polish/references/live-loop.md +98 -0
- package/skills/ce-polish/references/live-remote.md +35 -0
- package/skills/ce-polish/references/live-start.md +93 -0
- package/skills/ce-polish/references/live-stream-contract.md +253 -0
- package/skills/ce-polish/references/run.md +67 -0
- package/skills/ce-polish/scripts/detect-project-type.sh +277 -0
- package/skills/ce-polish/scripts/detect-riffrec.sh +225 -0
- package/skills/ce-polish/scripts/live-endpoint.js +2841 -0
- package/skills/ce-polish/scripts/read-launch-json.sh +117 -0
- package/skills/ce-polish/scripts/resolve-package-manager.sh +95 -0
- package/skills/ce-polish/scripts/resolve-port.sh +307 -0
- package/skills/ce-pov/SKILL.md +64 -0
- package/skills/ce-pov/references/agents/external-evidence-researcher.md +26 -0
- package/skills/ce-pov/references/agents/pov-peer.md +43 -0
- package/skills/ce-pov/references/agents/precedent-activity-scout.md +21 -0
- package/skills/ce-pov/references/agents/project-grounding-scout.md +32 -0
- package/skills/ce-pov/references/boundaries.md +36 -0
- package/skills/ce-pov/references/cross-model-panel.md +596 -0
- package/skills/ce-pov/references/followup.md +9 -0
- package/skills/ce-pov/references/grounding.md +47 -0
- package/skills/ce-pov/references/intake.md +61 -0
- package/skills/ce-pov/references/invocation.md +47 -0
- package/skills/ce-pov/references/method.md +68 -0
- package/skills/ce-pov/references/pov-schema.json +56 -0
- package/skills/ce-pov/references/report.md +7 -0
- package/skills/ce-pov/scripts/cross-model-pov.sh +1110 -0
- package/skills/ce-pov/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-product-pulse/SKILL.md +81 -0
- package/skills/ce-product-pulse/agents/openai.yaml +2 -0
- package/skills/ce-product-pulse/references/config.md +20 -0
- package/skills/ce-product-pulse/references/interview.md +260 -0
- package/skills/ce-product-pulse/references/report-template.md +89 -0
- package/skills/ce-product-pulse/references/run.md +46 -0
- package/skills/ce-product-pulse/references/setup.md +43 -0
- package/skills/ce-promote/SKILL.md +90 -0
- package/skills/ce-promote/agents/openai.yaml +2 -0
- package/skills/ce-promote/references/spiral-cli.md +149 -0
- package/skills/ce-proof/SKILL.md +65 -0
- package/skills/ce-proof/references/api.md +176 -0
- package/skills/ce-proof/references/workflows.md +124 -0
- package/skills/ce-prototype/SKILL.md +59 -0
- package/skills/ce-prototype/assets/annotate.css +206 -0
- package/skills/ce-prototype/assets/annotate.js +837 -0
- package/skills/ce-prototype/references/annotation-loop.md +32 -0
- package/skills/ce-prototype/references/build.md +39 -0
- package/skills/ce-prototype/references/craft-floor.md +43 -0
- package/skills/ce-prototype/references/preview.md +118 -0
- package/skills/ce-prototype/references/scoping.md +38 -0
- package/skills/ce-prototype/references/write-back.md +37 -0
- package/skills/ce-prototype/scripts/light-webserver.js +1275 -0
- package/skills/ce-resolve-pr-feedback/SKILL.md +60 -0
- package/skills/ce-resolve-pr-feedback/references/agents/pr-comment-resolver.md +59 -0
- package/skills/ce-resolve-pr-feedback/references/evaluation-rubric.md +141 -0
- package/skills/ce-resolve-pr-feedback/references/full-mode.md +336 -0
- package/skills/ce-resolve-pr-feedback/references/pipeline-mode.md +23 -0
- package/skills/ce-resolve-pr-feedback/references/resume.md +60 -0
- package/skills/ce-resolve-pr-feedback/references/return-to-caller.md +111 -0
- package/skills/ce-resolve-pr-feedback/references/targeted-mode.md +48 -0
- package/skills/ce-resolve-pr-feedback/scripts/get-pr-comments +176 -0
- package/skills/ce-resolve-pr-feedback/scripts/get-thread-for-comment +84 -0
- package/skills/ce-resolve-pr-feedback/scripts/pending-feedback.py +287 -0
- package/skills/ce-resolve-pr-feedback/scripts/reply-to-pr-thread +57 -0
- package/skills/ce-resolve-pr-feedback/scripts/resolve-pr-thread +23 -0
- package/skills/ce-retune/SKILL.md +42 -0
- package/skills/ce-retune/agents/openai.yaml +2 -0
- package/skills/ce-retune/references/baseline-mining.md +122 -0
- package/skills/ce-retune/references/corpus-audit.md +128 -0
- package/skills/ce-retune/references/cut-passes.md +129 -0
- package/skills/ce-retune/references/halt-taxonomy.md +123 -0
- package/skills/ce-retune/references/noise-floor.md +131 -0
- package/skills/ce-retune/references/workflow-shapes.md +73 -0
- package/skills/ce-riffrec-feedback-analysis/SKILL.md +33 -0
- package/skills/ce-riffrec-feedback-analysis/references/analyzer.md +18 -0
- package/skills/ce-riffrec-feedback-analysis/references/compound-engineering-feedback-format.md +116 -0
- package/skills/ce-riffrec-feedback-analysis/references/extensive-analysis.md +98 -0
- package/skills/ce-riffrec-feedback-analysis/references/install-riffrec.md +27 -0
- package/skills/ce-riffrec-feedback-analysis/references/quick-bug-report.md +38 -0
- package/skills/ce-riffrec-feedback-analysis/scripts/analyze_riffrec_zip.py +1306 -0
- package/skills/ce-setup/SKILL.md +103 -0
- package/skills/ce-setup/agents/openai.yaml +2 -0
- package/skills/ce-setup/assets/compounding-directive.md +11 -0
- package/skills/ce-setup/assets/noslop-directive.md +7 -0
- package/skills/ce-setup/assets/pack-rule-template.md +11 -0
- package/skills/ce-setup/references/acpx-cache-warm.md +14 -0
- package/skills/ce-setup/references/config-template.yaml +210 -0
- package/skills/ce-setup/references/legacy-codex-tool-map.md +15 -0
- package/skills/ce-setup/references/pack-scaffold.md +45 -0
- package/skills/ce-setup/references/repo-fixes.md +121 -0
- package/skills/ce-setup/scripts/check-health +929 -0
- package/skills/ce-setup/scripts/packs-resolve.py +737 -0
- package/skills/ce-simplify-code/SKILL.md +76 -0
- package/skills/ce-simplify-code/references/personas/code-quality-reviewer.md +17 -0
- package/skills/ce-simplify-code/references/personas/code-reuse-reviewer.md +7 -0
- package/skills/ce-simplify-code/references/personas/comment-reviewer.md +24 -0
- package/skills/ce-simplify-code/references/personas/efficiency-reviewer.md +11 -0
- package/skills/ce-simplify-code/references/personas/test-value-reviewer.md +23 -0
- package/skills/ce-simplify-code/references/reviewer-dispatch.md +11 -0
- package/skills/ce-simplify-code/references/standalone-report.md +25 -0
- package/skills/ce-strategy/SKILL.md +61 -0
- package/skills/ce-strategy/references/grounding.md +22 -0
- package/skills/ce-strategy/references/interview.md +179 -0
- package/skills/ce-strategy/references/strategy-template.md +94 -0
- package/skills/ce-strategy/references/update-run.md +33 -0
- package/skills/ce-sweep/SKILL.md +93 -0
- package/skills/ce-sweep/agents/openai.yaml +2 -0
- package/skills/ce-sweep/references/agents/media-analyzer.md +54 -0
- package/skills/ce-sweep/references/interview.md +208 -0
- package/skills/ce-sweep/references/model-tiers.md +13 -0
- package/skills/ce-sweep/references/plan-template.md +62 -0
- package/skills/ce-sweep/references/run.md +126 -0
- package/skills/ce-sweep/references/sources/email.md +57 -0
- package/skills/ce-sweep/references/sources/github-issues.md +59 -0
- package/skills/ce-sweep/references/sources/slack.md +61 -0
- package/skills/ce-sweep/references/state-schema.md +157 -0
- package/skills/ce-sweep/references/subagent-template.md +60 -0
- package/skills/ce-sweep/scripts/analyze_riffrec_zip.py +1306 -0
- package/skills/ce-sweep/scripts/sweep-state.py +793 -0
- package/skills/ce-test-browser/SKILL.md +50 -0
- package/skills/ce-test-browser/references/agent-browser-driver.md +47 -0
- package/skills/ce-test-browser/references/pipeline-orchestration.md +45 -0
- package/skills/ce-test-browser/references/route-and-report.md +129 -0
- package/skills/ce-test-browser/scripts/resolve-port.sh +41 -0
- package/skills/ce-test-xcode/SKILL.md +26 -0
- package/skills/ce-test-xcode/agents/openai.yaml +2 -0
- package/skills/ce-test-xcode/references/setup-and-build.md +32 -0
- package/skills/ce-test-xcode/references/test-and-report.md +64 -0
- package/skills/ce-work/SKILL.md +62 -0
- package/skills/ce-work/references/agents/figma-design-sync.md +27 -0
- package/skills/ce-work/references/agents/implementation-worker.md +17 -0
- package/skills/ce-work/references/cross-model-execution.md +191 -0
- package/skills/ce-work/references/execution-engines.md +64 -0
- package/skills/ce-work/references/execution-strategy.md +73 -0
- package/skills/ce-work/references/implementation-loop.md +107 -0
- package/skills/ce-work/references/implementation-result-schema.json +52 -0
- package/skills/ce-work/references/input-triage.md +50 -0
- package/skills/ce-work/references/non-code-execution.md +23 -0
- package/skills/ce-work/references/return-to-caller.md +33 -0
- package/skills/ce-work/references/review-findings-followup.md +82 -0
- package/skills/ce-work/references/shipping-workflow.md +89 -0
- package/skills/ce-work/references/tracker-defer.md +150 -0
- package/skills/ce-work/references/work-intake.md +51 -0
- package/skills/ce-work/references/workspace-setup.md +27 -0
- package/skills/ce-work/scripts/__pycache__/unit_workspace_jobs.cpython-314.pyc +0 -0
- package/skills/ce-work/scripts/__pycache__/unit_workspace_state.cpython-314.pyc +0 -0
- package/skills/ce-work/scripts/cross-model-work.sh +1385 -0
- package/skills/ce-work/scripts/peer-job-runner.py +2594 -0
- package/skills/ce-work/scripts/unit-workspace.py +215 -0
- package/skills/ce-work/scripts/unit_workspace_ignored.py +93 -0
- package/skills/ce-work/scripts/unit_workspace_integration.py +677 -0
- package/skills/ce-work/scripts/unit_workspace_jobs.py +1216 -0
- package/skills/ce-work/scripts/unit_workspace_lifecycle.py +981 -0
- package/skills/ce-work/scripts/unit_workspace_state.py +1379 -0
- package/skills/ce-work/scripts/unit_workspace_transaction.py +612 -0
- package/skills/ce-worktree/SKILL.md +54 -0
- package/skills/lfg/SKILL.md +59 -0
- package/skills/lfg/references/debug-return.md +25 -0
- package/skills/lfg/references/intake.md +30 -0
- package/skills/lfg/references/next-work-handoff.md +96 -0
- package/skills/lfg/references/plan-brief.md +36 -0
- package/skills/lfg/references/review-followup.md +78 -0
- package/skills/lfg/references/shipping.md +65 -0
- package/skills/lfg/references/stage-routing.md +49 -0
- package/skills/lfg/references/task-visibility.md +11 -0
- package/skills/lfg/references/tracker-defer.md +150 -0
- package/skills/lfg/references/work-return.md +27 -0
- package/skills/wtf/SKILL.md +33 -0
- package/skills/wtf/agents/openai.yaml +2 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract error signals from a DeepSeek Harness (dsh) session file.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python3 extract-errors.py <session-file> [--output PATH]
|
|
6
|
+
cat <session.jsonl> | python3 extract-errors.py
|
|
7
|
+
|
|
8
|
+
Passing the session path instead of piping through stdin is required for dsh
|
|
9
|
+
sessions, which are zstd-compressed containers of concatenated frames; the path
|
|
10
|
+
form decodes them through the bundled `dsh_session` reader. The stdin form only
|
|
11
|
+
works for already-decompressed JSONL (e.g. a dsh session piped through the
|
|
12
|
+
reader), and reports no errors when the stream is not dsh-shaped.
|
|
13
|
+
|
|
14
|
+
Finds failed tool calls / commands and outputs them with timestamps.
|
|
15
|
+
|
|
16
|
+
When --output PATH is given, the extracted error log is written to PATH and
|
|
17
|
+
stdout receives only a one-line JSON status (_meta with wrote/bytes/stats).
|
|
18
|
+
This lets callers route bulk content to a scratch file without round-tripping
|
|
19
|
+
extraction bytes through orchestrator tool results.
|
|
20
|
+
|
|
21
|
+
Without --output, extracted content goes to stdout and ends with a _meta line.
|
|
22
|
+
"""
|
|
23
|
+
import argparse
|
|
24
|
+
import io
|
|
25
|
+
import os
|
|
26
|
+
import sys
|
|
27
|
+
import json
|
|
28
|
+
|
|
29
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
30
|
+
|
|
31
|
+
import dsh_session # noqa: E402
|
|
32
|
+
|
|
33
|
+
parser = argparse.ArgumentParser(add_help=True)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"session_file",
|
|
36
|
+
nargs="?",
|
|
37
|
+
help="Session file to read. Omit to read JSONL from stdin. Required for compressed dsh sessions.",
|
|
38
|
+
)
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
"--output",
|
|
41
|
+
metavar="PATH",
|
|
42
|
+
help="Write extracted errors to PATH instead of stdout. Stdout receives a one-line _meta status.",
|
|
43
|
+
)
|
|
44
|
+
args = parser.parse_args()
|
|
45
|
+
|
|
46
|
+
# Session logs are UTF-8; force UTF-8 I/O so Windows' cp1252 default can't crash
|
|
47
|
+
# on non-Latin-1 content like emoji, smart quotes, or box-drawing (#1258).
|
|
48
|
+
# newline="\n" keeps bash-side consumers of our output (tr/xargs/grep) from
|
|
49
|
+
# seeing a Windows CRLF as part of the last field on every line.
|
|
50
|
+
sys.stdin.reconfigure(encoding="utf-8", errors="replace")
|
|
51
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace", newline="\n")
|
|
52
|
+
|
|
53
|
+
_original_stdout = sys.stdout
|
|
54
|
+
if args.output:
|
|
55
|
+
sys.stdout = io.StringIO()
|
|
56
|
+
|
|
57
|
+
stats = {"lines": 0, "parse_errors": 0, "errors_found": 0}
|
|
58
|
+
|
|
59
|
+
# Top-level record types only dsh emits. Anything else in the stream is a
|
|
60
|
+
# non-dsh or framework record we deliberately ignore.
|
|
61
|
+
_DSH_RECORD_TYPES = ("user/message", "assistant/message", "tool/result", "step/start")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def summarize_error(raw):
|
|
65
|
+
"""Extract a short error summary instead of dumping the full payload."""
|
|
66
|
+
text = str(raw).strip()
|
|
67
|
+
# Take the first non-empty line as the error message
|
|
68
|
+
for line in text.split("\n"):
|
|
69
|
+
line = line.strip()
|
|
70
|
+
if line:
|
|
71
|
+
return line[:200]
|
|
72
|
+
return text[:200]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _dsh_result_text(content):
|
|
76
|
+
"""Flatten a dsh tool-result payload into a one-line summary."""
|
|
77
|
+
if isinstance(content, str):
|
|
78
|
+
return summarize_error(content)
|
|
79
|
+
if isinstance(content, list):
|
|
80
|
+
parts = []
|
|
81
|
+
for block in content:
|
|
82
|
+
if isinstance(block, dict) and block.get("type") == "text":
|
|
83
|
+
parts.append(block.get("text", ""))
|
|
84
|
+
elif isinstance(block, str):
|
|
85
|
+
parts.append(block)
|
|
86
|
+
return summarize_error("\n".join(parts))
|
|
87
|
+
return summarize_error(content)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def handle_dsh(obj):
|
|
91
|
+
if obj.get("type") == "tool/result":
|
|
92
|
+
data = obj.get("data", {})
|
|
93
|
+
message = data.get("message", {})
|
|
94
|
+
content = message.get("content", [])
|
|
95
|
+
is_error = False
|
|
96
|
+
summary = ""
|
|
97
|
+
if isinstance(content, list):
|
|
98
|
+
for block in content:
|
|
99
|
+
if isinstance(block, dict) and block.get("type") == "tool-result":
|
|
100
|
+
if block.get("isError"):
|
|
101
|
+
is_error = True
|
|
102
|
+
summary = _dsh_result_text(block.get("content"))
|
|
103
|
+
# dsh also records structured failures outside the content blocks.
|
|
104
|
+
error = data.get("error")
|
|
105
|
+
if isinstance(error, dict):
|
|
106
|
+
is_error = True
|
|
107
|
+
if not summary:
|
|
108
|
+
summary = summarize_error(f"{error.get('name', 'error')}: {error.get('code', '')}")
|
|
109
|
+
if not is_error:
|
|
110
|
+
return
|
|
111
|
+
ts = dsh_session.iso_from_millis(obj.get("time"))[:19]
|
|
112
|
+
call_id = message.get("source", {}).get("callId", "")
|
|
113
|
+
print(f"[{ts}] [error] tool_call={call_id}: {summary}")
|
|
114
|
+
print("---")
|
|
115
|
+
stats["errors_found"] += 1
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def is_dsh_record(obj):
|
|
119
|
+
"""Report whether a parsed record can only come from a dsh session."""
|
|
120
|
+
t = obj.get("type")
|
|
121
|
+
if t in _DSH_RECORD_TYPES:
|
|
122
|
+
return True
|
|
123
|
+
# The session header is dsh only when it stamps createdAt in epoch millis;
|
|
124
|
+
# other harnesses open with an ISO `timestamp` string instead.
|
|
125
|
+
return t == "session" and isinstance(obj.get("createdAt"), (int, float))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Read the whole stream once: dsh decoding is not seekable, and error detection
|
|
129
|
+
# needs the full record set anyway.
|
|
130
|
+
objects = []
|
|
131
|
+
_source = None
|
|
132
|
+
_close_source = False
|
|
133
|
+
if args.session_file:
|
|
134
|
+
if dsh_session.is_session_file(args.session_file):
|
|
135
|
+
_source = dsh_session.read_lines(args.session_file)
|
|
136
|
+
elif dsh_session.available():
|
|
137
|
+
# A path we cannot decode as a dsh session has no dsh errors to report.
|
|
138
|
+
_source = []
|
|
139
|
+
else:
|
|
140
|
+
_source = open(args.session_file, "r", encoding="utf-8", errors="replace")
|
|
141
|
+
_close_source = True
|
|
142
|
+
else:
|
|
143
|
+
_source = sys.stdin
|
|
144
|
+
|
|
145
|
+
for line in _source:
|
|
146
|
+
line = line.strip()
|
|
147
|
+
if not line:
|
|
148
|
+
continue
|
|
149
|
+
stats["lines"] += 1
|
|
150
|
+
try:
|
|
151
|
+
obj = json.loads(line)
|
|
152
|
+
except (json.JSONDecodeError, KeyError):
|
|
153
|
+
stats["parse_errors"] += 1
|
|
154
|
+
continue
|
|
155
|
+
objects.append(obj)
|
|
156
|
+
|
|
157
|
+
if hasattr(_source, "close"):
|
|
158
|
+
_source.close()
|
|
159
|
+
|
|
160
|
+
# Only stream dsh records; a non-dsh session yields no findings rather than
|
|
161
|
+
# misparsed noise from another harness's schema.
|
|
162
|
+
for obj in objects:
|
|
163
|
+
if not is_dsh_record(obj):
|
|
164
|
+
continue
|
|
165
|
+
try:
|
|
166
|
+
handle_dsh(obj)
|
|
167
|
+
except KeyError:
|
|
168
|
+
stats["parse_errors"] += 1
|
|
169
|
+
|
|
170
|
+
print(json.dumps({"_meta": True, **stats}))
|
|
171
|
+
|
|
172
|
+
if args.output:
|
|
173
|
+
body = sys.stdout.getvalue()
|
|
174
|
+
sys.stdout = _original_stdout
|
|
175
|
+
with open(args.output, "w", encoding="utf-8", newline="\n") as f:
|
|
176
|
+
f.write(body)
|
|
177
|
+
bytes_written = os.path.getsize(args.output)
|
|
178
|
+
print(json.dumps({"_meta": True, "wrote": args.output, "bytes": bytes_written, **stats}))
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract session metadata from DeepSeek Harness (dsh) session files.
|
|
3
|
+
|
|
4
|
+
Batch mode (preferred — one invocation for all files):
|
|
5
|
+
python3 extract-metadata.py /path/to/dir/session-*.jsonl.zstd
|
|
6
|
+
python3 extract-metadata.py file1.jsonl.zstd file2.jsonl.zstd
|
|
7
|
+
|
|
8
|
+
Single-file mode (stdin):
|
|
9
|
+
head -20 <session.jsonl> | python3 extract-metadata.py
|
|
10
|
+
|
|
11
|
+
Detects dsh sessions from the JSONL structure. Non-dsh files are skipped.
|
|
12
|
+
Outputs one JSON object per file, one per line.
|
|
13
|
+
Includes a final _meta line with processing stats.
|
|
14
|
+
|
|
15
|
+
dsh sessions are zstd-compressed (`session*.jsonl.zstd`, one file per session
|
|
16
|
+
holding concatenated frames); they are decoded through `dsh_session.read_lines`
|
|
17
|
+
so every frame is read, not just the first. Decoding needs Python 3.14+
|
|
18
|
+
(`compression.zstd`); on older interpreters every file reports as unmatched.
|
|
19
|
+
"""
|
|
20
|
+
import sys
|
|
21
|
+
import json
|
|
22
|
+
import os
|
|
23
|
+
|
|
24
|
+
# LF-only line endings: callers may pipe our JSON lines through bash tools
|
|
25
|
+
# (tr/xargs/grep) where a Windows CRLF leaves a stray \r on every record.
|
|
26
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace", newline="\n")
|
|
27
|
+
|
|
28
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
29
|
+
|
|
30
|
+
import dsh_session # noqa: E402
|
|
31
|
+
|
|
32
|
+
MAX_LINES = 200 # Resumed dsh sessions front-load dozens of non-message records before the first user record
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def try_dsh(lines):
|
|
36
|
+
"""DeepSeek Harness sessions.
|
|
37
|
+
|
|
38
|
+
The dsh header is `{"type": "session", "cwd": ..., "createdAt": <epoch ms>}`.
|
|
39
|
+
`createdAt` in epoch milliseconds is the field that separates a dsh header
|
|
40
|
+
from any other harness that opens with a cwd-bearing session record.
|
|
41
|
+
"""
|
|
42
|
+
for line in lines:
|
|
43
|
+
try:
|
|
44
|
+
obj = json.loads(line.strip())
|
|
45
|
+
except (json.JSONDecodeError, KeyError):
|
|
46
|
+
continue
|
|
47
|
+
if obj.get("type") != "session" or "cwd" not in obj:
|
|
48
|
+
continue
|
|
49
|
+
if not isinstance(obj.get("createdAt"), (int, float)):
|
|
50
|
+
return None
|
|
51
|
+
return {
|
|
52
|
+
"platform": "dsh",
|
|
53
|
+
"cwd": obj.get("cwd", ""),
|
|
54
|
+
"session": obj.get("id", ""),
|
|
55
|
+
"ts": dsh_session.iso_from_millis(obj.get("createdAt")),
|
|
56
|
+
}
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def extract_from_lines(lines):
|
|
61
|
+
return try_dsh(lines)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_last_timestamp(filepath):
|
|
65
|
+
"""Return the ISO time of the last timestamped record in a dsh session."""
|
|
66
|
+
objects = dsh_session.read_objects(filepath)
|
|
67
|
+
for obj in reversed(objects):
|
|
68
|
+
stamp = dsh_session.iso_from_millis(obj.get("time"))
|
|
69
|
+
if stamp:
|
|
70
|
+
return stamp
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _extract_user_assistant_text(filepath):
|
|
75
|
+
"""Return concatenated user + assistant text content from a dsh session file.
|
|
76
|
+
|
|
77
|
+
Skips JSONL metadata field names and values (session id, timestamps, type
|
|
78
|
+
tags), tool calls, tool results, and thinking blocks. Only content the user
|
|
79
|
+
or the model actually said is included.
|
|
80
|
+
|
|
81
|
+
Without this filtering, common topic words like "session" would match every
|
|
82
|
+
session file via its id field, drowning out real content matches.
|
|
83
|
+
"""
|
|
84
|
+
chunks = []
|
|
85
|
+
if not dsh_session.is_session_file(filepath):
|
|
86
|
+
return ""
|
|
87
|
+
try:
|
|
88
|
+
objects = []
|
|
89
|
+
# dsh sessions are zstd-compressed and hold concatenated frames, so
|
|
90
|
+
# plain line iteration would yield binary garbage.
|
|
91
|
+
for line in dsh_session.read_lines(filepath):
|
|
92
|
+
try:
|
|
93
|
+
objects.append(json.loads(line.strip()))
|
|
94
|
+
except (json.JSONDecodeError, ValueError):
|
|
95
|
+
continue
|
|
96
|
+
|
|
97
|
+
for obj in objects:
|
|
98
|
+
t = obj.get("type")
|
|
99
|
+
|
|
100
|
+
# dsh: slash-tagged top-level records. User text lives at
|
|
101
|
+
# data.content[], assistant text at data.message.content[].
|
|
102
|
+
# dsh also stores framework context (runtime snapshots, the skill
|
|
103
|
+
# catalog, timestamps) as user rows, so only `source.kind == "user"`
|
|
104
|
+
# counts as something the person said.
|
|
105
|
+
if t == "user/message":
|
|
106
|
+
source = obj.get("data", {}).get("source")
|
|
107
|
+
if isinstance(source, dict) and source.get("kind") not in ("user", "goal"):
|
|
108
|
+
continue
|
|
109
|
+
chunks.extend(dsh_session.content_text(obj.get("data", {}).get("content")))
|
|
110
|
+
continue
|
|
111
|
+
if t == "assistant/message":
|
|
112
|
+
message = obj.get("data", {}).get("message", {})
|
|
113
|
+
chunks.extend(dsh_session.content_text(message.get("content")))
|
|
114
|
+
continue
|
|
115
|
+
except (OSError, IOError):
|
|
116
|
+
pass
|
|
117
|
+
return "\n".join(chunks)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def count_keyword_matches(filepath, keywords):
|
|
121
|
+
"""Case-insensitive substring count for each keyword in user/assistant text.
|
|
122
|
+
|
|
123
|
+
Returns a dict {original_keyword: count}. Scans only content the user or
|
|
124
|
+
assistant said — not JSONL metadata, tool calls, tool outputs, or thinking
|
|
125
|
+
blocks — so common topic words like "session" do not false-match against
|
|
126
|
+
the session id field.
|
|
127
|
+
"""
|
|
128
|
+
text_lower = _extract_user_assistant_text(filepath).lower()
|
|
129
|
+
return {kw: text_lower.count(kw.lower()) for kw in keywords}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def process_file(filepath):
|
|
133
|
+
"""Extract metadata only. Keyword scanning is done separately so callers
|
|
134
|
+
can apply cheap filters (e.g. --cwd-filter) before paying the full-file
|
|
135
|
+
content scan cost.
|
|
136
|
+
|
|
137
|
+
Returns (result, error): (dict, None) on success, (None, None) when the
|
|
138
|
+
file is readable but is not a dsh session, (None, filepath) on read error."""
|
|
139
|
+
try:
|
|
140
|
+
size = os.path.getsize(filepath)
|
|
141
|
+
if not dsh_session.is_session_file(filepath):
|
|
142
|
+
return None, None
|
|
143
|
+
if not dsh_session.available():
|
|
144
|
+
return None, None
|
|
145
|
+
lines = dsh_session.read_lines(filepath, MAX_LINES)
|
|
146
|
+
result = extract_from_lines(lines)
|
|
147
|
+
if result:
|
|
148
|
+
result["file"] = filepath
|
|
149
|
+
result["size"] = size
|
|
150
|
+
return result, None
|
|
151
|
+
else:
|
|
152
|
+
return None, None
|
|
153
|
+
except (OSError, IOError) as e:
|
|
154
|
+
return None, filepath
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _normalize_cwd(path):
|
|
158
|
+
path = path.replace("\\", "/").strip()
|
|
159
|
+
if len(path) > 1 and path.endswith("/") and not (
|
|
160
|
+
len(path) == 3 and path[1] == ":"
|
|
161
|
+
):
|
|
162
|
+
path = path.rstrip("/")
|
|
163
|
+
# Windows drive paths are case-insensitive. Do not rewrite POSIX /d/...
|
|
164
|
+
# to D:/ — those are different filesystems.
|
|
165
|
+
if len(path) >= 2 and path[1] == ":":
|
|
166
|
+
path = path[0].upper() + ":" + path[2:].casefold()
|
|
167
|
+
return path
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _is_abs_cwd(path):
|
|
171
|
+
if os.path.isabs(path):
|
|
172
|
+
return True
|
|
173
|
+
return len(path) >= 2 and path[1] == ":"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _cwd_paths_related(session_cwd, cwd_filter):
|
|
177
|
+
if session_cwd == cwd_filter:
|
|
178
|
+
return True
|
|
179
|
+
prefix = cwd_filter if cwd_filter.endswith("/") else cwd_filter + "/"
|
|
180
|
+
if session_cwd.startswith(prefix):
|
|
181
|
+
return True
|
|
182
|
+
prefix = session_cwd if session_cwd.endswith("/") else session_cwd + "/"
|
|
183
|
+
return cwd_filter.startswith(prefix)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _attach_timestamps(result, filepath):
|
|
187
|
+
# dsh already reported `createdAt` as ISO 8601; the last record's `time`
|
|
188
|
+
# is read separately because decompression is not seekable.
|
|
189
|
+
last_ts = get_last_timestamp(filepath)
|
|
190
|
+
if last_ts:
|
|
191
|
+
result["last_ts"] = last_ts
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def cwd_matches_filter(session_cwd, cwd_filter):
|
|
195
|
+
if not session_cwd or not cwd_filter:
|
|
196
|
+
return True
|
|
197
|
+
session = _normalize_cwd(session_cwd)
|
|
198
|
+
filt = _normalize_cwd(cwd_filter)
|
|
199
|
+
if not session or not filt:
|
|
200
|
+
return True
|
|
201
|
+
if _is_abs_cwd(filt):
|
|
202
|
+
return _cwd_paths_related(session, filt)
|
|
203
|
+
return filt in session.split("/")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
# Parse arguments: files and optional --cwd-filter / --keyword
|
|
207
|
+
files = []
|
|
208
|
+
cwd_filter = None
|
|
209
|
+
keywords = None
|
|
210
|
+
args = sys.argv[1:]
|
|
211
|
+
i = 0
|
|
212
|
+
while i < len(args):
|
|
213
|
+
if args[i] == "--cwd-filter" and i + 1 < len(args):
|
|
214
|
+
cwd_filter = args[i + 1]
|
|
215
|
+
i += 2
|
|
216
|
+
elif args[i] == "--keyword" and i + 1 < len(args):
|
|
217
|
+
keywords = [k for k in args[i + 1].split(",") if k]
|
|
218
|
+
i += 2
|
|
219
|
+
elif not args[i].startswith("-"):
|
|
220
|
+
files.append(args[i])
|
|
221
|
+
i += 1
|
|
222
|
+
else:
|
|
223
|
+
i += 1
|
|
224
|
+
|
|
225
|
+
if files:
|
|
226
|
+
# Batch mode: process all files
|
|
227
|
+
processed = 0
|
|
228
|
+
parse_errors = 0
|
|
229
|
+
no_metadata = 0
|
|
230
|
+
filtered = 0
|
|
231
|
+
matched = 0
|
|
232
|
+
for filepath in files:
|
|
233
|
+
if not dsh_session.is_session_file(filepath):
|
|
234
|
+
continue
|
|
235
|
+
result, error = process_file(filepath)
|
|
236
|
+
processed += 1
|
|
237
|
+
if result:
|
|
238
|
+
# Apply CWD filter first: cheap metadata-only check. Skip
|
|
239
|
+
# sessions from other repos before paying the full-file keyword
|
|
240
|
+
# scan cost — dsh discovery lists across projects, so without
|
|
241
|
+
# this ordering --keyword would scan files that are immediately
|
|
242
|
+
# discarded.
|
|
243
|
+
if cwd_filter:
|
|
244
|
+
session_cwd = result.get("cwd")
|
|
245
|
+
if session_cwd:
|
|
246
|
+
if not cwd_matches_filter(session_cwd, cwd_filter):
|
|
247
|
+
filtered += 1
|
|
248
|
+
continue
|
|
249
|
+
elif result.get("platform") == "dsh":
|
|
250
|
+
filtered += 1
|
|
251
|
+
continue
|
|
252
|
+
_attach_timestamps(result, filepath)
|
|
253
|
+
# Apply keyword scan only after cheap filters pass.
|
|
254
|
+
if keywords:
|
|
255
|
+
matches = count_keyword_matches(filepath, keywords)
|
|
256
|
+
result["keyword_matches"] = matches
|
|
257
|
+
result["match_count"] = sum(matches.values())
|
|
258
|
+
if result["match_count"] == 0:
|
|
259
|
+
continue
|
|
260
|
+
matched += 1
|
|
261
|
+
print(json.dumps(result))
|
|
262
|
+
elif error:
|
|
263
|
+
parse_errors += 1
|
|
264
|
+
else:
|
|
265
|
+
no_metadata += 1
|
|
266
|
+
|
|
267
|
+
meta = {"_meta": True, "files_processed": processed, "parse_errors": parse_errors}
|
|
268
|
+
if no_metadata:
|
|
269
|
+
meta["files_without_metadata"] = no_metadata
|
|
270
|
+
if filtered:
|
|
271
|
+
meta["filtered_by_cwd"] = filtered
|
|
272
|
+
if keywords:
|
|
273
|
+
meta["files_matched"] = matched
|
|
274
|
+
print(json.dumps(meta))
|
|
275
|
+
else:
|
|
276
|
+
# No file arguments: either single-file stdin mode or empty xargs invocation.
|
|
277
|
+
# When xargs runs us with no input (e.g., discover found no files), stdin is
|
|
278
|
+
# empty or a TTY — emit a clean zero-file result instead of a false parse error.
|
|
279
|
+
if sys.stdin.isatty():
|
|
280
|
+
lines = []
|
|
281
|
+
else:
|
|
282
|
+
lines = list(sys.stdin)
|
|
283
|
+
|
|
284
|
+
if not lines:
|
|
285
|
+
# No input at all — zero-file result (clean exit for empty pipelines).
|
|
286
|
+
# When --keyword was supplied, emit files_matched: 0 so callers relying
|
|
287
|
+
# on its presence to terminate quickly in zero-match scans see a
|
|
288
|
+
# consistent shape with the batch-mode no-match case.
|
|
289
|
+
meta = {"_meta": True, "files_processed": 0, "parse_errors": 0}
|
|
290
|
+
if keywords:
|
|
291
|
+
meta["files_matched"] = 0
|
|
292
|
+
print(json.dumps(meta))
|
|
293
|
+
else:
|
|
294
|
+
# Genuine single-file stdin mode (backward compatible)
|
|
295
|
+
result = extract_from_lines(lines)
|
|
296
|
+
meta = {"_meta": True, "files_processed": 1, "parse_errors": 0}
|
|
297
|
+
if result:
|
|
298
|
+
print(json.dumps(result))
|
|
299
|
+
else:
|
|
300
|
+
meta["files_without_metadata"] = 1
|
|
301
|
+
print(json.dumps(meta))
|