@nanonets/graft 0.24.1 → 0.25.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/README.md +26 -21
- package/dist/blast/render.js +1 -1
- package/dist/blast/render.js.map +1 -1
- package/dist/brand.js +1 -1
- package/dist/brand.js.map +1 -1
- package/dist/check/learning-edits.d.ts +18 -3
- package/dist/check/learning-edits.d.ts.map +1 -1
- package/dist/check/learning-edits.js +54 -10
- package/dist/check/learning-edits.js.map +1 -1
- package/dist/check/local-check.d.ts +7 -3
- package/dist/check/local-check.d.ts.map +1 -1
- package/dist/check/local-check.js +55 -11
- package/dist/check/local-check.js.map +1 -1
- package/dist/check/types.d.ts +11 -2
- package/dist/check/types.d.ts.map +1 -1
- package/dist/claude/format.d.ts +11 -7
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +50 -28
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hook-io.js +1 -1
- package/dist/claude/hook-io.js.map +1 -1
- package/dist/claude/hook-layers.d.ts +4 -2
- package/dist/claude/hook-layers.d.ts.map +1 -1
- package/dist/claude/hook-layers.js +21 -4
- package/dist/claude/hook-layers.js.map +1 -1
- package/dist/claude/hooks.d.ts +9 -32
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +154 -350
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +56 -18
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/note-signals.d.ts +6 -0
- package/dist/claude/note-signals.d.ts.map +1 -1
- package/dist/claude/note-signals.js +14 -3
- package/dist/claude/note-signals.js.map +1 -1
- package/dist/claude/post-bash.d.ts +26 -0
- package/dist/claude/post-bash.d.ts.map +1 -0
- package/dist/claude/post-bash.js +191 -0
- package/dist/claude/post-bash.js.map +1 -0
- package/dist/claude/pre-bash-skills.d.ts +21 -0
- package/dist/claude/pre-bash-skills.d.ts.map +1 -0
- package/dist/claude/pre-bash-skills.js +253 -0
- package/dist/claude/pre-bash-skills.js.map +1 -0
- package/dist/claude/pre-bash.d.ts +50 -0
- package/dist/claude/pre-bash.d.ts.map +1 -0
- package/dist/claude/pre-bash.js +245 -0
- package/dist/claude/pre-bash.js.map +1 -0
- package/dist/claude/prompt-consent.d.ts +19 -0
- package/dist/claude/prompt-consent.d.ts.map +1 -0
- package/dist/claude/prompt-consent.js +14 -0
- package/dist/claude/prompt-consent.js.map +1 -0
- package/dist/claude/prompt-hook.d.ts +76 -0
- package/dist/claude/prompt-hook.d.ts.map +1 -0
- package/dist/claude/prompt-hook.js +303 -0
- package/dist/claude/prompt-hook.js.map +1 -0
- package/dist/claude/prompt-skills.d.ts +19 -0
- package/dist/claude/prompt-skills.d.ts.map +1 -0
- package/dist/claude/prompt-skills.js +305 -0
- package/dist/claude/prompt-skills.js.map +1 -0
- package/dist/claude/session-metrics.js +4 -4
- package/dist/claude/session-metrics.js.map +1 -1
- package/dist/claude/settings-merge.d.ts +10 -0
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +46 -17
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +86 -28
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts +2 -0
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +53 -34
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/skill-use.d.ts +16 -0
- package/dist/claude/skill-use.d.ts.map +1 -0
- package/dist/claude/skill-use.js +78 -0
- package/dist/claude/skill-use.js.map +1 -0
- package/dist/claude/skills-wiring.d.ts +26 -0
- package/dist/claude/skills-wiring.d.ts.map +1 -0
- package/dist/claude/skills-wiring.js +110 -0
- package/dist/claude/skills-wiring.js.map +1 -0
- package/dist/claude/start-init.d.ts +13 -0
- package/dist/claude/start-init.d.ts.map +1 -0
- package/dist/claude/start-init.js +75 -0
- package/dist/claude/start-init.js.map +1 -0
- package/dist/claude/start-skills.d.ts +31 -0
- package/dist/claude/start-skills.d.ts.map +1 -0
- package/dist/claude/start-skills.js +274 -0
- package/dist/claude/start-skills.js.map +1 -0
- package/dist/claude/state.d.ts +19 -7
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js +59 -4
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/stop-skills.d.ts +23 -0
- package/dist/claude/stop-skills.d.ts.map +1 -0
- package/dist/claude/stop-skills.js +233 -0
- package/dist/claude/stop-skills.js.map +1 -0
- package/dist/claude/stop.d.ts +23 -0
- package/dist/claude/stop.d.ts.map +1 -0
- package/dist/claude/stop.js +219 -0
- package/dist/claude/stop.js.map +1 -0
- package/dist/claude/tally.d.ts +29 -41
- package/dist/claude/tally.d.ts.map +1 -1
- package/dist/claude/tally.js +111 -165
- package/dist/claude/tally.js.map +1 -1
- package/dist/claude/walls-hook.d.ts +52 -0
- package/dist/claude/walls-hook.d.ts.map +1 -0
- package/dist/claude/walls-hook.js +279 -0
- package/dist/claude/walls-hook.js.map +1 -0
- package/dist/cli-epilogue.d.ts.map +1 -1
- package/dist/cli-epilogue.js +24 -14
- package/dist/cli-epilogue.js.map +1 -1
- package/dist/cli-meta.js +3 -3
- package/dist/cli-meta.js.map +1 -1
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +8 -6
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +238 -402
- package/dist/cli.js.map +1 -1
- package/dist/cloud/head-learnings.d.ts +13 -0
- package/dist/cloud/head-learnings.d.ts.map +1 -0
- package/dist/cloud/head-learnings.js +84 -0
- package/dist/cloud/head-learnings.js.map +1 -0
- package/dist/cloud/lookup-activity.d.ts +5 -3
- package/dist/cloud/lookup-activity.d.ts.map +1 -1
- package/dist/cloud/lookup-activity.js +8 -8
- package/dist/cloud/lookup-activity.js.map +1 -1
- package/dist/cloud/nudge.d.ts +15 -7
- package/dist/cloud/nudge.d.ts.map +1 -1
- package/dist/cloud/nudge.js +42 -33
- package/dist/cloud/nudge.js.map +1 -1
- package/dist/cloud/onboarding.d.ts +37 -1
- package/dist/cloud/onboarding.d.ts.map +1 -1
- package/dist/cloud/onboarding.js +77 -1
- package/dist/cloud/onboarding.js.map +1 -1
- package/dist/cloud/other-repos.d.ts +39 -0
- package/dist/cloud/other-repos.d.ts.map +1 -0
- package/dist/cloud/other-repos.js +137 -0
- package/dist/cloud/other-repos.js.map +1 -0
- package/dist/cloud/pair.d.ts +17 -7
- package/dist/cloud/pair.d.ts.map +1 -1
- package/dist/cloud/pair.js +81 -60
- package/dist/cloud/pair.js.map +1 -1
- package/dist/cloud/workspace-sync.d.ts +67 -11
- package/dist/cloud/workspace-sync.d.ts.map +1 -1
- package/dist/cloud/workspace-sync.js +299 -55
- package/dist/cloud/workspace-sync.js.map +1 -1
- package/dist/cloud/workspace.d.ts +74 -10
- package/dist/cloud/workspace.d.ts.map +1 -1
- package/dist/cloud/workspace.js +96 -8
- package/dist/cloud/workspace.js.map +1 -1
- package/dist/hosts/claude-global.js +1 -1
- package/dist/hosts/claude-global.js.map +1 -1
- package/dist/hosts/codex-hooks.d.ts +6 -0
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +89 -16
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/codex-trust.d.ts +28 -0
- package/dist/hosts/codex-trust.d.ts.map +1 -0
- package/dist/hosts/codex-trust.js +280 -0
- package/dist/hosts/codex-trust.js.map +1 -0
- package/dist/hosts/cursor-hooks.d.ts.map +1 -1
- package/dist/hosts/cursor-hooks.js +3 -1
- package/dist/hosts/cursor-hooks.js.map +1 -1
- package/dist/init/candidates.d.ts +60 -0
- package/dist/init/candidates.d.ts.map +1 -0
- package/dist/init/candidates.js +202 -0
- package/dist/init/candidates.js.map +1 -0
- package/dist/init/claude-call.d.ts +51 -0
- package/dist/init/claude-call.d.ts.map +1 -0
- package/dist/init/claude-call.js +199 -0
- package/dist/init/claude-call.js.map +1 -0
- package/dist/init/discover-worker.d.ts +18 -0
- package/dist/init/discover-worker.d.ts.map +1 -0
- package/dist/init/discover-worker.js +111 -0
- package/dist/init/discover-worker.js.map +1 -0
- package/dist/init/handover.d.ts +16 -0
- package/dist/init/handover.d.ts.map +1 -0
- package/dist/init/handover.js +92 -0
- package/dist/init/handover.js.map +1 -0
- package/dist/init/howtos.d.ts +20 -0
- package/dist/init/howtos.d.ts.map +1 -0
- package/dist/init/howtos.js +90 -0
- package/dist/init/howtos.js.map +1 -0
- package/dist/init/init-record.d.ts +134 -0
- package/dist/init/init-record.d.ts.map +1 -0
- package/dist/init/init-record.js +339 -0
- package/dist/init/init-record.js.map +1 -0
- package/dist/init/install-paths.d.ts +6 -0
- package/dist/init/install-paths.d.ts.map +1 -0
- package/dist/init/install-paths.js +87 -0
- package/dist/init/install-paths.js.map +1 -0
- package/dist/init/keep-answer.d.ts +43 -0
- package/dist/init/keep-answer.d.ts.map +1 -0
- package/dist/init/keep-answer.js +118 -0
- package/dist/init/keep-answer.js.map +1 -0
- package/dist/init/keep-gate.d.ts +30 -0
- package/dist/init/keep-gate.d.ts.map +1 -0
- package/dist/init/keep-gate.js +178 -0
- package/dist/init/keep-gate.js.map +1 -0
- package/dist/init/keep-list.d.ts +67 -0
- package/dist/init/keep-list.d.ts.map +1 -0
- package/dist/init/keep-list.js +232 -0
- package/dist/init/keep-list.js.map +1 -0
- package/dist/init/keep.d.ts +52 -0
- package/dist/init/keep.d.ts.map +1 -0
- package/dist/init/keep.js +393 -0
- package/dist/init/keep.js.map +1 -0
- package/dist/init/look-back-mine.d.ts +37 -0
- package/dist/init/look-back-mine.d.ts.map +1 -0
- package/dist/init/look-back-mine.js +215 -0
- package/dist/init/look-back-mine.js.map +1 -0
- package/dist/init/look-back.d.ts +81 -0
- package/dist/init/look-back.d.ts.map +1 -0
- package/dist/init/look-back.js +170 -0
- package/dist/init/look-back.js.map +1 -0
- package/dist/init/miners.d.ts +46 -0
- package/dist/init/miners.d.ts.map +1 -0
- package/dist/init/miners.js +141 -0
- package/dist/init/miners.js.map +1 -0
- package/dist/init/name-call.d.ts +37 -0
- package/dist/init/name-call.d.ts.map +1 -0
- package/dist/init/name-call.js +151 -0
- package/dist/init/name-call.js.map +1 -0
- package/dist/init/plain-file.d.ts.map +1 -1
- package/dist/init/plain-file.js +3 -0
- package/dist/init/plain-file.js.map +1 -1
- package/dist/init/prefs.d.ts +70 -0
- package/dist/init/prefs.d.ts.map +1 -0
- package/dist/init/prefs.js +282 -0
- package/dist/init/prefs.js.map +1 -0
- package/dist/init/relay.d.ts +15 -0
- package/dist/init/relay.d.ts.map +1 -0
- package/dist/init/relay.js +15 -0
- package/dist/init/relay.js.map +1 -0
- package/dist/init/replay-runs.d.ts +121 -0
- package/dist/init/replay-runs.d.ts.map +1 -0
- package/dist/init/replay-runs.js +457 -0
- package/dist/init/replay-runs.js.map +1 -0
- package/dist/init/replay-tamper.d.ts +18 -0
- package/dist/init/replay-tamper.d.ts.map +1 -0
- package/dist/init/replay-tamper.js +87 -0
- package/dist/init/replay-tamper.js.map +1 -0
- package/dist/init/review-screen.d.ts +74 -0
- package/dist/init/review-screen.d.ts.map +1 -0
- package/dist/init/review-screen.js +258 -0
- package/dist/init/review-screen.js.map +1 -0
- package/dist/init/review-tty.d.ts +29 -0
- package/dist/init/review-tty.d.ts.map +1 -0
- package/dist/init/review-tty.js +218 -0
- package/dist/init/review-tty.js.map +1 -0
- package/dist/init/review.d.ts +12 -0
- package/dist/init/review.d.ts.map +1 -0
- package/dist/init/review.js +12 -0
- package/dist/init/review.js.map +1 -0
- package/dist/init/run.d.ts +87 -0
- package/dist/init/run.d.ts.map +1 -0
- package/dist/init/run.js +347 -0
- package/dist/init/run.js.map +1 -0
- package/dist/init/sessions.d.ts +63 -0
- package/dist/init/sessions.d.ts.map +1 -0
- package/dist/init/sessions.js +377 -0
- package/dist/init/sessions.js.map +1 -0
- package/dist/init/transcript.d.ts +81 -0
- package/dist/init/transcript.d.ts.map +1 -0
- package/dist/init/transcript.js +216 -0
- package/dist/init/transcript.js.map +1 -0
- package/dist/init/types.d.ts +139 -0
- package/dist/init/types.d.ts.map +1 -0
- package/dist/init/types.js +2 -0
- package/dist/init/types.js.map +1 -0
- package/dist/notes/cold-start.d.ts +5 -213
- package/dist/notes/cold-start.d.ts.map +1 -1
- package/dist/notes/cold-start.js +5 -654
- package/dist/notes/cold-start.js.map +1 -1
- package/dist/notes/edit-overlap.d.ts.map +1 -1
- package/dist/notes/edit-overlap.js +4 -1
- package/dist/notes/edit-overlap.js.map +1 -1
- package/dist/notes/notes.d.ts +8 -4
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js +9 -7
- package/dist/notes/notes.js.map +1 -1
- package/dist/notes/pr-reviews.d.ts +4 -0
- package/dist/notes/pr-reviews.d.ts.map +1 -1
- package/dist/notes/pr-reviews.js +6 -5
- package/dist/notes/pr-reviews.js.map +1 -1
- package/dist/notes/repo-trail.d.ts +1 -1
- package/dist/notes/repo-trail.d.ts.map +1 -1
- package/dist/notes/repo-trail.js +24 -4
- package/dist/notes/repo-trail.js.map +1 -1
- package/dist/search/grep.d.ts.map +1 -1
- package/dist/search/grep.js +4 -2
- package/dist/search/grep.js.map +1 -1
- package/dist/search/user-regexp.d.ts +26 -0
- package/dist/search/user-regexp.d.ts.map +1 -0
- package/dist/search/user-regexp.js +150 -0
- package/dist/search/user-regexp.js.map +1 -0
- package/dist/skills/anchors-cli.d.ts +5 -0
- package/dist/skills/anchors-cli.d.ts.map +1 -1
- package/dist/skills/anchors-cli.js +7 -2
- package/dist/skills/anchors-cli.js.map +1 -1
- package/dist/skills/anchors-wide.js +2 -2
- package/dist/skills/anchors-wide.js.map +1 -1
- package/dist/skills/cli-skills-1b.d.ts +17 -0
- package/dist/skills/cli-skills-1b.d.ts.map +1 -0
- package/dist/skills/cli-skills-1b.js +166 -0
- package/dist/skills/cli-skills-1b.js.map +1 -0
- package/dist/skills/cli-skills-2.d.ts +35 -0
- package/dist/skills/cli-skills-2.d.ts.map +1 -0
- package/dist/skills/cli-skills-2.js +129 -0
- package/dist/skills/cli-skills-2.js.map +1 -0
- package/dist/skills/cli-skills-report-1b.d.ts +49 -0
- package/dist/skills/cli-skills-report-1b.d.ts.map +1 -0
- package/dist/skills/cli-skills-report-1b.js +191 -0
- package/dist/skills/cli-skills-report-1b.js.map +1 -0
- package/dist/skills/cli-skills-report.d.ts +86 -0
- package/dist/skills/cli-skills-report.d.ts.map +1 -0
- package/dist/skills/cli-skills-report.js +121 -0
- package/dist/skills/cli-skills-report.js.map +1 -0
- package/dist/skills/cli-skills.d.ts +30 -0
- package/dist/skills/cli-skills.d.ts.map +1 -0
- package/dist/skills/cli-skills.js +379 -0
- package/dist/skills/cli-skills.js.map +1 -0
- package/dist/skills/compile-split.d.ts.map +1 -1
- package/dist/skills/compile-split.js +18 -0
- package/dist/skills/compile-split.js.map +1 -1
- package/dist/skills/compile-words.d.ts +4 -1
- package/dist/skills/compile-words.d.ts.map +1 -1
- package/dist/skills/compile-words.js +68 -8
- package/dist/skills/compile-words.js.map +1 -1
- package/dist/skills/compile.d.ts +7 -0
- package/dist/skills/compile.d.ts.map +1 -1
- package/dist/skills/compile.js +17 -0
- package/dist/skills/compile.js.map +1 -1
- package/dist/skills/credit.d.ts +86 -0
- package/dist/skills/credit.d.ts.map +1 -0
- package/dist/skills/credit.js +259 -0
- package/dist/skills/credit.js.map +1 -0
- package/dist/skills/fold-gated.d.ts +3 -0
- package/dist/skills/fold-gated.d.ts.map +1 -0
- package/dist/skills/fold-gated.js +78 -0
- package/dist/skills/fold-gated.js.map +1 -0
- package/dist/skills/fold.d.ts +87 -0
- package/dist/skills/fold.d.ts.map +1 -0
- package/dist/skills/fold.js +348 -0
- package/dist/skills/fold.js.map +1 -0
- package/dist/skills/follow-learnings.d.ts +128 -0
- package/dist/skills/follow-learnings.d.ts.map +1 -0
- package/dist/skills/follow-learnings.js +278 -0
- package/dist/skills/follow-learnings.js.map +1 -0
- package/dist/skills/learning-steps.d.ts +43 -0
- package/dist/skills/learning-steps.d.ts.map +1 -0
- package/dist/skills/learning-steps.js +294 -0
- package/dist/skills/learning-steps.js.map +1 -0
- package/dist/skills/lesson-gate.d.ts +25 -0
- package/dist/skills/lesson-gate.d.ts.map +1 -0
- package/dist/skills/lesson-gate.js +316 -0
- package/dist/skills/lesson-gate.js.map +1 -0
- package/dist/skills/offer-drift.d.ts +35 -0
- package/dist/skills/offer-drift.d.ts.map +1 -0
- package/dist/skills/offer-drift.js +98 -0
- package/dist/skills/offer-drift.js.map +1 -0
- package/dist/skills/offer-lesson.d.ts +31 -0
- package/dist/skills/offer-lesson.d.ts.map +1 -0
- package/dist/skills/offer-lesson.js +123 -0
- package/dist/skills/offer-lesson.js.map +1 -0
- package/dist/skills/offer-lines.d.ts +40 -0
- package/dist/skills/offer-lines.d.ts.map +1 -0
- package/dist/skills/offer-lines.js +80 -0
- package/dist/skills/offer-lines.js.map +1 -0
- package/dist/skills/offer-moment.d.ts +102 -0
- package/dist/skills/offer-moment.d.ts.map +1 -0
- package/dist/skills/offer-moment.js +260 -0
- package/dist/skills/offer-moment.js.map +1 -0
- package/dist/skills/offer-repair.d.ts +36 -0
- package/dist/skills/offer-repair.d.ts.map +1 -0
- package/dist/skills/offer-repair.js +212 -0
- package/dist/skills/offer-repair.js.map +1 -0
- package/dist/skills/offer-retire.d.ts +53 -0
- package/dist/skills/offer-retire.d.ts.map +1 -0
- package/dist/skills/offer-retire.js +149 -0
- package/dist/skills/offer-retire.js.map +1 -0
- package/dist/skills/offer-update.d.ts +54 -0
- package/dist/skills/offer-update.d.ts.map +1 -0
- package/dist/skills/offer-update.js +115 -0
- package/dist/skills/offer-update.js.map +1 -0
- package/dist/skills/offer-words-1b.d.ts +32 -0
- package/dist/skills/offer-words-1b.d.ts.map +1 -0
- package/dist/skills/offer-words-1b.js +80 -0
- package/dist/skills/offer-words-1b.js.map +1 -0
- package/dist/skills/offer-words-2.d.ts +123 -0
- package/dist/skills/offer-words-2.d.ts.map +1 -0
- package/dist/skills/offer-words-2.js +194 -0
- package/dist/skills/offer-words-2.js.map +1 -0
- package/dist/skills/offer-words.d.ts +65 -0
- package/dist/skills/offer-words.d.ts.map +1 -0
- package/dist/skills/offer-words.js +205 -0
- package/dist/skills/offer-words.js.map +1 -0
- package/dist/skills/offers.d.ts +66 -0
- package/dist/skills/offers.d.ts.map +1 -0
- package/dist/skills/offers.js +284 -0
- package/dist/skills/offers.js.map +1 -0
- package/dist/skills/runblock.d.ts +2 -0
- package/dist/skills/runblock.d.ts.map +1 -1
- package/dist/skills/runblock.js +11 -6
- package/dist/skills/runblock.js.map +1 -1
- package/dist/skills/save-gate.d.ts +64 -0
- package/dist/skills/save-gate.d.ts.map +1 -0
- package/dist/skills/save-gate.js +354 -0
- package/dist/skills/save-gate.js.map +1 -0
- package/dist/skills/save-verify.d.ts +59 -0
- package/dist/skills/save-verify.d.ts.map +1 -0
- package/dist/skills/save-verify.js +390 -0
- package/dist/skills/save-verify.js.map +1 -0
- package/dist/skills/settings.d.ts +12 -2
- package/dist/skills/settings.d.ts.map +1 -1
- package/dist/skills/settings.js +24 -2
- package/dist/skills/settings.js.map +1 -1
- package/dist/skills/skills.d.ts +26 -8
- package/dist/skills/skills.d.ts.map +1 -1
- package/dist/skills/skills.js +105 -52
- package/dist/skills/skills.js.map +1 -1
- package/dist/skills/types.d.ts +8 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/update-gate.d.ts +36 -0
- package/dist/skills/update-gate.d.ts.map +1 -0
- package/dist/skills/update-gate.js +357 -0
- package/dist/skills/update-gate.js.map +1 -0
- package/dist/skills/update-plan.d.ts +40 -0
- package/dist/skills/update-plan.d.ts.map +1 -0
- package/dist/skills/update-plan.js +196 -0
- package/dist/skills/update-plan.js.map +1 -0
- package/dist/skills/value-line.d.ts +94 -0
- package/dist/skills/value-line.d.ts.map +1 -0
- package/dist/skills/value-line.js +355 -0
- package/dist/skills/value-line.js.map +1 -0
- package/dist/telemetry/contract.d.ts +15 -1
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +80 -11
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/gate.js +4 -4
- package/dist/telemetry/gate.js.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/notice.js +5 -5
- package/dist/telemetry/notice.js.map +1 -1
- package/dist/telemetry/queue.d.ts.map +1 -1
- package/dist/telemetry/queue.js +7 -7
- package/dist/telemetry/queue.js.map +1 -1
- package/dist/telemetry/track.d.ts.map +1 -1
- package/dist/telemetry/track.js +4 -3
- package/dist/telemetry/track.js.map +1 -1
- package/dist/trace/checks.d.ts.map +1 -1
- package/dist/trace/checks.js +10 -2
- package/dist/trace/checks.js.map +1 -1
- package/dist/trace/gate-file.d.ts +1 -1
- package/dist/trace/gate-file.d.ts.map +1 -1
- package/dist/trace/gate-file.js +3 -3
- package/dist/trace/gate-file.js.map +1 -1
- package/dist/upkeep-run.d.ts.map +1 -1
- package/dist/upkeep-run.js +2 -23
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +2 -3
- package/dist/upkeep.js.map +1 -1
- package/dist/util/private-fs.d.ts +6 -0
- package/dist/util/private-fs.d.ts.map +1 -1
- package/dist/util/private-fs.js +9 -1
- package/dist/util/private-fs.js.map +1 -1
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +17 -3
- package/dist/util/state.js.map +1 -1
- package/package.json +1 -1
- package/dist/skills/found-skill.d.ts +0 -35
- package/dist/skills/found-skill.d.ts.map +0 -1
- package/dist/skills/found-skill.js +0 -66
- package/dist/skills/found-skill.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words of a repeated-job offer and of the answers to it (design 3.4,
|
|
3
|
+
* 3.5, 4.12, spec 9). Re-exported from `offers.ts`, where the design names
|
|
4
|
+
* them.
|
|
5
|
+
*
|
|
6
|
+
* An offer is exactly 2 lines the agent says word for word: what checked out
|
|
7
|
+
* and what it cost, in numbers counted from the transcript, then the
|
|
8
|
+
* question with its three keys. Every value is flattened to one line, so a
|
|
9
|
+
* branch name or a version from a command can never add a line. Never
|
|
10
|
+
* "memory" or "remember", no em dashes: a test greps every string here.
|
|
11
|
+
*/
|
|
12
|
+
import type { Host } from '../trace/host.js';
|
|
13
|
+
import type { DialectUse } from '../trace/dialect.js';
|
|
14
|
+
import type { CheckHit, JobClass, PendingOffer } from '../trace/types.js';
|
|
15
|
+
import type { HookOut } from './types.js';
|
|
16
|
+
export interface OfferFacts {
|
|
17
|
+
job: JobClass;
|
|
18
|
+
check: CheckHit;
|
|
19
|
+
ordinal: number;
|
|
20
|
+
unit: 'day' | 'time';
|
|
21
|
+
commands: number;
|
|
22
|
+
failed: number;
|
|
23
|
+
steps: number;
|
|
24
|
+
where: 'this repo' | 'every repo';
|
|
25
|
+
branches: string[];
|
|
26
|
+
}
|
|
27
|
+
/** For `trail skills` (2.10), once per time the governor turns on. */
|
|
28
|
+
export declare const GOVERNOR_LINE = "you kept fewer than 1 in 3 offers lately, so a job now has to come back a 4th day before Trail offers it";
|
|
29
|
+
export declare function ordinalWord(n: number): string;
|
|
30
|
+
/** 1b (4.13): the check's own line, as moment 2's line 1 opens (`Tests pass (12 passed).`), for moment 3's line 1. */
|
|
31
|
+
export declare function checkLine(check: CheckHit, branches?: string[]): string;
|
|
32
|
+
/** 4.12's line 2: the question an offer's yes answers. `n` is the skill's steps (a separate check counts as one). */
|
|
33
|
+
export declare function keepLine(n: number, where?: 'this repo' | 'every repo'): string;
|
|
34
|
+
/** `line` is a line 2 that `keepLine` (or moment 3's `repairLines`) writes, and nothing else (a question of the agent's own is not). */
|
|
35
|
+
export declare function isKeepLine(line: string): boolean;
|
|
36
|
+
/** The question after "show me" and the draft (4.12): a yes after the draft answers this. */
|
|
37
|
+
export declare const KEEP_IT = "Keep it? (yes / no)";
|
|
38
|
+
/** The reply's last words are `line` (said word for word as its last line): nothing after it, no question of the agent's own. */
|
|
39
|
+
export declare function endsWithLine(reply: string, line: string): boolean;
|
|
40
|
+
/** 4.12: exactly 2 lines, every number counted from the trace, every value flattened. */
|
|
41
|
+
export declare function offerLines(f: OfferFacts): [string, string];
|
|
42
|
+
/**
|
|
43
|
+
* 3.5: the Stop block's reason, which the agent reads. D101: from Trail, with Trail's own reason for offering; the
|
|
44
|
+
* 2 lines are Trail's question for the person, never an order to recite.
|
|
45
|
+
*/
|
|
46
|
+
export declare function stopBlockReason(o: PendingOffer, transcriptPath?: string | null, use?: DialectUse): string;
|
|
47
|
+
/** 3.5: the Stop notice the person reads (channel `notice`). */
|
|
48
|
+
export declare function noticeText(o: PendingOffer, transcriptPath?: string | null, use?: DialectUse): string;
|
|
49
|
+
/** 3.4: the passing check's PostToolUse context (channel `post-tool`). */
|
|
50
|
+
export declare function postToolOfferText(o: PendingOffer, transcriptPath?: string | null): string;
|
|
51
|
+
/** What "OK, not saved." grows into: the way to stop offers on the first no ever, the pause when it starts. */
|
|
52
|
+
export declare function notSaved(c: {
|
|
53
|
+
paused: boolean;
|
|
54
|
+
firstNo: boolean;
|
|
55
|
+
}): string;
|
|
56
|
+
/**
|
|
57
|
+
* 4.12, as context on the answering prompt; a bare no as a block where the host shows its reason (O2). D101: each
|
|
58
|
+
* directive says it is from Trail, quotes the words the person typed (`typed`, from the prompt hook's payload, never
|
|
59
|
+
* stored) and says why. 1b: a moment 3 or 4 offer's answers are `answer1b`'s, which need no lines.
|
|
60
|
+
*/
|
|
61
|
+
export declare function answerDirective(a: 'yes' | 'show' | 'no' | 'other', o: PendingOffer, c: {
|
|
62
|
+
paused: boolean;
|
|
63
|
+
firstNo: boolean;
|
|
64
|
+
}, env?: NodeJS.ProcessEnv, typed?: string, host?: Host): HookOut;
|
|
65
|
+
//# sourceMappingURL=offer-words.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offer-words.d.ts","sourceRoot":"","sources":["../../src/skills/offer-words.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAY1C,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACtE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAAC;IACnF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,sEAAsE;AACtE,eAAO,MAAM,aAAa,6GAA6G,CAAC;AAKxI,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7C;AAoDD,sHAAsH;AACtH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,MAAM,CAE1E;AAED,qHAAqH;AACrH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,WAAW,GAAG,YAA0B,GAAG,MAAM,CAG3F;AAKD,wIAAwI;AACxI,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED,6FAA6F;AAC7F,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAK7C,iIAAiI;AACjI,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAO1D;AAuBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,EAAE,cAAc,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,MAAM,CAU/G;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,CAAC,EAAE,YAAY,EAAE,cAAc,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,MAAM,CAK1G;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,cAAc,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,CAQ/F;AAED,+GAA+G;AAC/G,wBAAgB,QAAQ,CAAC,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAIzE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,KAAK,GAAE,MAAW,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAmB7M"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { flatLine } from '../notes/flatten.js';
|
|
2
|
+
import { JOB_CLASSES } from '../trace/jobs.js';
|
|
3
|
+
import { hostFacts } from './host-facts.js';
|
|
4
|
+
import { directive, FROM_TRAIL } from './directive-words.js';
|
|
5
|
+
import { offerLinesOf } from './offer-lines.js';
|
|
6
|
+
import { answer1b, blockReason1b, postTool1b } from './offer-words-1b.js';
|
|
7
|
+
import { answer2, blockReason2, postTool2 } from './offer-words-2.js';
|
|
8
|
+
/** Phase 2 (R11): moments 5 and 6 and the retire proposal have words of their own (offer-words-2.ts). */
|
|
9
|
+
const isPhase2 = (o) => o.moment === 'update' || o.moment === 'drift' || o.moment === 'retire';
|
|
10
|
+
/** For `trail skills` (2.10), once per time the governor turns on. */
|
|
11
|
+
export const GOVERNOR_LINE = 'you kept fewer than 1 in 3 offers lately, so a job now has to come back a 4th day before Trail offers it';
|
|
12
|
+
/** One line, at most `max` characters; '' when nothing is left. */
|
|
13
|
+
const one = (v, max = 40) => flatLine(v, max);
|
|
14
|
+
export function ordinalWord(n) {
|
|
15
|
+
const k = Math.max(0, Math.floor(n));
|
|
16
|
+
const teen = k % 100;
|
|
17
|
+
if (teen >= 11 && teen <= 13)
|
|
18
|
+
return `${k}th`;
|
|
19
|
+
return `${k}${['th', 'st', 'nd', 'rd'][k % 10] ?? 'th'}`;
|
|
20
|
+
}
|
|
21
|
+
const plural = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
|
|
22
|
+
/** "beta and prod", "beta, staging and prod". */
|
|
23
|
+
function listed(items) {
|
|
24
|
+
if (items.length < 2)
|
|
25
|
+
return items.join('');
|
|
26
|
+
return `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`;
|
|
27
|
+
}
|
|
28
|
+
/** The ship subject and its verb: "beta and prod are both", "prod is", "beta, staging and prod are all". */
|
|
29
|
+
function shipSubject(branches) {
|
|
30
|
+
const b = [...new Set(branches.map((x) => one(x)).filter(Boolean))];
|
|
31
|
+
if (!b.length)
|
|
32
|
+
return null;
|
|
33
|
+
if (b.length === 1)
|
|
34
|
+
return `${b[0]} is`;
|
|
35
|
+
return `${listed(b)} are ${b.length === 2 ? 'both' : 'all'}`;
|
|
36
|
+
}
|
|
37
|
+
/** 4.12's lead: what checked out, from the check's facts. Facts missing: the plainer words. */
|
|
38
|
+
function lead(f) {
|
|
39
|
+
const facts = f.check.facts;
|
|
40
|
+
const sha = one(facts.sha ?? '').slice(0, 7);
|
|
41
|
+
switch (f.check.family) {
|
|
42
|
+
case 'npm-view': {
|
|
43
|
+
const v = one(facts.version ?? '');
|
|
44
|
+
return `Published ${v || 'the new version'}: npm shows it.`;
|
|
45
|
+
}
|
|
46
|
+
case 'deploy': {
|
|
47
|
+
const state = one(facts.state ?? '') || 'ready';
|
|
48
|
+
const subject = shipSubject(f.branches);
|
|
49
|
+
if (subject)
|
|
50
|
+
return `Shipped: ${subject}${sha ? ` at ${sha}` : ''} and ${state}.`;
|
|
51
|
+
return `Shipped: the deploy${sha ? ` at ${sha}` : ''} is ${state}.`;
|
|
52
|
+
}
|
|
53
|
+
case 'ls-remote':
|
|
54
|
+
case 'push': {
|
|
55
|
+
const remote = one(facts.remote ?? '') || 'the remote';
|
|
56
|
+
const subject = shipSubject(f.branches.length ? f.branches : facts.branch ? [facts.branch] : []);
|
|
57
|
+
if (subject && sha)
|
|
58
|
+
return `Shipped: ${subject} at ${sha} on ${remote}.`;
|
|
59
|
+
if (subject)
|
|
60
|
+
return `Shipped: ${subject.replace(/ (?:is|are (?:both|all))$/, '')} moved on ${remote}.`;
|
|
61
|
+
return `Shipped: ${sha ? `${sha} is` : 'it is'} on ${remote}.`;
|
|
62
|
+
}
|
|
63
|
+
case 'tests': {
|
|
64
|
+
const n = facts.passedCount;
|
|
65
|
+
return typeof n === 'number' && Number.isFinite(n) && n > 0 ? `Tests pass (${Math.floor(n)} passed).` : 'Tests pass.';
|
|
66
|
+
}
|
|
67
|
+
case 'query':
|
|
68
|
+
return 'Done: the numbers are in.';
|
|
69
|
+
default:
|
|
70
|
+
return 'Done: the check passed.';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** 1b (4.13): the check's own line, as moment 2's line 1 opens (`Tests pass (12 passed).`), for moment 3's line 1. */
|
|
74
|
+
export function checkLine(check, branches = []) {
|
|
75
|
+
return lead({ check, branches });
|
|
76
|
+
}
|
|
77
|
+
/** 4.12's line 2: the question an offer's yes answers. `n` is the skill's steps (a separate check counts as one). */
|
|
78
|
+
export function keepLine(n, where = 'this repo') {
|
|
79
|
+
const k = Math.max(0, Math.floor(n));
|
|
80
|
+
return `Keep the ${k === 1 ? 'one' : k} that worked as a skill, just for you in ${where === 'every repo' ? 'every repo' : 'this repo'}? (yes / show me / no)`;
|
|
81
|
+
}
|
|
82
|
+
const KEEP_RE = /^Keep the (?:one|[1-9]\d*) that worked as a skill, just for you in (?:this repo|every repo)\? \(yes \/ show me \/ no\)$/;
|
|
83
|
+
/** Moment 3's line 2 for a skill (4.13, offer-repair.ts `repairLines`). */
|
|
84
|
+
const REPAIR_KEEP_RE = /^Keep the [1-9]\d* working steps as a skill, just for you in this repo\? \(yes \/ show me \/ no\)$/;
|
|
85
|
+
/** `line` is a line 2 that `keepLine` (or moment 3's `repairLines`) writes, and nothing else (a question of the agent's own is not). */
|
|
86
|
+
export function isKeepLine(line) {
|
|
87
|
+
const l = String(line ?? '');
|
|
88
|
+
return KEEP_RE.test(l) || REPAIR_KEEP_RE.test(l);
|
|
89
|
+
}
|
|
90
|
+
/** The question after "show me" and the draft (4.12): a yes after the draft answers this. */
|
|
91
|
+
export const KEEP_IT = 'Keep it? (yes / no)';
|
|
92
|
+
/** Spaces collapsed, and what a reply may dress its last line with (bold, italics, quotes, a full stop) taken off the end. */
|
|
93
|
+
const bare = (t) => String(t ?? '').replace(/\s+/g, ' ').trim().replace(/[\s*_`"'\u2018\u2019\u201c\u201d.]+$/u, '');
|
|
94
|
+
/** The reply's last words are `line` (said word for word as its last line): nothing after it, no question of the agent's own. */
|
|
95
|
+
export function endsWithLine(reply, line) {
|
|
96
|
+
const l = bare(line);
|
|
97
|
+
return l.length > 0 && bare(reply).endsWith(l);
|
|
98
|
+
}
|
|
99
|
+
/** 4.12: exactly 2 lines, every number counted from the trace, every value flattened. */
|
|
100
|
+
export function offerLines(f) {
|
|
101
|
+
const noun = JOB_CLASSES.find((j) => j.job === f.job)?.noun ?? 'job';
|
|
102
|
+
const commands = Math.max(0, Math.floor(f.commands));
|
|
103
|
+
const failed = Math.max(0, Math.floor(f.failed));
|
|
104
|
+
const cost = failed ? `${plural(commands, 'command')} this time, ${failed} failed` : `${plural(commands, 'command')} this time`;
|
|
105
|
+
const line1 = `${lead(f)} That's the ${ordinalWord(f.ordinal)} ${f.unit === 'day' ? 'day' : 'time'} I've worked out this ${noun} from scratch (${cost}).`;
|
|
106
|
+
return [flatLine(line1, 400), flatLine(keepLine(f.steps, f.where), 400)];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 1b (R12): the offer's lines through offerLinesOf (a correction's are rebuilt from the transcript); null when it has
|
|
110
|
+
* none, and then its texts are empty, so nothing goes out.
|
|
111
|
+
*/
|
|
112
|
+
function lines(o, transcriptPath, use) {
|
|
113
|
+
const l = offerLinesOf(o, transcriptPath, process.env, use);
|
|
114
|
+
return l ? [flatLine(l[0], 400), flatLine(l[1], 400)] : null;
|
|
115
|
+
}
|
|
116
|
+
const nameOf = (o) => one(o.name, 60);
|
|
117
|
+
const runOf = (o) => one(o.runId, 40);
|
|
118
|
+
/** D101: Trail's own reason for an offer, from its count: "Trail noticed this job worked out on 3 days; it offers once to keep it." */
|
|
119
|
+
function offerReason(o) {
|
|
120
|
+
const n = Math.floor(Number(o.seen?.n));
|
|
121
|
+
const how = !Number.isFinite(n) || n < 2 ? 'more than once' : o.seen?.unit === 'time' ? `${n} times` : `on ${n} days`;
|
|
122
|
+
return `Trail noticed this job worked out ${how}; it offers once to keep it.`;
|
|
123
|
+
}
|
|
124
|
+
/** Why the 2 lines end the reply: the person answers the last one, and Trail matches that answer to its words. */
|
|
125
|
+
const SO_THEY_ANSWER = 'so the person can answer (Trail reads their answer to the last line, so keep it as it is)';
|
|
126
|
+
/**
|
|
127
|
+
* 3.5: the Stop block's reason, which the agent reads. D101: from Trail, with Trail's own reason for offering; the
|
|
128
|
+
* 2 lines are Trail's question for the person, never an order to recite.
|
|
129
|
+
*/
|
|
130
|
+
export function stopBlockReason(o, transcriptPath = null, use) {
|
|
131
|
+
const both = lines(o, transcriptPath, use);
|
|
132
|
+
if (!both)
|
|
133
|
+
return '';
|
|
134
|
+
if (isPhase2(o))
|
|
135
|
+
return blockReason2(o, both);
|
|
136
|
+
if (o.moment !== 'repeated')
|
|
137
|
+
return blockReason1b(o, both);
|
|
138
|
+
const [a, b] = both;
|
|
139
|
+
return `[trail] ${FROM_TRAIL} ${offerReason(o)} If the job is done, end your reply with these 2 lines, ${SO_THEY_ANSWER}:\n${a}\n${b}\n`
|
|
140
|
+
+ `If they answer yes, run: trail skills add ${nameOf(o)} --run ${runOf(o)} (Trail checks their yes in this session before it keeps anything), then tell them the line it prints. `
|
|
141
|
+
+ `If they say show me, run trail skills draft ${runOf(o)} --print, paste what it prints, and ask "${KEEP_IT}". `
|
|
142
|
+
+ 'If they say no, Trail keeps nothing.';
|
|
143
|
+
}
|
|
144
|
+
/** 3.5: the Stop notice the person reads (channel `notice`). */
|
|
145
|
+
export function noticeText(o, transcriptPath = null, use) {
|
|
146
|
+
const both = lines(o, transcriptPath, use);
|
|
147
|
+
if (!both)
|
|
148
|
+
return '';
|
|
149
|
+
const [a, b] = both;
|
|
150
|
+
return `trail: ${a}\n${b}`;
|
|
151
|
+
}
|
|
152
|
+
/** 3.4: the passing check's PostToolUse context (channel `post-tool`). */
|
|
153
|
+
export function postToolOfferText(o, transcriptPath = null) {
|
|
154
|
+
const both = lines(o, transcriptPath);
|
|
155
|
+
if (!both)
|
|
156
|
+
return '';
|
|
157
|
+
if (isPhase2(o))
|
|
158
|
+
return postTool2(o, both);
|
|
159
|
+
if (o.moment !== 'repeated')
|
|
160
|
+
return postTool1b(o, both);
|
|
161
|
+
const [a, b] = both;
|
|
162
|
+
return `[trail] ${FROM_TRAIL} ${offerReason(o)} If this check finishes the job, end your reply with these 2 lines, ${SO_THEY_ANSWER}:\n${a}\n${b}\n`
|
|
163
|
+
+ "If the job isn't done yet, or you are about to ask the person something, leave them out.";
|
|
164
|
+
}
|
|
165
|
+
/** What "OK, not saved." grows into: the way to stop offers on the first no ever, the pause when it starts. */
|
|
166
|
+
export function notSaved(c) {
|
|
167
|
+
if (c.paused)
|
|
168
|
+
return "OK, not saved. I won't offer skills in this repo for 2 weeks. (To stop them everywhere: trail skills offers off)";
|
|
169
|
+
if (c.firstNo)
|
|
170
|
+
return 'OK, not saved. (To stop these offers: trail skills offers off)';
|
|
171
|
+
return 'OK, not saved.';
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 4.12, as context on the answering prompt; a bare no as a block where the host shows its reason (O2). D101: each
|
|
175
|
+
* directive says it is from Trail, quotes the words the person typed (`typed`, from the prompt hook's payload, never
|
|
176
|
+
* stored) and says why. 1b: a moment 3 or 4 offer's answers are `answer1b`'s, which need no lines.
|
|
177
|
+
*/
|
|
178
|
+
export function answerDirective(a, o, c, env = process.env, typed = '', host) {
|
|
179
|
+
if (isPhase2(o))
|
|
180
|
+
return answer2(a, o, c, env, typed, host);
|
|
181
|
+
if (o.moment !== 'repeated')
|
|
182
|
+
return answer1b(a, o, notSaved(c), env, typed, host);
|
|
183
|
+
switch (a) {
|
|
184
|
+
case 'yes':
|
|
185
|
+
return { context: directive(typed, `${OFFERED}, and this is their answer. To keep it as they said, run: trail skills add ${nameOf(o)} --run ${runOf(o)}. ${CHECKS_YES} Then tell them the line it prints.`) };
|
|
186
|
+
case 'show':
|
|
187
|
+
return { context: directive(typed, `${OFFERED}, and they want to see it first. Run trail skills draft ${runOf(o)} --print, paste what it prints as it is, then ask "${KEEP_IT}", since Trail reads their answer to that question.`) };
|
|
188
|
+
case 'no': {
|
|
189
|
+
const say = notSaved(c);
|
|
190
|
+
if (hostFacts(env, host).promptBlockShown)
|
|
191
|
+
return { block: `trail: ${say}` };
|
|
192
|
+
return { context: directive(typed, `${OFFERED}, and they said no, so Trail kept nothing. Let them know: "${say}"`) };
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
// The agent said the offer (stop, post-tool): it can let it go. A notice it never saw needs nothing.
|
|
196
|
+
return o.channel === 'notice' ? {} : {
|
|
197
|
+
context: directive(typed, "That isn't an answer to Trail's offer to keep the last job as a skill, so Trail dropped the offer and kept nothing. No need to bring the offer up again."),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** What an answer directive says the offer was. */
|
|
202
|
+
const OFFERED = 'Trail offered to keep the last job as a skill';
|
|
203
|
+
/** Why the agent may run the add: the gate checks the yes, the agent's word is not taken for it. */
|
|
204
|
+
const CHECKS_YES = 'Trail checks their yes in this session before it keeps anything.';
|
|
205
|
+
//# sourceMappingURL=offer-words.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offer-words.js","sourceRoot":"","sources":["../../src/skills/offer-words.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEtE,yGAAyG;AACzG,MAAM,QAAQ,GAAG,CAAC,CAA+B,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;AAQ7H,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,0GAA0G,CAAC;AAExI,mEAAmE;AACnE,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAEvD,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;IACrB,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IAC9C,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAEhF,iDAAiD;AACjD,SAAS,MAAM,CAAC,KAAe;IAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,4GAA4G;AAC5G,SAAS,WAAW,CAAC,QAAkB;IACrC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACxC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,+FAA+F;AAC/F,SAAS,IAAI,CAAC,CAAa;IACzB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;IAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACnC,OAAO,aAAa,CAAC,IAAI,iBAAiB,iBAAiB,CAAC;QAC9D,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,OAAO,CAAC;YAChD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,OAAO;gBAAE,OAAO,YAAY,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,KAAK,GAAG,CAAC;YAClF,OAAO,sBAAsB,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,GAAG,CAAC;QACtE,CAAC;QACD,KAAK,WAAW,CAAC;QACjB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,YAAY,CAAC;YACvD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjG,IAAI,OAAO,IAAI,GAAG;gBAAE,OAAO,YAAY,OAAO,OAAO,GAAG,OAAO,MAAM,GAAG,CAAC;YACzE,IAAI,OAAO;gBAAE,OAAO,YAAY,OAAO,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,aAAa,MAAM,GAAG,CAAC;YACvG,OAAO,YAAY,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,MAAM,GAAG,CAAC;QACjE,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;YAC5B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;QACxH,CAAC;QACD,KAAK,OAAO;YACV,OAAO,2BAA2B,CAAC;QACrC;YACE,OAAO,yBAAyB,CAAC;IACrC,CAAC;AACH,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,SAAS,CAAC,KAAe,EAAE,WAAqB,EAAE;IAChE,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAA2B,CAAC,CAAC;AAC5D,CAAC;AAED,qHAAqH;AACrH,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,QAAoC,WAAW;IACjF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,4CAA4C,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,wBAAwB,CAAC;AAChK,CAAC;AAED,MAAM,OAAO,GAAG,yHAAyH,CAAC;AAC1I,2EAA2E;AAC3E,MAAM,cAAc,GAAG,oGAAoG,CAAC;AAC5H,wIAAwI;AACxI,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,6FAA6F;AAC7F,MAAM,CAAC,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAE7C,8HAA8H;AAC9H,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,uCAAuC,EAAE,EAAE,CAAC,CAAC;AAE7H,iIAAiI;AACjI,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,IAAY;IACtD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,UAAU,CAAC,CAAa;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,KAAK,CAAC;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,eAAe,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,YAAY,CAAC;IAChI,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,yBAAyB,IAAI,kBAAkB,IAAI,IAAI,CAAC;IAC1J,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,SAAS,KAAK,CAAC,CAAe,EAAE,cAA6B,EAAE,GAAgB;IAC7E,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AACD,MAAM,MAAM,GAAG,CAAC,CAAe,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACpD,MAAM,KAAK,GAAG,CAAC,CAAe,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAEpD,uIAAuI;AACvI,SAAS,WAAW,CAAC,CAAe;IAClC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACtH,OAAO,qCAAqC,GAAG,8BAA8B,CAAC;AAChF,CAAC;AAED,kHAAkH;AAClH,MAAM,cAAc,GAAG,2FAA2F,CAAC;AAEnH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,CAAe,EAAE,iBAAgC,IAAI,EAAE,GAAgB;IACrG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACpB,OAAO,WAAW,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,2DAA2D,cAAc,MAAM,CAAC,KAAK,CAAC,IAAI;UACpI,6CAA6C,MAAM,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,yGAAyG;UACjL,+CAA+C,KAAK,CAAC,CAAC,CAAC,4CAA4C,OAAO,KAAK;UAC/G,sCAAsC,CAAC;AAC7C,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,CAAe,EAAE,iBAAgC,IAAI,EAAE,GAAgB;IAChG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACpB,OAAO,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;AAC7B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAAC,CAAe,EAAE,iBAAgC,IAAI;IACrF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACpB,OAAO,WAAW,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,uEAAuE,cAAc,MAAM,CAAC,KAAK,CAAC,IAAI;UAChJ,0FAA0F,CAAC;AACjG,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,QAAQ,CAAC,CAAwC;IAC/D,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,kHAAkH,CAAC;IACxI,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,gEAAgE,CAAC;IACvF,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,CAAkC,EAAE,CAAe,EAAE,CAAwC,EAAE,MAAyB,OAAO,CAAC,GAAG,EAAE,QAAgB,EAAE,EAAE,IAAW;IAClM,IAAI,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAClF,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,KAAK;YACR,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,OAAO,8EAA8E,MAAM,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,qCAAqC,CAAC,EAAE,CAAC;QAChN,KAAK,MAAM;YACT,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,OAAO,2DAA2D,KAAK,CAAC,CAAC,CAAC,sDAAsD,OAAO,qDAAqD,CAAC,EAAE,CAAC;QACxO,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,gBAAgB;gBAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,EAAE,EAAE,CAAC;YAC7E,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,OAAO,8DAA8D,GAAG,GAAG,CAAC,EAAE,CAAC;QACvH,CAAC;QACD;YACE,qGAAqG;YACrG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnC,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,0JAA0J,CAAC;aACtL,CAAC;IACN,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,MAAM,OAAO,GAAG,+CAA+C,CAAC;AAChE,oGAAoG;AACpG,MAAM,UAAU,GAAG,kEAAkE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { PendingOffer } from '../trace/types.js';
|
|
2
|
+
import type { Answer, OfferLine } from './types.js';
|
|
3
|
+
export { answerDirective, endsWithLine, isKeepLine, keepLine, noticeText, offerLines, postToolOfferText, stopBlockReason, GOVERNOR_LINE, KEEP_IT, type OfferFacts, } from './offer-words.js';
|
|
4
|
+
/** <home>/offers.jsonl */
|
|
5
|
+
export declare function offersPath(env?: NodeJS.ProcessEnv): string;
|
|
6
|
+
export declare function readOffers(env?: NodeJS.ProcessEnv): OfferLine[];
|
|
7
|
+
/** OfferLine's `answer` as the final one, null when never answered (`OfferLine & { answer: Answer | null }` can't hold null). */
|
|
8
|
+
export type OfferRecord = Omit<OfferLine, 'answer'> & {
|
|
9
|
+
answer: Answer | null;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Folds 'shown' + 'answer' + 'not-shown' lines by id: one record per offer with its final answer. The record's
|
|
13
|
+
* `at` is when it was shown; `not-shown` (the agent left it out) wins over `shown`; the last answer wins.
|
|
14
|
+
*/
|
|
15
|
+
export declare function foldOffers(lines: OfferLine[]): OfferRecord[];
|
|
16
|
+
export interface BudgetCtx {
|
|
17
|
+
repoKey: string;
|
|
18
|
+
key: string;
|
|
19
|
+
sessionOfferUsed: boolean;
|
|
20
|
+
now?: Date;
|
|
21
|
+
env?: NodeJS.ProcessEnv;
|
|
22
|
+
}
|
|
23
|
+
export type BudgetVerdict = {
|
|
24
|
+
ok: true;
|
|
25
|
+
extraDay: boolean;
|
|
26
|
+
secondChance: boolean;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
why: 'session' | 'week' | 'first-week' | 'said-no' | 'paused' | 'off' | 'off-here' | 'no-answer-twice' | 'too-soon';
|
|
30
|
+
};
|
|
31
|
+
/** 4.13, steps 1 to 8 in order. */
|
|
32
|
+
export declare function offerBudget(c: BudgetCtx): BudgetVerdict;
|
|
33
|
+
export declare function recordShown(o: PendingOffer, repoKey: string, env?: NodeJS.ProcessEnv, now?: Date): void;
|
|
34
|
+
/** A stop or post-tool offer the agent left out: the session stays spent; the week and the governor ignore it. */
|
|
35
|
+
export declare function recordNotShown(o: PendingOffer, repoKey: string, env?: NodeJS.ProcessEnv, now?: Date): void;
|
|
36
|
+
/**
|
|
37
|
+
* Records the answer and refreshes settings.lastNine. The 2nd 'no' in a row in this repo pauses it 14 days.
|
|
38
|
+
* Phase 2 (2.4): `op` says which change a yes chose (a fold op, drift's 'replace', or 'retire'); `answer` stays 1a's.
|
|
39
|
+
*/
|
|
40
|
+
export declare function recordAnswer(o: PendingOffer, repoKey: string, a: Answer, env?: NodeJS.ProcessEnv, now?: Date, op?: OfferLine['op']): {
|
|
41
|
+
paused: boolean;
|
|
42
|
+
firstNo: boolean;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* For `trail skills` (2.10): the governor line the first time it is printed while the governor is on (records
|
|
46
|
+
* governorSaidAt through noteGovernor); null otherwise. noteGovernor clears governorSaidAt when the governor turns
|
|
47
|
+
* off, so it is said again next time.
|
|
48
|
+
*/
|
|
49
|
+
export declare function governorLine(env?: NodeJS.ProcessEnv, now?: Date): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Init's `closed` line (2.4, 4.20, R53): an item the person was shown at `trail init` and didn't keep. It counts as
|
|
52
|
+
* "said no" for `key` forever, and for nothing else: not the session, the week, the first week, the pause or the
|
|
53
|
+
* governor (P10). Its only writer; b6 calls it for each skill key init closes.
|
|
54
|
+
*/
|
|
55
|
+
export declare function recordInitClosed(repoKey: string, key: string, env?: NodeJS.ProcessEnv, now?: Date): void;
|
|
56
|
+
/** Moment 5's key: `<skillId>|update|v<n>`. */
|
|
57
|
+
export declare const updateOfferKey: (skillId: string, version: number) => string;
|
|
58
|
+
/** Moment 6's key: `<skillId>|drift|v<n>`. */
|
|
59
|
+
export declare const driftOfferKey: (skillId: string, version: number) => string;
|
|
60
|
+
/** The retire proposal's key: `<skillId>|retire`. */
|
|
61
|
+
export declare const retireOfferKey: (skillId: string) => string;
|
|
62
|
+
/** The skill a skill-keyed offer names (moments 4, 5, 6 and the retire proposal); null for a repo-keyed one (2, 3). */
|
|
63
|
+
export declare function skillOfOfferKey(key: string): string | null;
|
|
64
|
+
/** 'o-' + 6 hex */
|
|
65
|
+
export declare function newOfferId(): string;
|
|
66
|
+
//# sourceMappingURL=offers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offers.d.ts","sourceRoot":"","sources":["../../src/skills/offers.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKpD,OAAO,EACL,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,UAAU,GACzJ,MAAM,kBAAkB,CAAC;AAmB1B,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAE1D;AAqBD,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,EAAE,CAgB/D;AAED,iIAAiI;AACjI,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAiB5D;AAsBD,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE;AAC3H,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GACtD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,UAAU,GAAG,iBAAiB,GAAG,UAAU,CAAA;CAAE,CAAC;AAEvI,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,aAAa,CA0BvD;AA0BD,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI,CAGnH;AAED,kHAAkH;AAClH,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI,CAEtH;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,EACvH,EAAE,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAe7D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,GAAG,IAAI,CAc3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI,CAKpH;AAgBD,+CAA+C;AAC/C,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,MAA8D,CAAC;AACjI,8CAA8C;AAC9C,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,MAA6D,CAAC;AAC/H,qDAAqD;AACrD,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAAsC,CAAC;AAGxF,uHAAuH;AACvH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1D;AAED,mBAAmB;AACnB,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill offers (design 2.5, 4.12, 4.13, spec 9): the log of every offer
|
|
3
|
+
* shown and answered (`~/.trail/offers.jsonl`, the never-ask-again list), the
|
|
4
|
+
* budget every offer shares, and the bookkeeping an answer leaves.
|
|
5
|
+
*
|
|
6
|
+
* The budget, in this order: offers off (everywhere or in this repo), a repo
|
|
7
|
+
* paused after two nos, 1 offer per session, 1 in the first week after skills
|
|
8
|
+
* go on, 3 a week, never again after a no for that (repo, job), one more
|
|
9
|
+
* chance 14+ days after an ignored offer and then never, and the governor:
|
|
10
|
+
* when fewer than 1 in 3 of the last 9 answered offers were kept, a job has
|
|
11
|
+
* to come back one more day before it is offered.
|
|
12
|
+
*
|
|
13
|
+
* The log is the truth. `settings.json` keeps only the pause and a cache of
|
|
14
|
+
* the governor's window; only this file writes them (a static test pins it).
|
|
15
|
+
* The words of an offer and of the answers to it are in `offer-words.ts`.
|
|
16
|
+
*/
|
|
17
|
+
import { randomBytes } from 'node:crypto';
|
|
18
|
+
import { localDate, noteGovernor, pauseRepo, readSettings } from './settings.js';
|
|
19
|
+
import { appendPrivateLine, trailPath } from '../util/private-fs.js';
|
|
20
|
+
import { readFileSync } from 'node:fs';
|
|
21
|
+
export { answerDirective, endsWithLine, isKeepLine, keepLine, noticeText, offerLines, postToolOfferText, stopBlockReason, GOVERNOR_LINE, KEEP_IT, } from './offer-words.js';
|
|
22
|
+
import { GOVERNOR_LINE } from './offer-words.js';
|
|
23
|
+
const DAY_MS = 86_400_000;
|
|
24
|
+
const WEEK_MS = 7 * DAY_MS;
|
|
25
|
+
const IGNORED_AFTER_MS = DAY_MS;
|
|
26
|
+
const SECOND_CHANCE_MS = 14 * DAY_MS;
|
|
27
|
+
const PAUSE_DAYS = 14;
|
|
28
|
+
const WEEK_CAP = 3;
|
|
29
|
+
const GOVERNOR_WINDOW = 9;
|
|
30
|
+
const EVENTS = new Set(['shown', 'answer', 'not-shown', 'closed']);
|
|
31
|
+
/** Phase 2 (R2): moments 5 and 6 and the retire proposal are kept as themselves; a moment this file doesn't know is
|
|
32
|
+
* written as 'repeated' (line below), so each new one must be listed here first. */
|
|
33
|
+
const MOMENTS = new Set(['repeated', 'repaired', 'correction', 'update', 'drift', 'retire']);
|
|
34
|
+
/** 2.4: what an answer line's yes chose. */
|
|
35
|
+
const OPS = new Set(['update', 'extend', 'split', 'replace', 'retire']);
|
|
36
|
+
const ANSWERS = new Set(['yes', 'no', 'show', 'none', 'withdrawn']);
|
|
37
|
+
const CHANNELS = new Set(['stop', 'notice', 'post-tool']);
|
|
38
|
+
/** <home>/offers.jsonl */
|
|
39
|
+
export function offersPath(env) {
|
|
40
|
+
return trailPath(env, 'offers.jsonl');
|
|
41
|
+
}
|
|
42
|
+
const str = (v) => typeof v === 'string';
|
|
43
|
+
function asLine(v) {
|
|
44
|
+
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
45
|
+
return null;
|
|
46
|
+
const l = v;
|
|
47
|
+
if (!str(l.id) || !str(l.at) || Number.isNaN(Date.parse(l.at)) || !EVENTS.has(l.event))
|
|
48
|
+
return null;
|
|
49
|
+
if (!str(l.repo) || !str(l.key) || !str(l.runId) || !str(l.name) || !CHANNELS.has(l.channel))
|
|
50
|
+
return null;
|
|
51
|
+
// 1b (4.20): a closed line is only ever init's, a no; every other line is an offer of moment 2, 3 or 4.
|
|
52
|
+
if (l.event === 'closed')
|
|
53
|
+
return l.moment === 'init' && l.answer === 'no' ? l : null;
|
|
54
|
+
if (!MOMENTS.has(l.moment))
|
|
55
|
+
return null;
|
|
56
|
+
if (l.event === 'answer' && !ANSWERS.has(l.answer))
|
|
57
|
+
return null;
|
|
58
|
+
// 2.4: an op outside the set is dropped, the line kept (its answer still counts).
|
|
59
|
+
if (Object.hasOwn(l, 'op') && !(l.event === 'answer' && OPS.has(l.op))) {
|
|
60
|
+
const { op: _op, ...rest } = l;
|
|
61
|
+
return rest;
|
|
62
|
+
}
|
|
63
|
+
return l;
|
|
64
|
+
}
|
|
65
|
+
export function readOffers(env) {
|
|
66
|
+
let text;
|
|
67
|
+
try {
|
|
68
|
+
text = readFileSync(offersPath(env), 'utf8');
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const raw of text.split('\n')) {
|
|
75
|
+
if (!raw.trim())
|
|
76
|
+
continue;
|
|
77
|
+
try {
|
|
78
|
+
const l = asLine(JSON.parse(raw));
|
|
79
|
+
if (l)
|
|
80
|
+
out.push(l);
|
|
81
|
+
}
|
|
82
|
+
catch { /* a bad line is skipped */ }
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Folds 'shown' + 'answer' + 'not-shown' lines by id: one record per offer with its final answer. The record's
|
|
88
|
+
* `at` is when it was shown; `not-shown` (the agent left it out) wins over `shown`; the last answer wins.
|
|
89
|
+
*/
|
|
90
|
+
export function foldOffers(lines) {
|
|
91
|
+
const byId = new Map();
|
|
92
|
+
for (const l of lines) {
|
|
93
|
+
let r = byId.get(l.id);
|
|
94
|
+
if (r === undefined) {
|
|
95
|
+
const { answer: _a, ...base } = l;
|
|
96
|
+
r = { ...base, event: l.event === 'answer' ? 'shown' : l.event, answer: null };
|
|
97
|
+
byId.set(l.id, r);
|
|
98
|
+
}
|
|
99
|
+
if (l.event === 'not-shown' && r.event !== 'closed')
|
|
100
|
+
r.event = 'not-shown';
|
|
101
|
+
if (l.event === 'closed')
|
|
102
|
+
r.answer = 'no';
|
|
103
|
+
if (l.event === 'answer' && l.answer) {
|
|
104
|
+
r.answer = l.answer;
|
|
105
|
+
if (l.op)
|
|
106
|
+
r.op = l.op;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return [...byId.values()];
|
|
110
|
+
}
|
|
111
|
+
/** yes, no or none (an ignored offer: answered none, or shown and never answered for 24 h); null otherwise, and for init's closed lines. */
|
|
112
|
+
function settled(r, now) {
|
|
113
|
+
if (r.event === 'closed')
|
|
114
|
+
return null; // "said no" for its key only (4.20, P10)
|
|
115
|
+
if (r.answer === 'yes' || r.answer === 'no' || r.answer === 'none')
|
|
116
|
+
return r.answer;
|
|
117
|
+
if (r.answer === null && r.event === 'shown' && now.getTime() - Date.parse(r.at) > IGNORED_AFTER_MS)
|
|
118
|
+
return 'none';
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const byTime = (a, b) => Date.parse(a.at) - Date.parse(b.at);
|
|
122
|
+
/** The governor's window: the last 9 offers that were kept, refused or ignored, oldest first. */
|
|
123
|
+
function lastNine(records, now) {
|
|
124
|
+
return records.slice().sort(byTime).flatMap((r) => {
|
|
125
|
+
const s = settled(r, now);
|
|
126
|
+
return s ? [s] : [];
|
|
127
|
+
}).slice(-GOVERNOR_WINDOW);
|
|
128
|
+
}
|
|
129
|
+
const governorOn = (nine) => nine.length >= 3 && nine.filter((a) => a === 'yes').length * 3 < nine.length;
|
|
130
|
+
/** 4.13, steps 1 to 8 in order. */
|
|
131
|
+
export function offerBudget(c) {
|
|
132
|
+
const now = c.now ?? new Date();
|
|
133
|
+
const s = readSettings(c.env);
|
|
134
|
+
if (s.offers === 'off')
|
|
135
|
+
return { ok: false, why: 'off' };
|
|
136
|
+
if (s.offRepos.includes(c.repoKey))
|
|
137
|
+
return { ok: false, why: 'off-here' };
|
|
138
|
+
const until = s.pausedUntil[c.repoKey];
|
|
139
|
+
if (until && until > localDate(now))
|
|
140
|
+
return { ok: false, why: 'paused' };
|
|
141
|
+
if (c.sessionOfferUsed)
|
|
142
|
+
return { ok: false, why: 'session' };
|
|
143
|
+
const records = foldOffers(readOffers(c.env));
|
|
144
|
+
const shown = records.filter((r) => r.event === 'shown');
|
|
145
|
+
const since = s.onSince === null ? NaN : Date.parse(s.onSince);
|
|
146
|
+
if (!Number.isNaN(since) && now.getTime() - since < WEEK_MS && shown.some((r) => Date.parse(r.at) >= since))
|
|
147
|
+
return { ok: false, why: 'first-week' };
|
|
148
|
+
const weekAgo = now.getTime() - WEEK_MS;
|
|
149
|
+
if (shown.filter((r) => Date.parse(r.at) > weekAgo && Date.parse(r.at) <= now.getTime() + 5000).length >= WEEK_CAP)
|
|
150
|
+
return { ok: false, why: 'week' };
|
|
151
|
+
const mine = records.filter((r) => r.key === c.key);
|
|
152
|
+
if (mine.some((r) => r.answer === 'no'))
|
|
153
|
+
return { ok: false, why: 'said-no' };
|
|
154
|
+
const ignored = mine.filter((r) => settled(r, now) === 'none');
|
|
155
|
+
let secondChance = false;
|
|
156
|
+
if (ignored.length >= 2)
|
|
157
|
+
return { ok: false, why: 'no-answer-twice' };
|
|
158
|
+
if (ignored.length === 1) {
|
|
159
|
+
if (now.getTime() - Date.parse(ignored[0].at) < SECOND_CHANCE_MS)
|
|
160
|
+
return { ok: false, why: 'too-soon' };
|
|
161
|
+
secondChance = true;
|
|
162
|
+
}
|
|
163
|
+
return { ok: true, extraDay: governorOn(lastNine(records, now)), secondChance };
|
|
164
|
+
}
|
|
165
|
+
function line(o, repoKey, event, now, answer, op) {
|
|
166
|
+
const moment = MOMENTS.has(o.moment) ? o.moment : 'repeated';
|
|
167
|
+
const l = { id: o.offerId, at: now.toISOString(), event, repo: repoKey, key: o.key, moment, runId: o.runId, name: o.name, channel: o.channel };
|
|
168
|
+
if (answer)
|
|
169
|
+
l.answer = answer;
|
|
170
|
+
if (answer && op && OPS.has(op))
|
|
171
|
+
l.op = op;
|
|
172
|
+
return l;
|
|
173
|
+
}
|
|
174
|
+
function append(l, env) {
|
|
175
|
+
appendPrivateLine(offersPath(env), JSON.stringify(l));
|
|
176
|
+
}
|
|
177
|
+
/** The governor cache in settings.json: the window as it is now; said-at kept while the governor stays on. */
|
|
178
|
+
function refreshGovernor(env, now, saidAt) {
|
|
179
|
+
const nine = lastNine(foldOffers(readOffers(env)), now);
|
|
180
|
+
const s = readSettings(env);
|
|
181
|
+
const keep = saidAt === undefined ? s.governorSaidAt : saidAt;
|
|
182
|
+
const next = governorOn(nine) ? keep : null;
|
|
183
|
+
if (JSON.stringify(s.lastNine) === JSON.stringify(nine) && s.governorSaidAt === next)
|
|
184
|
+
return;
|
|
185
|
+
try {
|
|
186
|
+
noteGovernor(nine, next, env);
|
|
187
|
+
}
|
|
188
|
+
catch { /* busy: the log stays the truth, the cache catches up next time */ }
|
|
189
|
+
}
|
|
190
|
+
export function recordShown(o, repoKey, env, now = new Date()) {
|
|
191
|
+
append(line(o, repoKey, 'shown', now), env);
|
|
192
|
+
refreshGovernor(env, now);
|
|
193
|
+
}
|
|
194
|
+
/** A stop or post-tool offer the agent left out: the session stays spent; the week and the governor ignore it. */
|
|
195
|
+
export function recordNotShown(o, repoKey, env, now = new Date()) {
|
|
196
|
+
append(line(o, repoKey, 'not-shown', now), env);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Records the answer and refreshes settings.lastNine. The 2nd 'no' in a row in this repo pauses it 14 days.
|
|
200
|
+
* Phase 2 (2.4): `op` says which change a yes chose (a fold op, drift's 'replace', or 'retire'); `answer` stays 1a's.
|
|
201
|
+
*/
|
|
202
|
+
export function recordAnswer(o, repoKey, a, env, now = new Date(), op) {
|
|
203
|
+
const before = a === 'no' ? foldOffers(readOffers(env)) : [];
|
|
204
|
+
append(line(o, repoKey, 'answer', now, a, op), env);
|
|
205
|
+
refreshGovernor(env, now);
|
|
206
|
+
if (a !== 'no')
|
|
207
|
+
return { paused: false, firstNo: false };
|
|
208
|
+
const firstNo = !before.some((r) => r.answer === 'no' && r.event !== 'closed' && r.id !== o.offerId);
|
|
209
|
+
const here = foldOffers(readOffers(env)).filter((r) => r.repo === repoKey).sort(byTime).filter((r) => settled(r, now) !== null);
|
|
210
|
+
const lastTwo = here.slice(-2);
|
|
211
|
+
if (lastTwo.length < 2 || !lastTwo.every((r) => settled(r, now) === 'no'))
|
|
212
|
+
return { paused: false, firstNo };
|
|
213
|
+
try {
|
|
214
|
+
pauseRepo(repoKey, new Date(now.getTime() + PAUSE_DAYS * DAY_MS), env);
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return { paused: false, firstNo }; // not written: not said
|
|
218
|
+
}
|
|
219
|
+
return { paused: true, firstNo };
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* For `trail skills` (2.10): the governor line the first time it is printed while the governor is on (records
|
|
223
|
+
* governorSaidAt through noteGovernor); null otherwise. noteGovernor clears governorSaidAt when the governor turns
|
|
224
|
+
* off, so it is said again next time.
|
|
225
|
+
*/
|
|
226
|
+
export function governorLine(env, now = new Date()) {
|
|
227
|
+
const nine = lastNine(foldOffers(readOffers(env)), now);
|
|
228
|
+
const s = readSettings(env);
|
|
229
|
+
if (!governorOn(nine)) {
|
|
230
|
+
if (s.governorSaidAt !== null || JSON.stringify(s.lastNine) !== JSON.stringify(nine))
|
|
231
|
+
refreshGovernor(env, now, null);
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
if (s.governorSaidAt !== null)
|
|
235
|
+
return null;
|
|
236
|
+
try {
|
|
237
|
+
noteGovernor(nine, now.toISOString(), env);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return null; // not recorded: say it next time instead of twice
|
|
241
|
+
}
|
|
242
|
+
return GOVERNOR_LINE;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Init's `closed` line (2.4, 4.20, R53): an item the person was shown at `trail init` and didn't keep. It counts as
|
|
246
|
+
* "said no" for `key` forever, and for nothing else: not the session, the week, the first week, the pause or the
|
|
247
|
+
* governor (P10). Its only writer; b6 calls it for each skill key init closes.
|
|
248
|
+
*/
|
|
249
|
+
export function recordInitClosed(repoKey, key, env, now = new Date()) {
|
|
250
|
+
append({
|
|
251
|
+
id: `o-init-${randomBytes(2).toString('hex')}`, at: now.toISOString(), event: 'closed', repo: repoKey, key, moment: 'init', runId: '', name: '',
|
|
252
|
+
channel: 'stop', answer: 'no',
|
|
253
|
+
}, env);
|
|
254
|
+
}
|
|
255
|
+
/* Keys (2.4, 4.10, P8, P13). Moments 5 and 6 are keyed per version, so a no is never asked again for that version and
|
|
256
|
+
* a new version (only after a yes, an adopted hand edit or a restore) may be offered again; the retire proposal is
|
|
257
|
+
* once per skill, ever. A key names a skill, never a repo: the offer's `repo` (1b) says where it was made. */
|
|
258
|
+
const KEY_PART = /^[^|\s]{1,200}$/;
|
|
259
|
+
function keyPart(skillId) {
|
|
260
|
+
if (!KEY_PART.test(String(skillId)))
|
|
261
|
+
throw new Error('trail: not a skill id for an offer key');
|
|
262
|
+
return skillId;
|
|
263
|
+
}
|
|
264
|
+
function keyVersion(version) {
|
|
265
|
+
if (!Number.isSafeInteger(version) || version < 1)
|
|
266
|
+
throw new Error('trail: not a skill version for an offer key');
|
|
267
|
+
return version;
|
|
268
|
+
}
|
|
269
|
+
/** Moment 5's key: `<skillId>|update|v<n>`. */
|
|
270
|
+
export const updateOfferKey = (skillId, version) => `${keyPart(skillId)}|update|v${keyVersion(version)}`;
|
|
271
|
+
/** Moment 6's key: `<skillId>|drift|v<n>`. */
|
|
272
|
+
export const driftOfferKey = (skillId, version) => `${keyPart(skillId)}|drift|v${keyVersion(version)}`;
|
|
273
|
+
/** The retire proposal's key: `<skillId>|retire`. */
|
|
274
|
+
export const retireOfferKey = (skillId) => `${keyPart(skillId)}|retire`;
|
|
275
|
+
const SKILL_KEY = /^([^|\s]{1,200})\|(?:correction|update\|v[1-9]\d*|drift\|v[1-9]\d*|retire)$/;
|
|
276
|
+
/** The skill a skill-keyed offer names (moments 4, 5, 6 and the retire proposal); null for a repo-keyed one (2, 3). */
|
|
277
|
+
export function skillOfOfferKey(key) {
|
|
278
|
+
return SKILL_KEY.exec(String(key))?.[1] ?? null;
|
|
279
|
+
}
|
|
280
|
+
/** 'o-' + 6 hex */
|
|
281
|
+
export function newOfferId() {
|
|
282
|
+
return `o-${randomBytes(3).toString('hex')}`;
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=offers.js.map
|