@slope-dev/slope 1.5.1
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 +243 -0
- package/dist/cli/commands/auto-card.d.ts +2 -0
- package/dist/cli/commands/auto-card.d.ts.map +1 -0
- package/dist/cli/commands/auto-card.js +267 -0
- package/dist/cli/commands/auto-card.js.map +1 -0
- package/dist/cli/commands/briefing.d.ts +2 -0
- package/dist/cli/commands/briefing.d.ts.map +1 -0
- package/dist/cli/commands/briefing.js +133 -0
- package/dist/cli/commands/briefing.js.map +1 -0
- package/dist/cli/commands/card.d.ts +2 -0
- package/dist/cli/commands/card.d.ts.map +1 -0
- package/dist/cli/commands/card.js +144 -0
- package/dist/cli/commands/card.js.map +1 -0
- package/dist/cli/commands/claim.d.ts +2 -0
- package/dist/cli/commands/claim.d.ts.map +1 -0
- package/dist/cli/commands/claim.js +99 -0
- package/dist/cli/commands/claim.js.map +1 -0
- package/dist/cli/commands/classify.d.ts +2 -0
- package/dist/cli/commands/classify.d.ts.map +1 -0
- package/dist/cli/commands/classify.js +70 -0
- package/dist/cli/commands/classify.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +4 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +156 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/distill.d.ts +2 -0
- package/dist/cli/commands/distill.d.ts.map +1 -0
- package/dist/cli/commands/distill.js +91 -0
- package/dist/cli/commands/distill.js.map +1 -0
- package/dist/cli/commands/escalate.d.ts +2 -0
- package/dist/cli/commands/escalate.d.ts.map +1 -0
- package/dist/cli/commands/escalate.js +136 -0
- package/dist/cli/commands/escalate.js.map +1 -0
- package/dist/cli/commands/extract.d.ts +2 -0
- package/dist/cli/commands/extract.d.ts.map +1 -0
- package/dist/cli/commands/extract.js +147 -0
- package/dist/cli/commands/extract.js.map +1 -0
- package/dist/cli/commands/flows.d.ts +2 -0
- package/dist/cli/commands/flows.d.ts.map +1 -0
- package/dist/cli/commands/flows.js +156 -0
- package/dist/cli/commands/flows.js.map +1 -0
- package/dist/cli/commands/guard.d.ts +15 -0
- package/dist/cli/commands/guard.d.ts.map +1 -0
- package/dist/cli/commands/guard.js +207 -0
- package/dist/cli/commands/guard.js.map +1 -0
- package/dist/cli/commands/hook.d.ts +2 -0
- package/dist/cli/commands/hook.d.ts.map +1 -0
- package/dist/cli/commands/hook.js +299 -0
- package/dist/cli/commands/hook.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +421 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/map.d.ts +10 -0
- package/dist/cli/commands/map.d.ts.map +1 -0
- package/dist/cli/commands/map.js +591 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/next.d.ts +2 -0
- package/dist/cli/commands/next.d.ts.map +1 -0
- package/dist/cli/commands/next.js +28 -0
- package/dist/cli/commands/next.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +54 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +2 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +118 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/release.d.ts +2 -0
- package/dist/cli/commands/release.d.ts.map +1 -0
- package/dist/cli/commands/release.js +64 -0
- package/dist/cli/commands/release.js.map +1 -0
- package/dist/cli/commands/report.d.ts +2 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +68 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/review-state.d.ts +11 -0
- package/dist/cli/commands/review-state.d.ts.map +1 -0
- package/dist/cli/commands/review-state.js +193 -0
- package/dist/cli/commands/review-state.js.map +1 -0
- package/dist/cli/commands/review.d.ts +2 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +53 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/roadmap.d.ts +2 -0
- package/dist/cli/commands/roadmap.d.ts.map +1 -0
- package/dist/cli/commands/roadmap.js +283 -0
- package/dist/cli/commands/roadmap.js.map +1 -0
- package/dist/cli/commands/session.d.ts +2 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +232 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/standup.d.ts +2 -0
- package/dist/cli/commands/standup.d.ts.map +1 -0
- package/dist/cli/commands/standup.js +117 -0
- package/dist/cli/commands/standup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +148 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/tournament.d.ts +2 -0
- package/dist/cli/commands/tournament.d.ts.map +1 -0
- package/dist/cli/commands/tournament.js +60 -0
- package/dist/cli/commands/tournament.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +2 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +74 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +2 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/guards/commit-nudge.d.ts +7 -0
- package/dist/cli/guards/commit-nudge.d.ts.map +1 -0
- package/dist/cli/guards/commit-nudge.js +50 -0
- package/dist/cli/guards/commit-nudge.js.map +1 -0
- package/dist/cli/guards/compaction.d.ts +8 -0
- package/dist/cli/guards/compaction.d.ts.map +1 -0
- package/dist/cli/guards/compaction.js +79 -0
- package/dist/cli/guards/compaction.js.map +1 -0
- package/dist/cli/guards/explore.d.ts +8 -0
- package/dist/cli/guards/explore.d.ts.map +1 -0
- package/dist/cli/guards/explore.js +78 -0
- package/dist/cli/guards/explore.js.map +1 -0
- package/dist/cli/guards/hazard.d.ts +7 -0
- package/dist/cli/guards/hazard.d.ts.map +1 -0
- package/dist/cli/guards/hazard.js +43 -0
- package/dist/cli/guards/hazard.js.map +1 -0
- package/dist/cli/guards/next-action.d.ts +28 -0
- package/dist/cli/guards/next-action.d.ts.map +1 -0
- package/dist/cli/guards/next-action.js +196 -0
- package/dist/cli/guards/next-action.js.map +1 -0
- package/dist/cli/guards/push-nudge.d.ts +7 -0
- package/dist/cli/guards/push-nudge.d.ts.map +1 -0
- package/dist/cli/guards/push-nudge.js +53 -0
- package/dist/cli/guards/push-nudge.js.map +1 -0
- package/dist/cli/guards/review-tier.d.ts +7 -0
- package/dist/cli/guards/review-tier.d.ts.map +1 -0
- package/dist/cli/guards/review-tier.js +108 -0
- package/dist/cli/guards/review-tier.js.map +1 -0
- package/dist/cli/guards/scope-drift.d.ts +7 -0
- package/dist/cli/guards/scope-drift.d.ts.map +1 -0
- package/dist/cli/guards/scope-drift.js +47 -0
- package/dist/cli/guards/scope-drift.js.map +1 -0
- package/dist/cli/guards/stop-check.d.ts +7 -0
- package/dist/cli/guards/stop-check.d.ts.map +1 -0
- package/dist/cli/guards/stop-check.js +34 -0
- package/dist/cli/guards/stop-check.js.map +1 -0
- package/dist/cli/guards/subagent-gate.d.ts +7 -0
- package/dist/cli/guards/subagent-gate.d.ts.map +1 -0
- package/dist/cli/guards/subagent-gate.js +39 -0
- package/dist/cli/guards/subagent-gate.js.map +1 -0
- package/dist/cli/guards/version-check.d.ts +8 -0
- package/dist/cli/guards/version-check.d.ts.map +1 -0
- package/dist/cli/guards/version-check.js +49 -0
- package/dist/cli/guards/version-check.js.map +1 -0
- package/dist/cli/guards/workflow-gate.d.ts +7 -0
- package/dist/cli/guards/workflow-gate.d.ts.map +1 -0
- package/dist/cli/guards/workflow-gate.js +31 -0
- package/dist/cli/guards/workflow-gate.js.map +1 -0
- package/dist/cli/hooks-config.d.ts +9 -0
- package/dist/cli/hooks-config.d.ts.map +1 -0
- package/dist/cli/hooks-config.js +21 -0
- package/dist/cli/hooks-config.js.map +1 -0
- package/dist/cli/index.d.ts +19 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +282 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/loader.d.ts +2 -0
- package/dist/cli/loader.d.ts.map +1 -0
- package/dist/cli/loader.js +2 -0
- package/dist/cli/loader.js.map +1 -0
- package/dist/cli/metaphor.d.ts +6 -0
- package/dist/cli/metaphor.d.ts.map +1 -0
- package/dist/cli/metaphor.js +26 -0
- package/dist/cli/metaphor.js.map +1 -0
- package/dist/cli/registries/api-registry.d.ts +11 -0
- package/dist/cli/registries/api-registry.d.ts.map +1 -0
- package/dist/cli/registries/api-registry.js +42 -0
- package/dist/cli/registries/api-registry.js.map +1 -0
- package/dist/cli/registries/file-registry.d.ts +13 -0
- package/dist/cli/registries/file-registry.d.ts.map +1 -0
- package/dist/cli/registries/file-registry.js +55 -0
- package/dist/cli/registries/file-registry.js.map +1 -0
- package/dist/cli/registries/index.d.ts +7 -0
- package/dist/cli/registries/index.d.ts.map +1 -0
- package/dist/cli/registries/index.js +20 -0
- package/dist/cli/registries/index.js.map +1 -0
- package/dist/cli/store.d.ts +3 -0
- package/dist/cli/store.d.ts.map +1 -0
- package/dist/cli/store.js +13 -0
- package/dist/cli/store.js.map +1 -0
- package/dist/cli/template-generator.d.ts +15 -0
- package/dist/cli/template-generator.d.ts.map +1 -0
- package/dist/cli/template-generator.js +562 -0
- package/dist/cli/template-generator.js.map +1 -0
- package/dist/core/advisor.d.ts +63 -0
- package/dist/core/advisor.d.ts.map +1 -0
- package/dist/core/advisor.js +395 -0
- package/dist/core/advisor.js.map +1 -0
- package/dist/core/briefing.d.ts +103 -0
- package/dist/core/briefing.d.ts.map +1 -0
- package/dist/core/briefing.js +380 -0
- package/dist/core/briefing.js.map +1 -0
- package/dist/core/builder.d.ts +70 -0
- package/dist/core/builder.d.ts.map +1 -0
- package/dist/core/builder.js +175 -0
- package/dist/core/builder.js.map +1 -0
- package/dist/core/ci-signals.d.ts +10 -0
- package/dist/core/ci-signals.d.ts.map +1 -0
- package/dist/core/ci-signals.js +145 -0
- package/dist/core/ci-signals.js.map +1 -0
- package/dist/core/config.d.ts +48 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +42 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +14 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +44 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/dashboard.d.ts +40 -0
- package/dist/core/dashboard.d.ts.map +1 -0
- package/dist/core/dashboard.js +413 -0
- package/dist/core/dashboard.js.map +1 -0
- package/dist/core/dispersion.d.ts +12 -0
- package/dist/core/dispersion.d.ts.map +1 -0
- package/dist/core/dispersion.js +164 -0
- package/dist/core/dispersion.js.map +1 -0
- package/dist/core/escalation.d.ts +52 -0
- package/dist/core/escalation.d.ts.map +1 -0
- package/dist/core/escalation.js +105 -0
- package/dist/core/escalation.js.map +1 -0
- package/dist/core/flows.d.ts +44 -0
- package/dist/core/flows.d.ts.map +1 -0
- package/dist/core/flows.js +123 -0
- package/dist/core/flows.js.map +1 -0
- package/dist/core/formatter.d.ts +23 -0
- package/dist/core/formatter.d.ts.map +1 -0
- package/dist/core/formatter.js +301 -0
- package/dist/core/formatter.js.map +1 -0
- package/dist/core/guard.d.ts +124 -0
- package/dist/core/guard.d.ts.map +1 -0
- package/dist/core/guard.js +185 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/handicap.d.ts +22 -0
- package/dist/core/handicap.d.ts.map +1 -0
- package/dist/core/handicap.js +111 -0
- package/dist/core/handicap.js.map +1 -0
- package/dist/core/index.d.ts +55 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +62 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/leaderboard.d.ts +32 -0
- package/dist/core/leaderboard.d.ts.map +1 -0
- package/dist/core/leaderboard.js +98 -0
- package/dist/core/leaderboard.js.map +1 -0
- package/dist/core/loader.d.ts +17 -0
- package/dist/core/loader.d.ts.map +1 -0
- package/dist/core/loader.js +68 -0
- package/dist/core/loader.js.map +1 -0
- package/dist/core/metaphor.d.ts +73 -0
- package/dist/core/metaphor.d.ts.map +1 -0
- package/dist/core/metaphor.js +73 -0
- package/dist/core/metaphor.js.map +1 -0
- package/dist/core/metaphors/baseball.d.ts +3 -0
- package/dist/core/metaphors/baseball.d.ts.map +1 -0
- package/dist/core/metaphors/baseball.js +89 -0
- package/dist/core/metaphors/baseball.js.map +1 -0
- package/dist/core/metaphors/dnd.d.ts +3 -0
- package/dist/core/metaphors/dnd.d.ts.map +1 -0
- package/dist/core/metaphors/dnd.js +89 -0
- package/dist/core/metaphors/dnd.js.map +1 -0
- package/dist/core/metaphors/gaming.d.ts +3 -0
- package/dist/core/metaphors/gaming.d.ts.map +1 -0
- package/dist/core/metaphors/gaming.js +89 -0
- package/dist/core/metaphors/gaming.js.map +1 -0
- package/dist/core/metaphors/golf.d.ts +3 -0
- package/dist/core/metaphors/golf.d.ts.map +1 -0
- package/dist/core/metaphors/golf.js +89 -0
- package/dist/core/metaphors/golf.js.map +1 -0
- package/dist/core/metaphors/index.d.ts +8 -0
- package/dist/core/metaphors/index.d.ts.map +1 -0
- package/dist/core/metaphors/index.js +17 -0
- package/dist/core/metaphors/index.js.map +1 -0
- package/dist/core/metaphors/matrix.d.ts +3 -0
- package/dist/core/metaphors/matrix.d.ts.map +1 -0
- package/dist/core/metaphors/matrix.js +89 -0
- package/dist/core/metaphors/matrix.js.map +1 -0
- package/dist/core/metaphors/tennis.d.ts +3 -0
- package/dist/core/metaphors/tennis.d.ts.map +1 -0
- package/dist/core/metaphors/tennis.js +89 -0
- package/dist/core/metaphors/tennis.js.map +1 -0
- package/dist/core/pipeline.d.ts +39 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +158 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/player.d.ts +51 -0
- package/dist/core/player.d.ts.map +1 -0
- package/dist/core/player.js +101 -0
- package/dist/core/player.js.map +1 -0
- package/dist/core/plugins.d.ts +33 -0
- package/dist/core/plugins.d.ts.map +1 -0
- package/dist/core/plugins.js +176 -0
- package/dist/core/plugins.js.map +1 -0
- package/dist/core/pr-signals.d.ts +23 -0
- package/dist/core/pr-signals.d.ts.map +1 -0
- package/dist/core/pr-signals.js +178 -0
- package/dist/core/pr-signals.js.map +1 -0
- package/dist/core/registry.d.ts +20 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +62 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/report.d.ts +50 -0
- package/dist/core/report.d.ts.map +1 -0
- package/dist/core/report.js +392 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/roadmap.d.ts +74 -0
- package/dist/core/roadmap.d.ts.map +1 -0
- package/dist/core/roadmap.js +389 -0
- package/dist/core/roadmap.js.map +1 -0
- package/dist/core/roles.d.ts +23 -0
- package/dist/core/roles.d.ts.map +1 -0
- package/dist/core/roles.js +107 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/standup.d.ts +44 -0
- package/dist/core/standup.d.ts.map +1 -0
- package/dist/core/standup.js +164 -0
- package/dist/core/standup.js.map +1 -0
- package/dist/core/store.d.ts +43 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +11 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/team-handicap.d.ts +59 -0
- package/dist/core/team-handicap.d.ts.map +1 -0
- package/dist/core/team-handicap.js +227 -0
- package/dist/core/team-handicap.js.map +1 -0
- package/dist/core/tournament.d.ts +12 -0
- package/dist/core/tournament.d.ts.map +1 -0
- package/dist/core/tournament.js +249 -0
- package/dist/core/tournament.js.map +1 -0
- package/dist/core/types.d.ts +339 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validation.d.ts +23 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +140 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +17 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +363 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/index.test.d.ts +2 -0
- package/dist/mcp/index.test.d.ts.map +1 -0
- package/dist/mcp/index.test.js +497 -0
- package/dist/mcp/index.test.js.map +1 -0
- package/dist/mcp/registry.d.ts +17 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +708 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/sandbox.d.ts +15 -0
- package/dist/mcp/sandbox.d.ts.map +1 -0
- package/dist/mcp/sandbox.js +153 -0
- package/dist/mcp/sandbox.js.map +1 -0
- package/dist/store/index.d.ts +40 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +324 -0
- package/dist/store/index.js.map +1 -0
- package/dist/tokens/colors.d.ts +47 -0
- package/dist/tokens/colors.d.ts.map +1 -0
- package/dist/tokens/colors.js +56 -0
- package/dist/tokens/colors.js.map +1 -0
- package/dist/tokens/css.d.ts +3 -0
- package/dist/tokens/css.d.ts.map +1 -0
- package/dist/tokens/css.js +58 -0
- package/dist/tokens/css.js.map +1 -0
- package/dist/tokens/index.d.ts +5 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +6 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/spacing.d.ts +23 -0
- package/dist/tokens/spacing.d.ts.map +1 -0
- package/dist/tokens/spacing.js +28 -0
- package/dist/tokens/spacing.js.map +1 -0
- package/dist/tokens/typography.d.ts +28 -0
- package/dist/tokens/typography.d.ts.map +1 -0
- package/dist/tokens/typography.js +34 -0
- package/dist/tokens/typography.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/cli/guards/compaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Explore guard: fires on Read|Glob|Grep (PreToolUse).
|
|
4
|
+
* Suggests checking codebase map before deep exploration.
|
|
5
|
+
* Includes staleness awareness when CODEBASE.md has YAML frontmatter.
|
|
6
|
+
*/
|
|
7
|
+
export declare function exploreGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
8
|
+
//# sourceMappingURL=explore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/explore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKlE;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAyCtF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import { loadConfig } from '../config.js';
|
|
5
|
+
const DEFAULT_INDEX_PATHS = ['CODEBASE.md', '.slope/index.json', 'docs/architecture.md'];
|
|
6
|
+
/**
|
|
7
|
+
* Explore guard: fires on Read|Glob|Grep (PreToolUse).
|
|
8
|
+
* Suggests checking codebase map before deep exploration.
|
|
9
|
+
* Includes staleness awareness when CODEBASE.md has YAML frontmatter.
|
|
10
|
+
*/
|
|
11
|
+
export async function exploreGuard(input, cwd) {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const indexPaths = config.guidance?.indexPaths ?? DEFAULT_INDEX_PATHS;
|
|
14
|
+
// Find which index files exist
|
|
15
|
+
const found = [];
|
|
16
|
+
for (const p of indexPaths) {
|
|
17
|
+
const full = join(cwd, p);
|
|
18
|
+
if (existsSync(full)) {
|
|
19
|
+
found.push(p);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (found.length === 0) {
|
|
23
|
+
return {}; // No index — passthrough
|
|
24
|
+
}
|
|
25
|
+
// Check if CODEBASE.md exists and assess staleness
|
|
26
|
+
const mapPath = join(cwd, 'CODEBASE.md');
|
|
27
|
+
if (existsSync(mapPath)) {
|
|
28
|
+
const staleness = checkMapStaleness(mapPath, cwd);
|
|
29
|
+
if (staleness === 'stale') {
|
|
30
|
+
return {
|
|
31
|
+
context: `SLOPE: Codebase map at CODEBASE.md is stale (${getStalenessDetail(mapPath, cwd)}). Run 'slope map' to refresh, or explore if needed.`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Current map — estimate token size
|
|
35
|
+
const content = readFileSync(mapPath, 'utf8');
|
|
36
|
+
const approxTokens = Math.round(content.length / 4 / 1000);
|
|
37
|
+
return {
|
|
38
|
+
context: `SLOPE: Codebase map at CODEBASE.md (~${approxTokens}k tokens). Read it or use search({ module: 'map' }) before exploring.`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// Fallback: other index files found but no CODEBASE.md
|
|
42
|
+
return {
|
|
43
|
+
context: `SLOPE: Codebase index available at: ${found.join(', ')} — check before deep exploration.`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function checkMapStaleness(mapPath, cwd) {
|
|
47
|
+
try {
|
|
48
|
+
const content = readFileSync(mapPath, 'utf8');
|
|
49
|
+
const metaMatch = content.match(/^---\n([\s\S]*?)\n---/m);
|
|
50
|
+
if (!metaMatch)
|
|
51
|
+
return 'current'; // No metadata — can't check
|
|
52
|
+
const gitShaMatch = metaMatch[1].match(/git_sha:\s*"?([^"\n]+)"?/);
|
|
53
|
+
if (!gitShaMatch)
|
|
54
|
+
return 'current';
|
|
55
|
+
const distance = parseInt(execSync(`git rev-list --count ${gitShaMatch[1]}..HEAD 2>/dev/null`, { cwd, encoding: 'utf8', timeout: 5000 }).trim() || '0', 10);
|
|
56
|
+
return distance > 50 ? 'stale' : 'current';
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return 'current'; // Can't determine — assume current
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function getStalenessDetail(mapPath, cwd) {
|
|
63
|
+
try {
|
|
64
|
+
const content = readFileSync(mapPath, 'utf8');
|
|
65
|
+
const metaMatch = content.match(/^---\n([\s\S]*?)\n---/m);
|
|
66
|
+
if (!metaMatch)
|
|
67
|
+
return 'unknown';
|
|
68
|
+
const gitShaMatch = metaMatch[1].match(/git_sha:\s*"?([^"\n]+)"?/);
|
|
69
|
+
if (!gitShaMatch)
|
|
70
|
+
return 'unknown';
|
|
71
|
+
const distance = execSync(`git rev-list --count ${gitShaMatch[1]}..HEAD 2>/dev/null`, { cwd, encoding: 'utf8', timeout: 5000 }).trim();
|
|
72
|
+
return `${distance} commits behind`;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return 'unknown';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=explore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../../../src/cli/guards/explore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Hazard guard: fires on Edit|Write (PreToolUse).
|
|
4
|
+
* Warns about known issues in the file area being edited.
|
|
5
|
+
*/
|
|
6
|
+
export declare function hazardGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
7
|
+
//# sourceMappingURL=hazard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazard.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/hazard.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIlE;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqCrF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { loadConfig } from '../config.js';
|
|
4
|
+
/**
|
|
5
|
+
* Hazard guard: fires on Edit|Write (PreToolUse).
|
|
6
|
+
* Warns about known issues in the file area being edited.
|
|
7
|
+
*/
|
|
8
|
+
export async function hazardGuard(input, cwd) {
|
|
9
|
+
const filePath = input.tool_input?.file_path;
|
|
10
|
+
if (!filePath)
|
|
11
|
+
return {};
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const recency = config.guidance?.hazardRecency ?? 5;
|
|
14
|
+
// Determine the area from the file path (use directory)
|
|
15
|
+
const area = dirname(filePath).replace(cwd + '/', '').replace(cwd, '');
|
|
16
|
+
if (!area || area === '.')
|
|
17
|
+
return {};
|
|
18
|
+
// Load common issues and find matches
|
|
19
|
+
const warnings = [];
|
|
20
|
+
try {
|
|
21
|
+
const issuesPath = join(cwd, config.commonIssuesPath);
|
|
22
|
+
if (existsSync(issuesPath)) {
|
|
23
|
+
const issues = JSON.parse(readFileSync(issuesPath, 'utf8'));
|
|
24
|
+
const areaLower = area.toLowerCase();
|
|
25
|
+
for (const pattern of issues.recurring_patterns) {
|
|
26
|
+
// Check if pattern is relevant to this area
|
|
27
|
+
const text = `${pattern.title} ${pattern.description} ${pattern.prevention}`.toLowerCase();
|
|
28
|
+
if (text.includes(areaLower) || areaLower.split('/').some(seg => text.includes(seg))) {
|
|
29
|
+
const lastSprint = Math.max(...pattern.sprints_hit);
|
|
30
|
+
warnings.push(`[${pattern.category}] ${pattern.title} (last: S${lastSprint}) — ${pattern.prevention.slice(0, 100)}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch { /* skip — common issues are optional */ }
|
|
36
|
+
if (warnings.length === 0)
|
|
37
|
+
return {};
|
|
38
|
+
const header = `SLOPE hazard warning for ${area}:`;
|
|
39
|
+
return {
|
|
40
|
+
context: [header, ...warnings.map(w => ` ${w}`)].join('\n'),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=hazard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazard.js","sourceRoot":"","sources":["../../../src/cli/guards/hazard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAgB,EAAE,GAAW;IAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,SAA+B,CAAC;IACnE,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,aAAa,IAAI,CAAC,CAAC;IAEpD,wDAAwD;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvE,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAErC,sCAAsC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAqB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAErC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAChD,4CAA4C;gBAC5C,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC3F,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBACrF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;oBACpD,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,KAAK,YAAY,UAAU,OAAO,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBACvH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,uCAAuC,CAAC,CAAC;IAEnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,4BAA4B,IAAI,GAAG,CAAC;IACnD,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;KAC7D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/** Sprint state types for next-action detection */
|
|
3
|
+
type SprintState = {
|
|
4
|
+
type: 'mid-sprint';
|
|
5
|
+
sprintNumber: number;
|
|
6
|
+
claimCount: number;
|
|
7
|
+
targets: string[];
|
|
8
|
+
} | {
|
|
9
|
+
type: 'sprint-complete';
|
|
10
|
+
sprintNumber: number;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'needs-review';
|
|
13
|
+
sprintNumber: number;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'between-sprints';
|
|
16
|
+
roadmapContext?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Next-action guard: fires on Stop.
|
|
20
|
+
* Suggests next actions before session end based on sprint state.
|
|
21
|
+
*/
|
|
22
|
+
export declare function nextActionGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
23
|
+
/** Detect current sprint state via store then filesystem fallback */
|
|
24
|
+
export declare function detectSprintState(cwd: string): Promise<SprintState>;
|
|
25
|
+
/** Build block reason text from sprint state */
|
|
26
|
+
export declare function buildSuggestions(state: SprintState): string;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=next-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-action.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/next-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAe,MAAM,qBAAqB,CAAC;AAI/E,mDAAmD;AACnD,KAAK,WAAW,GACZ;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GACnF;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmCzF;AAED,qEAAqE;AACrE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAiEzE;AAuBD,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAqE3D"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { loadConfig, detectLatestSprint, parseRoadmap, formatStrategicContext } from '../../core/index.js';
|
|
4
|
+
import { resolveStore } from '../store.js';
|
|
5
|
+
/**
|
|
6
|
+
* Next-action guard: fires on Stop.
|
|
7
|
+
* Suggests next actions before session end based on sprint state.
|
|
8
|
+
*/
|
|
9
|
+
export async function nextActionGuard(input, cwd) {
|
|
10
|
+
// Re-prompt prevention: check if we already prompted this session
|
|
11
|
+
const slopeDir = join(cwd, '.slope');
|
|
12
|
+
const stateFile = join(slopeDir, '.next-action-prompted');
|
|
13
|
+
if (input.session_id) {
|
|
14
|
+
try {
|
|
15
|
+
if (existsSync(stateFile)) {
|
|
16
|
+
const raw = JSON.parse(readFileSync(stateFile, 'utf8'));
|
|
17
|
+
if (raw.session_id === input.session_id) {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch { /* corrupted state file — proceed */ }
|
|
23
|
+
}
|
|
24
|
+
// Detect sprint state
|
|
25
|
+
const state = await detectSprintState(cwd);
|
|
26
|
+
// Build suggestion text
|
|
27
|
+
const suggestion = buildSuggestions(state);
|
|
28
|
+
// Write state file atomically
|
|
29
|
+
try {
|
|
30
|
+
mkdirSync(slopeDir, { recursive: true });
|
|
31
|
+
const tmpPath = join(slopeDir, '.next-action-prompted.tmp');
|
|
32
|
+
const json = JSON.stringify({
|
|
33
|
+
session_id: input.session_id,
|
|
34
|
+
prompted_at: new Date().toISOString(),
|
|
35
|
+
});
|
|
36
|
+
writeFileSync(tmpPath, json);
|
|
37
|
+
renameSync(tmpPath, stateFile);
|
|
38
|
+
}
|
|
39
|
+
catch { /* best-effort — don't fail the guard */ }
|
|
40
|
+
return { blockReason: suggestion };
|
|
41
|
+
}
|
|
42
|
+
/** Detect current sprint state via store then filesystem fallback */
|
|
43
|
+
export async function detectSprintState(cwd) {
|
|
44
|
+
// Try store first for active claims
|
|
45
|
+
let claimsFromStore = null;
|
|
46
|
+
try {
|
|
47
|
+
const store = await resolveStore(cwd);
|
|
48
|
+
try {
|
|
49
|
+
const claims = await store.getActiveClaims();
|
|
50
|
+
if (claims.length > 0) {
|
|
51
|
+
const sprintNumber = Math.max(...claims.map(c => c.sprint_number));
|
|
52
|
+
return {
|
|
53
|
+
type: 'mid-sprint',
|
|
54
|
+
sprintNumber,
|
|
55
|
+
claimCount: claims.length,
|
|
56
|
+
targets: claims.map(c => c.target),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
claimsFromStore = claims;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
store.close();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Store unavailable — try filesystem fallback
|
|
67
|
+
try {
|
|
68
|
+
const claimsPath = join(cwd, '.slope', 'claims.json');
|
|
69
|
+
if (existsSync(claimsPath)) {
|
|
70
|
+
const raw = JSON.parse(readFileSync(claimsPath, 'utf8'));
|
|
71
|
+
if (Array.isArray(raw) && raw.length > 0) {
|
|
72
|
+
const sprintNumber = Math.max(...raw.map((c) => c.sprint_number ?? 0));
|
|
73
|
+
return {
|
|
74
|
+
type: 'mid-sprint',
|
|
75
|
+
sprintNumber,
|
|
76
|
+
claimCount: raw.length,
|
|
77
|
+
targets: raw.map((c) => c.target ?? 'unknown'),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch { /* filesystem fallback failed */ }
|
|
83
|
+
}
|
|
84
|
+
// Load config and scorecards for remaining checks
|
|
85
|
+
let config;
|
|
86
|
+
try {
|
|
87
|
+
config = loadConfig(cwd);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { type: 'between-sprints' };
|
|
91
|
+
}
|
|
92
|
+
const latestScoredSprint = detectLatestSprint(config, cwd);
|
|
93
|
+
// If no claims and no scorecards, we're between sprints
|
|
94
|
+
if (latestScoredSprint === 0 && (claimsFromStore === null || claimsFromStore.length === 0)) {
|
|
95
|
+
return buildBetweenSprints(config, cwd, 0);
|
|
96
|
+
}
|
|
97
|
+
// Check if the latest sprint has a review
|
|
98
|
+
if (latestScoredSprint > 0) {
|
|
99
|
+
const retrosDir = join(cwd, config.scorecardDir);
|
|
100
|
+
const reviewPath = join(retrosDir, `sprint-${latestScoredSprint}-review.md`);
|
|
101
|
+
if (!existsSync(reviewPath)) {
|
|
102
|
+
return { type: 'needs-review', sprintNumber: latestScoredSprint };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Default: between sprints
|
|
106
|
+
return buildBetweenSprints(config, cwd, latestScoredSprint);
|
|
107
|
+
}
|
|
108
|
+
/** Build between-sprints state with optional roadmap context */
|
|
109
|
+
function buildBetweenSprints(config, cwd, latestSprint) {
|
|
110
|
+
let roadmapContext;
|
|
111
|
+
try {
|
|
112
|
+
if (config.roadmapPath) {
|
|
113
|
+
const roadmapFile = join(cwd, config.roadmapPath);
|
|
114
|
+
if (existsSync(roadmapFile)) {
|
|
115
|
+
const raw = JSON.parse(readFileSync(roadmapFile, 'utf8'));
|
|
116
|
+
const { roadmap } = parseRoadmap(raw);
|
|
117
|
+
if (roadmap) {
|
|
118
|
+
const nextSprint = latestSprint + 1;
|
|
119
|
+
const ctx = formatStrategicContext(roadmap, nextSprint);
|
|
120
|
+
if (ctx)
|
|
121
|
+
roadmapContext = ctx;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch { /* roadmap parsing failed — proceed without context */ }
|
|
127
|
+
return { type: 'between-sprints', roadmapContext };
|
|
128
|
+
}
|
|
129
|
+
/** Build block reason text from sprint state */
|
|
130
|
+
export function buildSuggestions(state) {
|
|
131
|
+
const header = 'SLOPE next-action: Before ending this session, present the user with options for what to do next.';
|
|
132
|
+
switch (state.type) {
|
|
133
|
+
case 'mid-sprint': {
|
|
134
|
+
const targetList = state.targets.join(', ');
|
|
135
|
+
return [
|
|
136
|
+
header,
|
|
137
|
+
'',
|
|
138
|
+
`Current state: Mid-sprint — ${state.claimCount} active claim(s) for sprint ${state.sprintNumber}: ${targetList}`,
|
|
139
|
+
'',
|
|
140
|
+
'Suggested options:',
|
|
141
|
+
'1. Continue with the next ticket',
|
|
142
|
+
'2. Push and take a break — resume later',
|
|
143
|
+
'3. End session — nothing more to do right now',
|
|
144
|
+
'',
|
|
145
|
+
'Present these using AskUserQuestion. If the user chooses to end the session, stop without further action.',
|
|
146
|
+
].join('\n');
|
|
147
|
+
}
|
|
148
|
+
case 'sprint-complete':
|
|
149
|
+
return [
|
|
150
|
+
header,
|
|
151
|
+
'',
|
|
152
|
+
`Current state: Sprint ${state.sprintNumber} is complete but unscored`,
|
|
153
|
+
'',
|
|
154
|
+
'Suggested options:',
|
|
155
|
+
'1. Score the sprint — run post-hole routine',
|
|
156
|
+
'2. Run `slope validate` on the scorecard',
|
|
157
|
+
'3. Distill learnings into common issues',
|
|
158
|
+
'4. End session — nothing more to do right now',
|
|
159
|
+
'',
|
|
160
|
+
'Present these using AskUserQuestion. If the user chooses to end the session, stop without further action.',
|
|
161
|
+
].join('\n');
|
|
162
|
+
case 'needs-review': {
|
|
163
|
+
return [
|
|
164
|
+
header,
|
|
165
|
+
'',
|
|
166
|
+
`Current state: Sprint ${state.sprintNumber} has a scorecard but no review`,
|
|
167
|
+
'',
|
|
168
|
+
'Suggested options:',
|
|
169
|
+
'1. Generate sprint review',
|
|
170
|
+
'2. Distill learnings and update common issues',
|
|
171
|
+
'3. Run `slope review` for the full sprint review',
|
|
172
|
+
'4. End session — nothing more to do right now',
|
|
173
|
+
'',
|
|
174
|
+
'Present these using AskUserQuestion. If the user chooses to end the session, stop without further action.',
|
|
175
|
+
].join('\n');
|
|
176
|
+
}
|
|
177
|
+
case 'between-sprints': {
|
|
178
|
+
const contextLine = state.roadmapContext
|
|
179
|
+
? `\n${state.roadmapContext}\n`
|
|
180
|
+
: '';
|
|
181
|
+
return [
|
|
182
|
+
header,
|
|
183
|
+
'',
|
|
184
|
+
`Current state: No active sprint${contextLine}`,
|
|
185
|
+
'Suggested options:',
|
|
186
|
+
'1. Check next sprint candidates from the roadmap',
|
|
187
|
+
'2. Start a new sprint',
|
|
188
|
+
'3. Run `slope briefing` for a status overview',
|
|
189
|
+
'4. End session — nothing more to do right now',
|
|
190
|
+
'',
|
|
191
|
+
'Present these using AskUserQuestion. If the user chooses to end the session, stop without further action.',
|
|
192
|
+
].join('\n');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=next-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-action.js","sourceRoot":"","sources":["../../../src/cli/guards/next-action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Push nudge guard: fires PostToolUse on Bash.
|
|
4
|
+
* Nudges to push after git commit commands when unpushed count or time is high.
|
|
5
|
+
*/
|
|
6
|
+
export declare function pushNudgeGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
7
|
+
//# sourceMappingURL=push-nudge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-nudge.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/push-nudge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlE;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAgDxF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { loadConfig } from '../config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Push nudge guard: fires PostToolUse on Bash.
|
|
5
|
+
* Nudges to push after git commit commands when unpushed count or time is high.
|
|
6
|
+
*/
|
|
7
|
+
export async function pushNudgeGuard(input, cwd) {
|
|
8
|
+
const command = input.tool_input?.command ?? '';
|
|
9
|
+
// Only fire after git commit commands
|
|
10
|
+
if (!command.includes('git commit'))
|
|
11
|
+
return {};
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const guidance = config.guidance ?? {};
|
|
14
|
+
const pushCommitThreshold = guidance.pushCommitThreshold ?? 5;
|
|
15
|
+
const pushInterval = guidance.pushInterval ?? 30;
|
|
16
|
+
const nudges = [];
|
|
17
|
+
// Check if on main/master — always nudge (should push or switch branch)
|
|
18
|
+
try {
|
|
19
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD 2>/dev/null', { cwd, encoding: 'utf8' }).trim();
|
|
20
|
+
if (branch === 'main' || branch === 'master') {
|
|
21
|
+
nudges.push(`Committing directly on ${branch} — consider pushing or switching to a feature branch.`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch { /* not a git repo */ }
|
|
25
|
+
// Check unpushed commit count
|
|
26
|
+
try {
|
|
27
|
+
const unpushed = execSync('git log @{u}..HEAD --oneline 2>/dev/null', { cwd, encoding: 'utf8' }).trim();
|
|
28
|
+
if (unpushed) {
|
|
29
|
+
const count = unpushed.split('\n').filter(Boolean).length;
|
|
30
|
+
if (count >= pushCommitThreshold) {
|
|
31
|
+
nudges.push(`${count} unpushed commits — push to preserve your recovery point.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch { /* no upstream */ }
|
|
36
|
+
// Check time since oldest unpushed commit
|
|
37
|
+
try {
|
|
38
|
+
const oldest = execSync('git log @{u}..HEAD --format=%ct --reverse 2>/dev/null', { cwd, encoding: 'utf8' }).trim().split('\n')[0];
|
|
39
|
+
if (oldest) {
|
|
40
|
+
const minutesSince = (Date.now() / 1000 - parseInt(oldest, 10)) / 60;
|
|
41
|
+
if (minutesSince >= pushInterval) {
|
|
42
|
+
nudges.push(`~${Math.round(minutesSince)} minutes since oldest unpushed commit — push now.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch { /* no upstream */ }
|
|
47
|
+
if (nudges.length === 0)
|
|
48
|
+
return {};
|
|
49
|
+
return {
|
|
50
|
+
context: `SLOPE push discipline:\n${nudges.map(n => ` ${n}`).join('\n')}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=push-nudge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-nudge.js","sourceRoot":"","sources":["../../../src/cli/guards/push-nudge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAgB,EAAE,GAAW;IAChE,MAAM,OAAO,GAAI,KAAK,CAAC,UAAU,EAAE,OAAkB,IAAI,EAAE,CAAC;IAE5D,sCAAsC;IACtC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvC,MAAM,mBAAmB,GAAG,QAAQ,CAAC,mBAAmB,IAAI,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC;IAEjD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,wEAAwE;IACxE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,6CAA6C,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzG,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,uDAAuD,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAEhC,8BAA8B;IAC9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,0CAA0C,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxG,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC1D,IAAI,KAAK,IAAI,mBAAmB,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,2DAA2D,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAE7B,0CAA0C;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,uDAAuD,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAClI,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YACrE,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,mDAAmD,CAAC,CAAC;YAC/F,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,OAAO;QACL,OAAO,EAAE,2BAA2B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KAC3E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Review-tier guard: fires PreToolUse on ExitPlanMode.
|
|
4
|
+
* Recommends a review tier based on plan scope (context-only, never deny).
|
|
5
|
+
*/
|
|
6
|
+
export declare function reviewTierGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
7
|
+
//# sourceMappingURL=review-tier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-tier.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/review-tier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAQlE;;;GAGG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuDzF"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Review-tier guard: fires PreToolUse on ExitPlanMode.
|
|
5
|
+
* Recommends a review tier based on plan scope (context-only, never deny).
|
|
6
|
+
*/
|
|
7
|
+
export async function reviewTierGuard(input, cwd) {
|
|
8
|
+
// Find the plan file
|
|
9
|
+
const planContent = findPlanContent(input, cwd);
|
|
10
|
+
if (!planContent)
|
|
11
|
+
return {};
|
|
12
|
+
// Analyze the plan
|
|
13
|
+
const ticketCount = countTickets(planContent);
|
|
14
|
+
const packageRefs = countPackageRefs(planContent);
|
|
15
|
+
const hasSchemaOrApi = /\b(schema|migration|api|endpoint)\b/i.test(planContent);
|
|
16
|
+
const hasInfra = /\b(infrastructure|new package|new service|architect)\b/i.test(planContent);
|
|
17
|
+
const isResearchOrDocs = /^#+\s*(research|docs|documentation|infra|spike)\b/im.test(planContent)
|
|
18
|
+
&& ticketCount === 0;
|
|
19
|
+
// Determine recommended tier
|
|
20
|
+
let tier;
|
|
21
|
+
let rounds;
|
|
22
|
+
if (isResearchOrDocs || ticketCount === 0) {
|
|
23
|
+
tier = 'Skip';
|
|
24
|
+
rounds = 0;
|
|
25
|
+
}
|
|
26
|
+
else if (ticketCount <= 2 && packageRefs <= 1) {
|
|
27
|
+
tier = 'Light';
|
|
28
|
+
rounds = 1;
|
|
29
|
+
}
|
|
30
|
+
else if (ticketCount >= 5 || hasInfra) {
|
|
31
|
+
tier = 'Deep';
|
|
32
|
+
rounds = 3;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// 3-4 tickets, or multi-package, or schema/API changes
|
|
36
|
+
tier = 'Standard';
|
|
37
|
+
rounds = 2;
|
|
38
|
+
}
|
|
39
|
+
// Check if review-state.json already matches
|
|
40
|
+
const statePath = join(cwd, '.slope', 'review-state.json');
|
|
41
|
+
if (existsSync(statePath)) {
|
|
42
|
+
try {
|
|
43
|
+
const state = JSON.parse(readFileSync(statePath, 'utf8'));
|
|
44
|
+
if (state.rounds_required >= rounds) {
|
|
45
|
+
// Already set to at least the recommended level — silent passthrough
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch { /* malformed — proceed with recommendation */ }
|
|
50
|
+
}
|
|
51
|
+
// Build context message
|
|
52
|
+
const scopeDesc = [
|
|
53
|
+
`${ticketCount} ticket${ticketCount !== 1 ? 's' : ''}`,
|
|
54
|
+
packageRefs > 1 ? `${packageRefs} packages` : null,
|
|
55
|
+
hasSchemaOrApi ? 'schema/API changes' : null,
|
|
56
|
+
hasInfra ? 'new infrastructure' : null,
|
|
57
|
+
].filter(Boolean).join(', ');
|
|
58
|
+
return {
|
|
59
|
+
context: `SLOPE review-tier: Plan has ${scopeDesc} — recommend ${tier} review (${rounds} round${rounds !== 1 ? 's' : ''}). Set rounds_required: ${rounds} in .slope/review-state.json`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function findPlanContent(input, cwd) {
|
|
63
|
+
// Try to find plan file from tool_input (ExitPlanMode context)
|
|
64
|
+
// Claude Code stores plans in .claude/plans/
|
|
65
|
+
const plansDir = join(cwd, '.claude', 'plans');
|
|
66
|
+
if (existsSync(plansDir)) {
|
|
67
|
+
// Find the most recently modified .md file
|
|
68
|
+
try {
|
|
69
|
+
const files = readdirSync(plansDir)
|
|
70
|
+
.filter(f => f.endsWith('.md'))
|
|
71
|
+
.map(f => ({
|
|
72
|
+
name: f,
|
|
73
|
+
path: join(plansDir, f),
|
|
74
|
+
mtime: (() => { try {
|
|
75
|
+
return statSync(join(plansDir, f)).mtimeMs;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return 0;
|
|
79
|
+
} })(),
|
|
80
|
+
}))
|
|
81
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
82
|
+
if (files.length > 0) {
|
|
83
|
+
return readFileSync(files[0].path, 'utf8');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch { /* no plans dir or can't read */ }
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
function countTickets(content) {
|
|
91
|
+
// Match ticket patterns: ### S\d+-\d+, ### Ticket, numbered ticket headers
|
|
92
|
+
const ticketHeaders = content.match(/^###\s+S\d+-\d+/gm) ?? [];
|
|
93
|
+
if (ticketHeaders.length > 0)
|
|
94
|
+
return ticketHeaders.length;
|
|
95
|
+
// Fallback: count ### level headers that look like tickets
|
|
96
|
+
const h3Headers = content.match(/^###\s+/gm) ?? [];
|
|
97
|
+
return h3Headers.length;
|
|
98
|
+
}
|
|
99
|
+
function countPackageRefs(content) {
|
|
100
|
+
// Count distinct packages/ references
|
|
101
|
+
const refs = new Set();
|
|
102
|
+
const matches = content.matchAll(/packages\/(\w[\w-]*)/g);
|
|
103
|
+
for (const m of matches) {
|
|
104
|
+
refs.add(m[1]);
|
|
105
|
+
}
|
|
106
|
+
return refs.size;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=review-tier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-tier.js","sourceRoot":"","sources":["../../../src/cli/guards/review-tier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAgB,EAAE,GAAW;IACjE,qBAAqB;IACrB,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,mBAAmB;IACnB,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,sCAAsC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,yDAAyD,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7F,MAAM,gBAAgB,GAAG,qDAAqD,CAAC,IAAI,CAAC,WAAW,CAAC;WAC3F,WAAW,KAAK,CAAC,CAAC;IAEvB,6BAA6B;IAC7B,IAAI,IAAY,CAAC;IACjB,IAAI,MAAc,CAAC;IAEnB,IAAI,gBAAgB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QAC1C,IAAI,GAAG,MAAM,CAAC;QACd,MAAM,GAAG,CAAC,CAAC;IACb,CAAC;SAAM,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,OAAO,CAAC;QACf,MAAM,GAAG,CAAC,CAAC;IACb,CAAC;SAAM,IAAI,WAAW,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxC,IAAI,GAAG,MAAM,CAAC;QACd,MAAM,GAAG,CAAC,CAAC;IACb,CAAC;SAAM,CAAC;QACN,uDAAuD;QACvD,IAAI,GAAG,UAAU,CAAC;QAClB,MAAM,GAAG,CAAC,CAAC;IACb,CAAC;IAED,6CAA6C;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;YACvE,IAAI,KAAK,CAAC,eAAe,IAAI,MAAM,EAAE,CAAC;gBACpC,qEAAqE;gBACrE,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,6CAA6C,CAAC,CAAC;IAC3D,CAAC;IAED,wBAAwB;IACxB,MAAM,SAAS,GAAG;QAChB,GAAG,WAAW,UAAU,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACtD,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,WAAW,CAAC,CAAC,CAAC,IAAI;QAClD,cAAc,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI;QAC5C,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI;KACvC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE7B,OAAO;QACL,OAAO,EAAE,+BAA+B,SAAS,gBAAgB,IAAI,YAAY,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,2BAA2B,MAAM,8BAA8B;KACvL,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAgB,EAAE,GAAW;IACpD,+DAA+D;IAC/D,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,2CAA2C;QAC3C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC;iBAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;iBAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,IAAI,EAAE,CAAC;gBACP,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACvB,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;oBAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,OAAO,CAAC,CAAC;gBAAC,CAAC,CAAC,CAAC,CAAC,EAAE;aAC7F,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YAErC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,2EAA2E;IAC3E,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC,MAAM,CAAC;IAE1D,2DAA2D;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IACnD,OAAO,SAAS,CAAC,MAAM,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,sCAAsC;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HookInput, GuardResult } from '../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scope drift guard: fires PreToolUse on Edit|Write.
|
|
4
|
+
* Warns when editing files outside the claimed ticket's scope.
|
|
5
|
+
*/
|
|
6
|
+
export declare function scopeDriftGuard(input: HookInput, cwd: string): Promise<GuardResult>;
|
|
7
|
+
//# sourceMappingURL=scope-drift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-drift.d.ts","sourceRoot":"","sources":["../../../src/cli/guards/scope-drift.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIlE;;;GAGG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAwCzF"}
|