github-issue-tower-defence-management 1.117.1 → 1.117.3

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.
Files changed (55) hide show
  1. package/.github/workflows/create-pr.yml +17 -2
  2. package/CHANGELOG.md +14 -0
  3. package/README.md +3 -2
  4. package/bin/adapter/entry-points/console/ui-dist/assets/{index-CJJsRF8i.js → index-BXcfEKkX.js} +1 -1
  5. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  6. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +7 -2
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  8. package/bin/adapter/entry-points/handlers/notifySilentTmuxSessions.js +5 -4
  9. package/bin/adapter/entry-points/handlers/notifySilentTmuxSessions.js.map +1 -1
  10. package/bin/adapter/proxy/ClaudeMessageResponseParser.js +5 -1
  11. package/bin/adapter/proxy/ClaudeMessageResponseParser.js.map +1 -1
  12. package/bin/adapter/repositories/GraphqlProjectRepository.js +3 -3
  13. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
  14. package/bin/adapter/repositories/LocalStorageCacheRepository.js +1 -1
  15. package/bin/adapter/repositories/LocalStorageCacheRepository.js.map +1 -1
  16. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js +5 -1
  17. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js.map +1 -1
  18. package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -1
  19. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  20. package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js +2 -1
  21. package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js.map +1 -1
  22. package/bin/domain/usecases/UpdateIssueStatusByLabelUseCase.js +1 -1
  23. package/bin/domain/usecases/UpdateIssueStatusByLabelUseCase.js.map +1 -1
  24. package/eslint.config.mjs +67 -0
  25. package/package.json +8 -7
  26. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.test.ts +12 -21
  27. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.ts +1 -1
  28. package/src/adapter/entry-points/console/ui-dist/assets/{index-CJJsRF8i.js → index-BXcfEKkX.js} +1 -1
  29. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  30. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +6 -0
  31. package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +1 -1
  32. package/src/adapter/entry-points/handlers/machineStatusWriter.test.ts +1 -1
  33. package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.ts +7 -0
  34. package/src/adapter/entry-points/handlers/tokenStatusWriter.test.ts +1 -1
  35. package/src/adapter/proxy/ClaudeMessageResponseParser.ts +3 -2
  36. package/src/adapter/repositories/GraphqlProjectRepository.ts +3 -2
  37. package/src/adapter/repositories/LocalStorageCacheRepository.ts +1 -1
  38. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.test.ts +118 -0
  39. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.ts +4 -0
  40. package/src/domain/usecases/AssignNoAssigneeIssueToManagerUseCase.test.ts +2 -1
  41. package/src/domain/usecases/HandleScheduledEventUseCase.ts +1 -1
  42. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.ts +1 -0
  43. package/src/domain/usecases/UpdateIssueStatusByLabelUseCase.ts +1 -0
  44. package/tsconfig.json +1 -0
  45. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  46. package/types/adapter/entry-points/handlers/notifySilentTmuxSessions.d.ts +2 -0
  47. package/types/adapter/entry-points/handlers/notifySilentTmuxSessions.d.ts.map +1 -1
  48. package/types/adapter/proxy/ClaudeMessageResponseParser.d.ts.map +1 -1
  49. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
  50. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts +2 -1
  51. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts.map +1 -1
  52. package/types/domain/usecases/NotifySilentLiveSessionsUseCase.d.ts +1 -0
  53. package/types/domain/usecases/NotifySilentLiveSessionsUseCase.d.ts.map +1 -1
  54. package/types/domain/usecases/UpdateIssueStatusByLabelUseCase.d.ts.map +1 -1
  55. package/.eslintrc.cjs +0 -59
@@ -73,9 +73,24 @@ jobs:
73
73
  PR_ID=$(echo "$PR_DATA" | jq -r '.node_id')
74
74
  echo "node_id=$PR_ID" >> "$GITHUB_OUTPUT"
75
75
 
76
- - name: Enable Auto Merge for PR
76
+ - name: Check auto-merge capability
77
77
  if: steps.resolve_pr.outputs.pr_number
78
- continue-on-error: true
78
+ id: check_auto_merge
79
+ run: |
80
+ REPO_DATA=$(curl -s \
81
+ -H "Authorization: token ${{ steps.app-token.outputs.token }}" \
82
+ -H "Accept: application/vnd.github.v3+json" \
83
+ "https://api.github.com/repos/${{ github.repository }}")
84
+ ALLOW_AUTO_MERGE=$(echo "$REPO_DATA" | jq -r '.allow_auto_merge')
85
+ echo "allowed=$ALLOW_AUTO_MERGE" >> "$GITHUB_OUTPUT"
86
+ if [ "$ALLOW_AUTO_MERGE" != "true" ]; then
87
+ echo "Repository has allow_auto_merge disabled. Skipping auto-merge enablement."
88
+ fi
89
+ env:
90
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
91
+
92
+ - name: Enable Auto Merge for PR
93
+ if: steps.resolve_pr.outputs.pr_number && steps.check_auto_merge.outputs.allowed == 'true'
79
94
  run: |
80
95
  RESPONSE=$(curl -s -X POST \
81
96
  -H "Authorization: bearer ${{ steps.app-token.outputs.token }}" \
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.117.3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.117.2...v1.117.3) (2026-06-29)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * disable console detail prefetch to stop GraphQL rate-limit exhaustion ([#1102](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1102)) ([b577193](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/b5771933b5a344eec5ed057b03bcf70139e82557))
7
+
8
+ ## [1.117.2](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.117.1...v1.117.2) (2026-06-29)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * exclude long-dead sub-agents from silent-monitor stall flagging ([#1100](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1100)) ([9cfe761](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/9cfe761f77121a4eb5183d86dbc36ec6095fbcfa))
14
+
1
15
  ## [1.117.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.117.0...v1.117.1) (2026-06-29)
2
16
 
3
17
 
package/README.md CHANGED
@@ -292,6 +292,7 @@ subAgentTranscriptRootDirectory?: string # Optional: Projects root directory (fo
292
292
  mainSilentThresholdSeconds?: number # Optional: Seconds of main-session output silence after which the main-session self-check section is sent. Default 600
293
293
  subAgentSilentThresholdSeconds?: number # Optional: Seconds of sub-process output silence after which the sub-process section is sent. Default 300
294
294
  subAgentRunningThresholdSeconds?: number # Optional: Seconds a sub-process may run before the sub-process section is sent regardless of its output silence. Default 900
295
+ subAgentSilentCeilingSeconds?: number # Optional: Upper bound, in seconds, on how long a transcript-discovered sub-agent may have been output-idle and still be considered a notification candidate. A sub-agent whose transcript has been silent strictly longer than this ceiling is treated as dead and excluded, so the section reports only sub-agents that recently went silent rather than long-dead transcripts that linger on disk. Applies only to transcript-based discovery (`subAgentTranscriptRootDirectory`); the process-match discovery already gates on live processes. Default 3600. Limitation: a sub-agent that is genuinely still running but has been idle longer than the ceiling is not reported
295
296
  silentNotificationStaggerSeconds?: number # Optional: Seconds to wait between consecutive session notifications within one cycle, so the targets are notified sequentially rather than all at once. Default 25
296
297
  activeHubTaskStatus?: string # Optional: GitHub Project Status value that marks a session's hub task as still actively worked in an interactive session. For a session whose name is a `https://github.com/{owner}/{repo}/issues/{N}` issue URL, the hub task's latest Status is resolved before sending and the notification is skipped when the issue is closed or its Status differs from this value. Sessions whose name is not a github.com issue URL are never checked. When the hub task Status cannot be resolved (transient API error or the issue is not found), the notification is sent anyway (fail-open) and a warning is logged. When unset, this hub-task active-status check is a no-op and existing behavior is preserved
297
298
  silentSubAgentMessageHeader?: string # Optional: Overrides the line shown above the sub-process list in the sub-process section. When unset, a generic built-in line is used
@@ -559,11 +560,11 @@ Candidate sessions are first selected from the live process tree: every live tmu
559
560
 
560
561
  The main-session stalled section is sent when the session's main output has been idle for at least `mainSilentThresholdSeconds`, unless the session is currently waiting on the owner (in that case the silence is expected and the section is suppressed). Idle time is computed from the timestamp of the latest entry of any kind in the session's resolved transcript rather than from the transcript file modification time, so a session that keeps appending tool results, owner replies, or any other entry type while emitting no assistant text still counts as active and is not mistaken for a silent one. Whether a session is waiting on the owner is determined through an injectable port; the built-in default reports no session as waiting, so the suppression is only applied when a host provides an implementation. When `ownerCallMarker` is configured, a transcript-based implementation is used: it reads each session's resolved transcript and treats the session as waiting on the owner when the latest entry containing `ownerCallMarker` is newer (by full timestamp) than the latest genuine owner reply. A self-check reminder that the monitor injects into a session via `tmux send-keys` itself lands in that session's transcript as a `user` text entry; every injected reminder carries a fixed sentinel tag (`[TDPM_SILENT_SESSION_SELF_CHECK_REMINDER]`), and a `user` entry whose text contains that sentinel is not counted as a genuine owner reply. This prevents the monitor's own reminder from being mistaken for the owner answering, which would otherwise make a genuinely waiting session stop being suppressed. The stalled section's owner-call self-check point also instructs the agent on the required owner-call notification format: the owner-call must be emitted as the configured owner-call marker tag (interpolated from `ownerCallMarker` when set) as a complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag, and the content between the markers must begin with the 🔴 emoji immediately, because the owner's app only surfaces the notification together with its content when the exact, well-formed tag with the leading 🔴 is present and a malformed tag results in only a red indicator with no readable content. The same self-check point also tells the agent when to fire the owner-call: if the agent has completed or answered a request from the owner in this session, it must fire the owner-call to report the result to the owner, because completing or answering an owner's requested action is itself a reason to fire the owner-call. Completing or answering an owner request without firing the owner-call means the owner is never notified — the owner's app only surfaces the session when the owner-call fires — so the task silently stalls; the point states the causal link explicitly, noting that if the self-check reminder keeps arriving it is likely because an owner request was completed or answered without firing the owner-call, so the agent should fire the owner-call to report the result to the owner.
561
562
 
562
- The sub-process section is sent, regardless of main output, when at least one sub-process of the session has been output-idle for `subAgentSilentThresholdSeconds` or has been running for `subAgentRunningThresholdSeconds`; the message lists each matched sub-process with its idle and running minutes. Sub-processes are discovered in one of two ways: when `subAgentTranscriptRootDirectory` is configured, each session's `subagents/agent-<id>.jsonl` transcripts are scanned. The sub-agent directory is the `subagents/` directory that sits next to the session's already-resolved main-session transcript file under `projects/<cwd-slug>/<sessionId>/subagents/`, derived by stripping the `.jsonl` suffix from the main-session transcript path and appending `subagents`; this on-disk path is keyed by the session's working-directory slug and session id, not by the tmux session name. Finished sub-agents (latest transcript entry `stop_reason` equal to `end_turn` or `stop_sequence`) are skipped, and idle time is taken from the transcript file modification time (following symlinks) while running time is taken from its first entry timestamp; otherwise sub-processes are discovered by matching `subAgentProcessMatchPattern` against process command lines.
563
+ The sub-process section is sent, regardless of main output, when at least one sub-process of the session has been output-idle for `subAgentSilentThresholdSeconds` or has been running for `subAgentRunningThresholdSeconds`; the message lists each matched sub-process with its idle and running minutes. Sub-processes are discovered in one of two ways: when `subAgentTranscriptRootDirectory` is configured, each session's `subagents/agent-<id>.jsonl` transcripts are scanned. The sub-agent directory is the `subagents/` directory that sits next to the session's already-resolved main-session transcript file under `projects/<cwd-slug>/<sessionId>/subagents/`, derived by stripping the `.jsonl` suffix from the main-session transcript path and appending `subagents`; this on-disk path is keyed by the session's working-directory slug and session id, not by the tmux session name. Finished sub-agents (latest transcript entry `stop_reason` equal to `end_turn` or `stop_sequence`) are skipped, and idle time is taken from the transcript file modification time (following symlinks) while running time is taken from its first entry timestamp. A sub-agent that died without writing a clean `stop_reason` (killed, crashed, or token-exhausted) leaves its transcript behind under the session's `subagents/` directory, and because sub-agents run in-process inside the parent session rather than as separate operating-system processes, no process-liveness signal can be matched back to such a transcript. To keep these long-dead transcripts from being reported forever, a sub-agent whose transcript has been output-idle strictly longer than `subAgentSilentCeilingSeconds` is treated as dead and excluded, so the section reports only sub-agents that recently went silent. The limitation of this recency upper bound is that a sub-agent that is genuinely still running but has been idle longer than the ceiling is not reported. Otherwise sub-processes are discovered by matching `subAgentProcessMatchPattern` against process command lines.
563
564
 
564
565
  There is no per-session notification cooldown: every cycle, a session is notified whenever it still meets the silent-target condition (output silent at or beyond the threshold and not waiting on the owner). No suppression state is persisted. Because silence is measured from the latest transcript entry of any type — including the monitor's own injected reminder and the owner's reply — a notified session's measured silence resets as soon as it produces any activity, so a session that has resumed is not re-flagged; this already prevents redundant nudges without a cooldown. When more than one session is notified in the same cycle, the sends are spaced out sequentially with `silentNotificationStaggerSeconds` between consecutive sends (no wait before the first or after the last) so the targets are not all triggered at once. When `activeHubTaskStatus` is configured, each notification is gated on the latest GitHub Project Status of the session's hub task: a session whose name identifies a github.com issue or pull request — accepted both as a clean `https://github.com/{owner}/{repo}/issues/{N}` URL and as the real tmux session-name form `https_//github_com/{owner}/{repo}/issues/{N}` produced by replacing `.` and `:` with `_` (the `pull` path is accepted in both forms too) — is notified only while that hub task is open and in the configured active Status, so a session whose hub task has been closed or moved to another Status is skipped; sessions whose name does not identify a github.com issue or pull request are never gated, and a hub task whose Status cannot be resolved fails open (the notification is sent and a warning is logged). When `activeHubTaskStatus` is unset, this hub-task check is a no-op. Process-snapshot collection, transcript resolution, owner-call detection, the wait between sends, and the message wording are all performed through injectable ports, so the logic is unit-testable without touching the host, and the host-specific process and environment access, sub-process pattern, and message wording are supplied through adapters or configuration. When `silentNotificationEnabled` is not true the step is a no-op, and any error during the step is logged and swallowed so the schedule cycle is never affected.
565
566
 
566
- Each config key above has a matching environment variable read when the config key is unset: `TDPM_SILENT_NOTIFICATION_ENABLED` (the string `true` enables the step), `TDPM_SILENT_OWNER_CALL_MARKER`, `TDPM_SUBAGENT_OUTPUT_ROOT_DIRECTORY`, `TDPM_SUBAGENT_PROCESS_MATCH_PATTERN`, `TDPM_SUBAGENT_TRANSCRIPT_ROOT_DIRECTORY`, `TDPM_MAIN_SILENT_THRESHOLD_SECONDS`, `TDPM_SUBAGENT_SILENT_THRESHOLD_SECONDS`, `TDPM_SUBAGENT_RUNNING_THRESHOLD_SECONDS`, `TDPM_SILENT_NOTIFICATION_STAGGER_SECONDS`, `TDPM_ACTIVE_HUB_TASK_STATUS`, `TDPM_SILENT_MAIN_STALLED_MESSAGE`, `TDPM_SILENT_SUBAGENT_MESSAGE_HEADER`, and `TDPM_SILENT_SUBAGENT_MESSAGE_FOOTER`.
567
+ Each config key above has a matching environment variable read when the config key is unset: `TDPM_SILENT_NOTIFICATION_ENABLED` (the string `true` enables the step), `TDPM_SILENT_OWNER_CALL_MARKER`, `TDPM_SUBAGENT_OUTPUT_ROOT_DIRECTORY`, `TDPM_SUBAGENT_PROCESS_MATCH_PATTERN`, `TDPM_SUBAGENT_TRANSCRIPT_ROOT_DIRECTORY`, `TDPM_MAIN_SILENT_THRESHOLD_SECONDS`, `TDPM_SUBAGENT_SILENT_THRESHOLD_SECONDS`, `TDPM_SUBAGENT_RUNNING_THRESHOLD_SECONDS`, `TDPM_SUBAGENT_SILENT_CEILING_SECONDS`, `TDPM_SILENT_NOTIFICATION_STAGGER_SECONDS`, `TDPM_ACTIVE_HUB_TASK_STATUS`, `TDPM_SILENT_MAIN_STALLED_MESSAGE`, `TDPM_SILENT_SUBAGENT_MESSAGE_HEADER`, and `TDPM_SILENT_SUBAGENT_MESSAGE_FOOTER`.
567
568
 
568
569
  ## Token Rotation Order File
569
570