@codyswann/lisa 4.84.11 → 4.86.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/dist/cli/doctor-session-manager-pending.d.ts +17 -0
- package/dist/cli/doctor-session-manager-pending.d.ts.map +1 -0
- package/dist/cli/doctor-session-manager-pending.js +130 -0
- package/dist/cli/doctor-session-manager-pending.js.map +1 -0
- package/dist/cli/doctor-session-manager-token.d.ts +69 -0
- package/dist/cli/doctor-session-manager-token.d.ts.map +1 -0
- package/dist/cli/doctor-session-manager-token.js +264 -0
- package/dist/cli/doctor-session-manager-token.js.map +1 -0
- package/dist/cli/doctor-session-manager.d.ts +3 -1
- package/dist/cli/doctor-session-manager.d.ts.map +1 -1
- package/dist/cli/doctor-session-manager.js +168 -146
- package/dist/cli/doctor-session-manager.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +34 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +172 -23
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa/commands/session-manager.md +1 -1
- package/plugins/lisa/commands/setup/session-manager.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +39 -7
- package/plugins/lisa/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa-agy/commands/lisa/session-manager.md +1 -1
- package/plugins/lisa-agy/commands/lisa/setup/session-manager.md +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa-agy/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa-agy/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa-agy/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/commands/lisa/session-manager.md +1 -1
- package/plugins/lisa-copilot/commands/lisa/setup/session-manager.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +39 -7
- package/plugins/lisa-copilot/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa-copilot/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa-copilot/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa-copilot/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/commands/lisa/session-manager.md +1 -1
- package/plugins/lisa-cursor/commands/lisa/setup/session-manager.md +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +39 -7
- package/plugins/lisa-cursor/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa-cursor/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa-cursor/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa-cursor/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/rules/reference/config-resolution.md +39 -7
- package/plugins/lisa-devin/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/lisa-devin/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/lisa-devin/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/lisa-devin/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/commands/session-manager.md +1 -1
- package/plugins/src/base/commands/setup/session-manager.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +39 -7
- package/plugins/src/base/skills/lisa-secrets-access/SKILL.md +5 -3
- package/plugins/src/base/skills/lisa-secrets-access/scripts/providers.mjs +121 -3
- package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +47 -26
- package/plugins/src/base/skills/lisa-session-manager/SKILL.md +197 -54
- package/plugins/src/base/skills/lisa-session-manager/references/runbook-template.md +23 -10
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-cycle.mjs +21 -3
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-human.mjs +199 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager-token.mjs +99 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-manager.mjs +52 -52
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-queue.mjs +51 -139
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-runtime.mjs +5 -3
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-setup.mjs +94 -14
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-status.mjs +73 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +105 -15
- package/plugins/src/base/skills/lisa-session-manager/scripts/config.mjs +39 -11
- package/plugins/src/base/skills/lisa-session-manager/scripts/human-answer.mjs +162 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/human-needed.mjs +198 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/json-input.mjs +34 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/launch-shell.mjs +115 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/launch.mjs +69 -60
- package/plugins/src/base/skills/lisa-session-manager/scripts/ledger-questions.mjs +252 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/ledger.mjs +22 -56
- package/plugins/src/base/skills/lisa-session-manager/scripts/queue-github.mjs +117 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/session-manager.mjs +17 -5
- package/plugins/src/base/skills/lisa-session-manager/scripts/token-migrate.mjs +180 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/token-provider.mjs +150 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/token-read.mjs +166 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/token-store.mjs +248 -0
- package/plugins/src/base/skills/lisa-session-manager/scripts/token.mjs +39 -120
- package/plugins/src/base/skills/lisa-setup-session-manager/SKILL.md +82 -19
- package/rails/copy-overwrite/scripts/lisa-rspec-shards.mjs +747 -0
- package/rails/copy-overwrite/scripts/lisa_rspec_shard_recorder.rb +143 -0
- package/rails/copy-overwrite/scripts/lisa_simplecov_collate.rb +51 -0
- package/rails/create-only/.github/workflows/ci.yml +4 -0
- package/scripts/two-channel-couplings.json +89 -7
- package/typescript/copy-overwrite/.prettierignore +1 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Starting and stopping the session manager, and the Telegram bot token it
|
|
3
|
-
* needs.
|
|
3
|
+
* needs when Telegram is its notification channel. Telegram is optional
|
|
4
|
+
* (#4555): with `notify.provider` `"none"` the manager launches with no
|
|
5
|
+
* channel, no state dir and no plugin, and none of the isolation below applies.
|
|
4
6
|
*
|
|
5
7
|
* The official Telegram plugin keeps its token, pairing list, inbox and
|
|
6
8
|
* `bot.pid` in one state dir (`TELEGRAM_STATE_DIR`, else
|
|
@@ -11,16 +13,20 @@
|
|
|
11
13
|
* env, and the shared default dir is refused outright;
|
|
12
14
|
* - the plugin is enabled only through the manager's own `--settings`, never
|
|
13
15
|
* at user scope, so worker sessions never start a poller;
|
|
14
|
-
* - the token lives in
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* - the token lives in the project's secrets provider when one is configured
|
|
17
|
+
* (token-store.mjs, #4555), reaching the manager's tmux session through
|
|
18
|
+
* `source-file -` on stdin ({@link buildSourcedLaunch}); with no provider it
|
|
19
|
+
* lives in `<stateDir>/.env` (dir 0700, file 0600). Either way it is read
|
|
20
|
+
* from the operator's terminal with echo off (or the clipboard), and never
|
|
21
|
+
* appears in argv, a return value, an error message or a log line.
|
|
17
22
|
*
|
|
18
23
|
* The tmux argv is returned as an array and handed straight to `spawnSync`.
|
|
19
24
|
* With more than one command argument tmux runs the command directly rather
|
|
20
25
|
* than through `sh -c`, so the settings JSON and the loop prompt are never
|
|
21
26
|
* re-parsed by a shell.
|
|
22
27
|
*
|
|
23
|
-
* The state dir lives in state-dir.mjs
|
|
28
|
+
* The state dir lives in state-dir.mjs, the token in token.mjs, and the
|
|
29
|
+
* foreground and stdin renderings of the launch in launch-shell.mjs; all are
|
|
24
30
|
* re-exported here so callers keep one import.
|
|
25
31
|
*
|
|
26
32
|
* Everything here is pure or takes injected seams. This module never reads
|
|
@@ -33,6 +39,11 @@ import path from "node:path";
|
|
|
33
39
|
import { parseLoopInterval } from "./config.mjs";
|
|
34
40
|
import { LaunchError } from "./state-dir.mjs";
|
|
35
41
|
|
|
42
|
+
export {
|
|
43
|
+
buildForegroundCommand,
|
|
44
|
+
buildSourcedLaunch,
|
|
45
|
+
tmuxQuote,
|
|
46
|
+
} from "./launch-shell.mjs";
|
|
36
47
|
export {
|
|
37
48
|
LaunchError,
|
|
38
49
|
realpathExisting,
|
|
@@ -42,6 +53,8 @@ export {
|
|
|
42
53
|
assertTokenPresent,
|
|
43
54
|
buildStoreTokenCommand,
|
|
44
55
|
loadPromptSecret,
|
|
56
|
+
readTokenFromClipboard,
|
|
57
|
+
readTokenFromPrompt,
|
|
45
58
|
storeToken,
|
|
46
59
|
storeTokenFromClipboard,
|
|
47
60
|
validateBotToken,
|
|
@@ -54,26 +67,28 @@ export const TELEGRAM_PLUGIN_ID = "telegram@claude-plugins-official";
|
|
|
54
67
|
/** Same slug rule the config validator applies to `sessionManager.name`. */
|
|
55
68
|
const SESSION_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
56
69
|
|
|
57
|
-
/** A `'` inside a single-quoted shell word: close, escaped quote, reopen. */
|
|
58
|
-
const ESCAPED_QUOTE = "'\\''";
|
|
59
|
-
|
|
60
|
-
/** An argument a POSIX shell reads back unchanged without quotes. */
|
|
61
|
-
const SHELL_SAFE = /^[A-Za-z0-9_@%+=:,./-]+$/;
|
|
62
|
-
|
|
63
70
|
/** The skill command each manager loop iteration runs. */
|
|
64
71
|
const CYCLE_COMMAND = "/lisa:session-manager cycle";
|
|
65
72
|
|
|
73
|
+
/** The notification providers a launch can be built for. */
|
|
74
|
+
const LAUNCH_NOTIFY = new Set(["none", "telegram"]);
|
|
75
|
+
|
|
66
76
|
/**
|
|
67
|
-
* Settings blob for the manager session only:
|
|
68
|
-
*
|
|
77
|
+
* Settings blob for the manager session only: workers' messages accepted,
|
|
78
|
+
* and the Telegram plugin on when Telegram is the notification channel. With
|
|
79
|
+
* no channel (`"none"`) the plugin is left out entirely, so the manager never
|
|
80
|
+
* starts a poller (#4555).
|
|
81
|
+
* @param {string} [notify] - Notification provider: "telegram" (default) or "none"
|
|
69
82
|
* @returns {{ crossSessionInbound: "accept",
|
|
70
|
-
* enabledPlugins
|
|
83
|
+
* enabledPlugins?: Record<string, boolean> }} Fresh settings object
|
|
71
84
|
*/
|
|
72
|
-
export function buildManagerSettings() {
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
export function buildManagerSettings(notify = "telegram") {
|
|
86
|
+
return notify === "telegram"
|
|
87
|
+
? {
|
|
88
|
+
crossSessionInbound: "accept",
|
|
89
|
+
enabledPlugins: { [TELEGRAM_PLUGIN_ID]: true },
|
|
90
|
+
}
|
|
91
|
+
: { crossSessionInbound: "accept" };
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
/**
|
|
@@ -111,9 +126,15 @@ function assertAbsolute(label, value) {
|
|
|
111
126
|
* `TELEGRAM_STATE_DIR` goes only into this session's env so no other session
|
|
112
127
|
* ever sees it. `SM_SCRIPTS_DIR` lets every cycle's Bash find these scripts
|
|
113
128
|
* without re-resolving the plugin root.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
129
|
+
*
|
|
130
|
+
* With `notify: "none"` there is no channel: no `TELEGRAM_STATE_DIR`, no
|
|
131
|
+
* `--channels` and no plugin in the settings, and a `stateDir` is refused
|
|
132
|
+
* because only the telegram provider uses one (#4555).
|
|
133
|
+
* @param {{ name: string, root: string, stateDir?: string,
|
|
134
|
+
* scriptsDir: string, interval: string,
|
|
135
|
+
* notify?: string }} input - Session name, project root,
|
|
136
|
+
* resolved state dir (telegram only), this scripts dir, the loop interval
|
|
137
|
+
* (e.g. "5m") and the notification provider (default telegram)
|
|
117
138
|
* @returns {string[]} argv for `spawnSync("tmux", argv)`
|
|
118
139
|
*/
|
|
119
140
|
export function buildManagerLaunch({
|
|
@@ -122,10 +143,11 @@ export function buildManagerLaunch({
|
|
|
122
143
|
stateDir,
|
|
123
144
|
scriptsDir,
|
|
124
145
|
interval,
|
|
146
|
+
notify = "telegram",
|
|
125
147
|
}) {
|
|
126
148
|
assertSessionName(name);
|
|
127
149
|
assertAbsolute("root", root);
|
|
128
|
-
|
|
150
|
+
const telegram = assertNotify(notify, stateDir) === "telegram";
|
|
129
151
|
assertAbsolute("scriptsDir", scriptsDir);
|
|
130
152
|
if (parseLoopInterval(interval) === null) {
|
|
131
153
|
throw new LaunchError(
|
|
@@ -139,8 +161,7 @@ export function buildManagerLaunch({
|
|
|
139
161
|
name,
|
|
140
162
|
"-c",
|
|
141
163
|
root,
|
|
142
|
-
"-e",
|
|
143
|
-
`TELEGRAM_STATE_DIR=${stateDir}`,
|
|
164
|
+
...(telegram ? ["-e", `TELEGRAM_STATE_DIR=${stateDir}`] : []),
|
|
144
165
|
"-e",
|
|
145
166
|
`SM_SCRIPTS_DIR=${scriptsDir}`,
|
|
146
167
|
"claude",
|
|
@@ -148,50 +169,38 @@ export function buildManagerLaunch({
|
|
|
148
169
|
name,
|
|
149
170
|
"--dangerously-skip-permissions",
|
|
150
171
|
"--settings",
|
|
151
|
-
JSON.stringify(buildManagerSettings()),
|
|
152
|
-
"--channels",
|
|
153
|
-
`plugin:${TELEGRAM_PLUGIN_ID}`,
|
|
172
|
+
JSON.stringify(buildManagerSettings(notify)),
|
|
173
|
+
...(telegram ? ["--channels", `plugin:${TELEGRAM_PLUGIN_ID}`] : []),
|
|
154
174
|
// `--channels` is variadic (claude 2.1.296): without `--` it takes the
|
|
155
175
|
// prompt as a second channel entry and claude exits 1 ("--channels
|
|
156
|
-
// entries must be tagged") before the session starts.
|
|
176
|
+
// entries must be tagged") before the session starts. Kept with no
|
|
177
|
+
// channel too, so the prompt is never read as an option.
|
|
157
178
|
"--",
|
|
158
179
|
`/loop ${interval} ${CYCLE_COMMAND}`,
|
|
159
180
|
];
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* @
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return `'${value.replaceAll("'", ESCAPED_QUOTE)}'`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* The shell line an operator runs to start the manager in the foreground,
|
|
173
|
-
* from the tmux argv {@link buildManagerLaunch} returned: same cwd, the same
|
|
174
|
-
* two session variables, the same claude argv. `start` prints it when the
|
|
175
|
-
* tmux session dies at once, because tmux closes the window and claude's own
|
|
176
|
-
* error goes with it. It is display text only and is never executed here.
|
|
177
|
-
* The token is not in the argv, so it is not in this line either.
|
|
178
|
-
* @param {readonly string[]} argv - Result of {@link buildManagerLaunch}
|
|
179
|
-
* @returns {string} One shell line
|
|
184
|
+
* Refuse an unsupported provider, a telegram launch without an absolute state
|
|
185
|
+
* dir, and a state dir on a launch with no channel.
|
|
186
|
+
* @param {unknown} notify - Notification provider
|
|
187
|
+
* @param {unknown} stateDir - Resolved state dir, if any
|
|
188
|
+
* @returns {"telegram" | "none"} The provider
|
|
180
189
|
*/
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return
|
|
190
|
+
function assertNotify(notify, stateDir) {
|
|
191
|
+
if (!LAUNCH_NOTIFY.has(notify)) {
|
|
192
|
+
throw new LaunchError(
|
|
193
|
+
`notify "${String(notify)}" is not supported; use "none" or "telegram".`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
if (notify === "telegram") {
|
|
197
|
+
assertAbsolute("stateDir", stateDir);
|
|
198
|
+
} else if (stateDir !== undefined) {
|
|
199
|
+
throw new LaunchError(
|
|
200
|
+
`stateDir is only used with the telegram provider; notify is "none".`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return notify;
|
|
195
204
|
}
|
|
196
205
|
|
|
197
206
|
/**
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ledger side of "mark and move on" (CodySwannGT/lisa#4555, part 3):
|
|
3
|
+
* recording that an item's human-needed mark was read back on the tracker,
|
|
4
|
+
* queueing a human's answer for the next cycle to deliver, and listing what
|
|
5
|
+
* is waiting on a person.
|
|
6
|
+
*
|
|
7
|
+
* The manager records a question in the ledger BEFORE it writes the tracker
|
|
8
|
+
* marker, then records `marked` once the marker is read back. A crash in
|
|
9
|
+
* between leaves a pending question with `markedAt: null`, which the next
|
|
10
|
+
* cycle (and `lisa doctor`) can see and finish, rather than a marker on the
|
|
11
|
+
* tracker the ledger knows nothing about and so would never remove.
|
|
12
|
+
*
|
|
13
|
+
* Recording and clearing the question itself ({@link setPendingQuestion},
|
|
14
|
+
* {@link clearPendingQuestion}) lives here too; ledger.mjs re-exports both.
|
|
15
|
+
* Writes go through ledger.mjs's atomic read-transform-write.
|
|
16
|
+
* @module session-manager/ledger-questions
|
|
17
|
+
*/
|
|
18
|
+
import { HUMAN_NEEDED_KINDS } from "./human-needed.mjs";
|
|
19
|
+
import {
|
|
20
|
+
placeholderItem,
|
|
21
|
+
requireItem,
|
|
22
|
+
updateLedger,
|
|
23
|
+
withItem,
|
|
24
|
+
} from "./ledger.mjs";
|
|
25
|
+
|
|
26
|
+
/** Ways an item can be marked human-needed. */
|
|
27
|
+
const MARKER_TYPES = new Set(["label", "role"]);
|
|
28
|
+
|
|
29
|
+
/** A tracker comment id: GitHub numeric or node id, Jira id, Linear uuid. */
|
|
30
|
+
const COMMENT_ID = /^[A-Za-z0-9_.:-]{1,200}$/;
|
|
31
|
+
|
|
32
|
+
/** Where a queued answer came from. */
|
|
33
|
+
const ANSWER_SOURCES = new Set(["cli", "item", "channel"]);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The item's pending question, or a refusal naming the ref.
|
|
37
|
+
* @param {import("./ledger.mjs").LedgerItem} entry - Ledger item
|
|
38
|
+
* @param {string} ref - Its ref
|
|
39
|
+
* @returns {NonNullable<import("./ledger.mjs").LedgerItem["pendingQuestion"]>}
|
|
40
|
+
* The pending question
|
|
41
|
+
*/
|
|
42
|
+
function requirePending(entry, ref) {
|
|
43
|
+
if (!entry.pendingQuestion) {
|
|
44
|
+
throw new Error(`${ref} has no pending question in the ledger`);
|
|
45
|
+
}
|
|
46
|
+
return entry.pendingQuestion;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Record that the item's human-needed marker was applied and read back.
|
|
51
|
+
* @param {string} projectRoot - Absolute project root
|
|
52
|
+
* `commentId` is the id of the question comment the manager posted, read
|
|
53
|
+
* back from `lisa-tracker-write`. It is kept in `managerCommentIds` so
|
|
54
|
+
* `item-answer` never takes the manager's own comment as an answer, whoever
|
|
55
|
+
* the tracker says wrote it and whatever it says.
|
|
56
|
+
* @param {{ref: string, markerType: string, marker: string,
|
|
57
|
+
* commentId?: string}} mark - The mark
|
|
58
|
+
* @param {import("./ledger.mjs").LedgerSeams} [seams] - Injected seams
|
|
59
|
+
* @returns {Promise<import("./ledger.mjs").LedgerItem>} The updated item
|
|
60
|
+
*/
|
|
61
|
+
export function recordMarked(
|
|
62
|
+
projectRoot,
|
|
63
|
+
{ ref, markerType, marker, commentId },
|
|
64
|
+
seams
|
|
65
|
+
) {
|
|
66
|
+
if (!MARKER_TYPES.has(markerType)) {
|
|
67
|
+
return Promise.reject(new Error("--marker-type must be label or role."));
|
|
68
|
+
}
|
|
69
|
+
if (typeof marker !== "string" || marker.trim() === "") {
|
|
70
|
+
return Promise.reject(new Error("--marker must name the label or role."));
|
|
71
|
+
}
|
|
72
|
+
if (commentId !== undefined && !COMMENT_ID.test(commentId)) {
|
|
73
|
+
return Promise.reject(
|
|
74
|
+
new Error("--comment-id must be the tracker's comment id.")
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
78
|
+
const previous = requireItem(ledger, ref);
|
|
79
|
+
const pending = requirePending(previous, ref);
|
|
80
|
+
return withItem(ledger, ref, {
|
|
81
|
+
...previous,
|
|
82
|
+
pendingQuestion: {
|
|
83
|
+
...pending,
|
|
84
|
+
markerType,
|
|
85
|
+
marker,
|
|
86
|
+
markedAt: at,
|
|
87
|
+
managerCommentIds: [
|
|
88
|
+
...new Set([
|
|
89
|
+
...(pending.managerCommentIds ?? []),
|
|
90
|
+
...(commentId === undefined ? [] : [commentId]),
|
|
91
|
+
]),
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
history: [
|
|
95
|
+
...(previous.history ?? []),
|
|
96
|
+
{ event: "marked", at, markerType, marker },
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Queue a human's answer on a pending question. The manager delivers it on
|
|
104
|
+
* its next cycle (SendMessage, or `resume`), then clears the question.
|
|
105
|
+
* @param {string} projectRoot - Absolute project root
|
|
106
|
+
* @param {{ref: string, source: string, text: string, author?: string|null}}
|
|
107
|
+
* answer - The answer
|
|
108
|
+
* @param {import("./ledger.mjs").LedgerSeams} [seams] - Injected seams
|
|
109
|
+
* @returns {Promise<import("./ledger.mjs").LedgerItem>} The updated item
|
|
110
|
+
*/
|
|
111
|
+
export function queueAnswer(
|
|
112
|
+
projectRoot,
|
|
113
|
+
{ ref, source, text, author = null },
|
|
114
|
+
seams
|
|
115
|
+
) {
|
|
116
|
+
if (!ANSWER_SOURCES.has(source)) {
|
|
117
|
+
return Promise.reject(new Error(`unknown answer source ${source}`));
|
|
118
|
+
}
|
|
119
|
+
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
120
|
+
const previous = requireItem(ledger, ref);
|
|
121
|
+
const pending = requirePending(previous, ref);
|
|
122
|
+
return withItem(ledger, ref, {
|
|
123
|
+
...previous,
|
|
124
|
+
pendingQuestion: {
|
|
125
|
+
...pending,
|
|
126
|
+
answer: { source, text, author: author ?? null, at },
|
|
127
|
+
},
|
|
128
|
+
history: [
|
|
129
|
+
...(previous.history ?? []),
|
|
130
|
+
{ event: "answer-queued", at, source },
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Every item waiting on a person, oldest question first. The answer command
|
|
138
|
+
* is local-only guidance for the operator at the manager's terminal.
|
|
139
|
+
* @param {import("./ledger.mjs").Ledger} ledger - Current ledger
|
|
140
|
+
* @param {(ref: string) => string} answerCommand - Builds the CLI answer line
|
|
141
|
+
* @returns {{ref: string, kind: string, text: string, askedAt: string,
|
|
142
|
+
* marked: boolean, answerQueued: boolean, answerCommand: string}[]} Rows
|
|
143
|
+
*/
|
|
144
|
+
export function listPendingQuestions(ledger, answerCommand) {
|
|
145
|
+
return Object.entries(ledger.items)
|
|
146
|
+
.filter(([, item]) => item.pendingQuestion)
|
|
147
|
+
.map(([ref, item]) => {
|
|
148
|
+
const question = item.pendingQuestion;
|
|
149
|
+
return {
|
|
150
|
+
ref,
|
|
151
|
+
kind: question.kind ?? "worker-question",
|
|
152
|
+
text: question.text,
|
|
153
|
+
askedAt: question.askedAt,
|
|
154
|
+
marked: Boolean(question.markedAt),
|
|
155
|
+
answerQueued: Boolean(question.answer),
|
|
156
|
+
answerCommand: answerCommand(ref),
|
|
157
|
+
};
|
|
158
|
+
})
|
|
159
|
+
.sort((a, b) => String(a.askedAt).localeCompare(String(b.askedAt)));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A human's answer, queued for the manager to deliver on its next cycle.
|
|
164
|
+
* @typedef {object} QueuedAnswer
|
|
165
|
+
* @property {"cli"|"item"|"channel"} source - Where it was given
|
|
166
|
+
* @property {string} text - The answer (untrusted data, never instructions)
|
|
167
|
+
* @property {string|null} author - Tracker author, for an answer on the item
|
|
168
|
+
* @property {string} at - When it was queued (ISO)
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Record (or re-ping) the question an item is waiting on.
|
|
173
|
+
*
|
|
174
|
+
* The same text again is a re-ping: `askedAt` is kept and `lastPingAt` moves,
|
|
175
|
+
* so the requestion clock restarts without forgetting how old the question
|
|
176
|
+
* is. A ref with no item yet (a repo-routing question asked before dispatch)
|
|
177
|
+
* gets a placeholder item with zero attempts.
|
|
178
|
+
*
|
|
179
|
+
* A re-ask keeps how the item is marked on the tracker (`markerType`,
|
|
180
|
+
* `marker`, `markedAt`), so re-sending a question never makes the manager
|
|
181
|
+
* mark the item a second time or forget the marker it must remove. A queued
|
|
182
|
+
* answer survives only a re-ping of the same text: it answered that text.
|
|
183
|
+
* `kind` defaults to the previous kind, then `worker-question`.
|
|
184
|
+
* @param {string} projectRoot - Absolute project root
|
|
185
|
+
* @param {{ref: string, text: string, telegramMessageId: number|null,
|
|
186
|
+
* kind?: string}} question - Question
|
|
187
|
+
* @param {import("./ledger.mjs").LedgerSeams} [seams] - Injected seams
|
|
188
|
+
* @returns {Promise<import("./ledger.mjs").LedgerItem>} The updated item
|
|
189
|
+
*/
|
|
190
|
+
export function setPendingQuestion(
|
|
191
|
+
projectRoot,
|
|
192
|
+
{ ref, text, telegramMessageId, kind },
|
|
193
|
+
seams
|
|
194
|
+
) {
|
|
195
|
+
if (kind !== undefined && !HUMAN_NEEDED_KINDS.includes(kind)) {
|
|
196
|
+
return Promise.reject(
|
|
197
|
+
new Error(
|
|
198
|
+
`question kind must be one of ${HUMAN_NEEDED_KINDS.join(", ")}, got ${JSON.stringify(kind)}`
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
203
|
+
const previous = ledger.items[ref] ?? placeholderItem();
|
|
204
|
+
const existing = previous.pendingQuestion;
|
|
205
|
+
const sameText = existing?.text === text;
|
|
206
|
+
return withItem(ledger, ref, {
|
|
207
|
+
...previous,
|
|
208
|
+
pendingQuestion: {
|
|
209
|
+
text,
|
|
210
|
+
kind: kind ?? existing?.kind ?? "worker-question",
|
|
211
|
+
askedAt: sameText ? existing.askedAt : at,
|
|
212
|
+
lastPingAt: at,
|
|
213
|
+
telegramMessageId: telegramMessageId ?? null,
|
|
214
|
+
markerType: existing?.markerType ?? null,
|
|
215
|
+
marker: existing?.marker ?? null,
|
|
216
|
+
markedAt: existing?.markedAt ?? null,
|
|
217
|
+
managerCommentIds: existing?.managerCommentIds ?? [],
|
|
218
|
+
answer: sameText ? (existing.answer ?? null) : null,
|
|
219
|
+
},
|
|
220
|
+
history: [...(previous.history ?? []), { event: "question", at }],
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Clear an item's pending question, once its answer has been delivered and
|
|
227
|
+
* the manager's own marker removed. `resetAttempts` zeroes the attempt count:
|
|
228
|
+
* an `exhausted` item a human has answered starts again from attempt one
|
|
229
|
+
* instead of being exhausted again on its first stall.
|
|
230
|
+
* @param {string} projectRoot - Absolute project root
|
|
231
|
+
* @param {{ref: string, resetAttempts?: boolean}} target - Item
|
|
232
|
+
* @param {import("./ledger.mjs").LedgerSeams} [seams] - Injected seams
|
|
233
|
+
* @returns {Promise<import("./ledger.mjs").LedgerItem>} The updated item
|
|
234
|
+
*/
|
|
235
|
+
export function clearPendingQuestion(
|
|
236
|
+
projectRoot,
|
|
237
|
+
{ ref, resetAttempts = false },
|
|
238
|
+
seams
|
|
239
|
+
) {
|
|
240
|
+
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
241
|
+
const previous = requireItem(ledger, ref);
|
|
242
|
+
return withItem(ledger, ref, {
|
|
243
|
+
...previous,
|
|
244
|
+
pendingQuestion: null,
|
|
245
|
+
...(resetAttempts ? { attempts: 0 } : {}),
|
|
246
|
+
history: [
|
|
247
|
+
...(previous.history ?? []),
|
|
248
|
+
{ event: "answered", at, ...(resetAttempts ? { reset: true } : {}) },
|
|
249
|
+
],
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
@@ -21,6 +21,14 @@ import { randomUUID } from "node:crypto";
|
|
|
21
21
|
import * as nodeFs from "node:fs/promises";
|
|
22
22
|
import { dirname, join } from "node:path";
|
|
23
23
|
|
|
24
|
+
// The question writers live in ledger-questions.mjs (#4555), re-exported so
|
|
25
|
+
// callers keep one import. They are called, never evaluated, at load time, so
|
|
26
|
+
// the import cycle back to this module's primitives is safe.
|
|
27
|
+
export {
|
|
28
|
+
clearPendingQuestion,
|
|
29
|
+
setPendingQuestion,
|
|
30
|
+
} from "./ledger-questions.mjs";
|
|
31
|
+
|
|
24
32
|
/** Shape version, bumped only on an incompatible change. */
|
|
25
33
|
const LEDGER_VERSION = 1;
|
|
26
34
|
|
|
@@ -43,6 +51,16 @@ const FINISH_STATUSES = new Set(["DONE", "FAILED"]);
|
|
|
43
51
|
* @property {string} askedAt - When it was first asked (ISO)
|
|
44
52
|
* @property {string} lastPingAt - When it was last (re-)sent (ISO)
|
|
45
53
|
* @property {number|null} telegramMessageId - Telegram message carrying it
|
|
54
|
+
* @property {string} [kind] - Why a human is needed: worker-question |
|
|
55
|
+
* repo-route | exhausted | decision (#4555)
|
|
56
|
+
* @property {"label"|"role"|null} [markerType] - How the item is marked
|
|
57
|
+
* human-needed on the tracker, once the manager has read the mark back
|
|
58
|
+
* @property {string|null} [marker] - The label or role value it carries
|
|
59
|
+
* @property {string|null} [markedAt] - When the mark was read back (ISO);
|
|
60
|
+
* null means recorded but not yet marked on the tracker
|
|
61
|
+
* @property {string[]} [managerCommentIds] - Ids of the comments the manager
|
|
62
|
+
* posted on the item (its question comment), never read as an answer
|
|
63
|
+
* @property {import("./ledger-questions.mjs").QueuedAnswer|null} [answer] - An answer waiting to be delivered
|
|
46
64
|
*/
|
|
47
65
|
|
|
48
66
|
/**
|
|
@@ -199,7 +217,7 @@ export async function writeLedger(projectRoot, ledger, seams) {
|
|
|
199
217
|
* @param {(ledger: Ledger, at: string) => {ledger: Ledger, result: T}} transform - Pure update
|
|
200
218
|
* @returns {Promise<T>} The transform's result
|
|
201
219
|
*/
|
|
202
|
-
async function updateLedger(projectRoot, seams, transform) {
|
|
220
|
+
export async function updateLedger(projectRoot, seams, transform) {
|
|
203
221
|
const { now } = resolveSeams(seams);
|
|
204
222
|
const current = await readLedger(projectRoot, seams);
|
|
205
223
|
const { ledger, result } = transform(current, now().toISOString());
|
|
@@ -214,7 +232,7 @@ async function updateLedger(projectRoot, seams, transform) {
|
|
|
214
232
|
* @param {LedgerItem} entry - New item
|
|
215
233
|
* @returns {{ledger: Ledger, result: LedgerItem}} Update
|
|
216
234
|
*/
|
|
217
|
-
function withItem(ledger, ref, entry) {
|
|
235
|
+
export function withItem(ledger, ref, entry) {
|
|
218
236
|
return {
|
|
219
237
|
ledger: { ...ledger, items: { ...ledger.items, [ref]: entry } },
|
|
220
238
|
result: entry,
|
|
@@ -227,7 +245,7 @@ function withItem(ledger, ref, entry) {
|
|
|
227
245
|
* @param {string} ref - Item key
|
|
228
246
|
* @returns {LedgerItem} The item
|
|
229
247
|
*/
|
|
230
|
-
function requireItem(ledger, ref) {
|
|
248
|
+
export function requireItem(ledger, ref) {
|
|
231
249
|
const entry = ledger.items[ref];
|
|
232
250
|
if (!entry)
|
|
233
251
|
throw new Error(
|
|
@@ -240,7 +258,7 @@ function requireItem(ledger, ref) {
|
|
|
240
258
|
* A ledger item for a ref the manager has asked about but not dispatched.
|
|
241
259
|
* @returns {LedgerItem} Placeholder item
|
|
242
260
|
*/
|
|
243
|
-
function placeholderItem() {
|
|
261
|
+
export function placeholderItem() {
|
|
244
262
|
return {
|
|
245
263
|
repo: null,
|
|
246
264
|
worker: null,
|
|
@@ -291,58 +309,6 @@ export function recordSpawn(
|
|
|
291
309
|
});
|
|
292
310
|
}
|
|
293
311
|
|
|
294
|
-
/**
|
|
295
|
-
* Record (or re-ping) the question an item is waiting on.
|
|
296
|
-
*
|
|
297
|
-
* The same text again is a re-ping: `askedAt` is kept and `lastPingAt` moves,
|
|
298
|
-
* so the requestion clock restarts without forgetting how old the question
|
|
299
|
-
* is. A ref with no item yet (a repo-routing question asked before dispatch)
|
|
300
|
-
* gets a placeholder item with zero attempts.
|
|
301
|
-
* @param {string} projectRoot - Absolute project root
|
|
302
|
-
* @param {{ref: string, text: string, telegramMessageId: number|null}} question - Question
|
|
303
|
-
* @param {LedgerSeams} [seams] - Injected seams
|
|
304
|
-
* @returns {Promise<LedgerItem>} The updated item
|
|
305
|
-
*/
|
|
306
|
-
export function setPendingQuestion(
|
|
307
|
-
projectRoot,
|
|
308
|
-
{ ref, text, telegramMessageId },
|
|
309
|
-
seams
|
|
310
|
-
) {
|
|
311
|
-
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
312
|
-
const previous = ledger.items[ref] ?? placeholderItem();
|
|
313
|
-
const existing = previous.pendingQuestion;
|
|
314
|
-
const askedAt = existing?.text === text ? existing.askedAt : at;
|
|
315
|
-
return withItem(ledger, ref, {
|
|
316
|
-
...previous,
|
|
317
|
-
pendingQuestion: {
|
|
318
|
-
text,
|
|
319
|
-
askedAt,
|
|
320
|
-
lastPingAt: at,
|
|
321
|
-
telegramMessageId: telegramMessageId ?? null,
|
|
322
|
-
},
|
|
323
|
-
history: [...(previous.history ?? []), { event: "question", at }],
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Clear an item's pending question, once its answer has been delivered.
|
|
330
|
-
* @param {string} projectRoot - Absolute project root
|
|
331
|
-
* @param {{ref: string}} target - Item
|
|
332
|
-
* @param {LedgerSeams} [seams] - Injected seams
|
|
333
|
-
* @returns {Promise<LedgerItem>} The updated item
|
|
334
|
-
*/
|
|
335
|
-
export function clearPendingQuestion(projectRoot, { ref }, seams) {
|
|
336
|
-
return updateLedger(projectRoot, seams, (ledger, at) => {
|
|
337
|
-
const previous = requireItem(ledger, ref);
|
|
338
|
-
return withItem(ledger, ref, {
|
|
339
|
-
...previous,
|
|
340
|
-
pendingQuestion: null,
|
|
341
|
-
history: [...(previous.history ?? []), { event: "answered", at }],
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
312
|
/**
|
|
347
313
|
* Record this cycle's hash of the worker's logs. `lastProgressAt` moves only
|
|
348
314
|
* when the hash changed, which is what "no output for N minutes" measures.
|