panopticon-cli 0.4.33 → 0.5.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.
Files changed (52) hide show
  1. package/README.md +96 -210
  2. package/dist/{agents-VLK4BMVA.js → agents-E43Y3HNU.js} +5 -5
  3. package/dist/{chunk-ASY7T35E.js → chunk-AAFQANKW.js} +231 -76
  4. package/dist/chunk-AAFQANKW.js.map +1 -0
  5. package/dist/{chunk-KJ2TRXNK.js → chunk-FTCPTHIJ.js} +47 -420
  6. package/dist/chunk-FTCPTHIJ.js.map +1 -0
  7. package/dist/{chunk-PI7Y3PSN.js → chunk-GR6ZZMCX.js} +25 -6
  8. package/dist/chunk-GR6ZZMCX.js.map +1 -0
  9. package/dist/chunk-HJSM6E6U.js +1038 -0
  10. package/dist/chunk-HJSM6E6U.js.map +1 -0
  11. package/dist/{chunk-BKCWRMUX.js → chunk-HZT2AOPN.js} +81 -9
  12. package/dist/chunk-HZT2AOPN.js.map +1 -0
  13. package/dist/{chunk-XFR2DLMR.js → chunk-NTO3EDB3.js} +3 -3
  14. package/dist/{chunk-XFR2DLMR.js.map → chunk-NTO3EDB3.js.map} +1 -1
  15. package/dist/{chunk-RBUO57TC.js → chunk-PPRFKTVC.js} +2 -2
  16. package/dist/chunk-PPRFKTVC.js.map +1 -0
  17. package/dist/{chunk-XKT5MHPT.js → chunk-WQG2TYCB.js} +2 -2
  18. package/dist/cli/index.js +1383 -880
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/dashboard/prompts/work-agent.md +2 -0
  21. package/dist/dashboard/public/assets/{index-UjZq6ykz.css → index-BxpjweAL.css} +1 -1
  22. package/dist/dashboard/public/assets/index-DQHkwvvJ.js +743 -0
  23. package/dist/dashboard/public/index.html +2 -2
  24. package/dist/dashboard/server.js +3593 -2052
  25. package/dist/index.d.ts +10 -1
  26. package/dist/index.js +5 -3
  27. package/dist/index.js.map +1 -1
  28. package/dist/{specialist-context-T3NBMCIE.js → specialist-context-ZC6A4M3I.js} +4 -4
  29. package/dist/{specialist-logs-CVKD3YJ3.js → specialist-logs-KLGJCEUL.js} +4 -4
  30. package/dist/{specialists-TKAP6T6Z.js → specialists-O4HWDJL5.js} +4 -4
  31. package/dist/{traefik-QX4ZV4YG.js → traefik-QN7R5I6V.js} +2 -2
  32. package/dist/{workspace-manager-KLHUCIZV.js → workspace-manager-IE4JL2JP.js} +2 -2
  33. package/package.json +1 -1
  34. package/scripts/stop-hook +7 -0
  35. package/scripts/work-agent-stop-hook +137 -0
  36. package/skills/myn-standards/SKILL.md +351 -0
  37. package/skills/write-spec/SKILL.md +138 -0
  38. package/dist/chunk-7XNJJBH6.js +0 -538
  39. package/dist/chunk-7XNJJBH6.js.map +0 -1
  40. package/dist/chunk-ASY7T35E.js.map +0 -1
  41. package/dist/chunk-BKCWRMUX.js.map +0 -1
  42. package/dist/chunk-KJ2TRXNK.js.map +0 -1
  43. package/dist/chunk-PI7Y3PSN.js.map +0 -1
  44. package/dist/chunk-RBUO57TC.js.map +0 -1
  45. package/dist/dashboard/public/assets/index-kAJqtLDO.js +0 -708
  46. /package/dist/{agents-VLK4BMVA.js.map → agents-E43Y3HNU.js.map} +0 -0
  47. /package/dist/{chunk-XKT5MHPT.js.map → chunk-WQG2TYCB.js.map} +0 -0
  48. /package/dist/{specialist-context-T3NBMCIE.js.map → specialist-context-ZC6A4M3I.js.map} +0 -0
  49. /package/dist/{specialist-logs-CVKD3YJ3.js.map → specialist-logs-KLGJCEUL.js.map} +0 -0
  50. /package/dist/{specialists-TKAP6T6Z.js.map → specialists-O4HWDJL5.js.map} +0 -0
  51. /package/dist/{traefik-QX4ZV4YG.js.map → traefik-QN7R5I6V.js.map} +0 -0
  52. /package/dist/{workspace-manager-KLHUCIZV.js.map → workspace-manager-IE4JL2JP.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -829,5 +829,14 @@ declare function getProviderEnv(provider: ProviderConfig, apiKey: string): Recor
829
829
  * Must be called before spawning the agent.
830
830
  */
831
831
  declare function setupCredentialFileAuth(provider: ProviderConfig, workspacePath: string): void;
832
+ /**
833
+ * Clear credential-file auth from workspace settings.
834
+ *
835
+ * When switching from a credential-file provider (e.g. Kimi) to a static/plan-based
836
+ * provider (e.g. Anthropic), the apiKeyHelper must be removed from
837
+ * .claude/settings.local.json. Otherwise Claude Code will keep using the stale
838
+ * token helper and fail with "Invalid API key".
839
+ */
840
+ declare function clearCredentialFileAuth(workspacePath: string): void;
832
841
 
833
- export { AGENTS_DIR, ARCHIVES_DIR, type AnthropicModel, type ApiKeysConfig, BACKUPS_DIR, BIN_DIR, type BackupInfo, CACHE_AGENTS_DIR, CACHE_MANIFEST, CACHE_RULES_DIR, CACHE_SKILLS_DIR, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, type Comment, type ComplexityLevel, type ComplexityModels, DOCS_DIR, type DevrootSyncItem, type GitHubConfig, GitHubTracker, type GitLabConfig, GitLabTracker, type GoogleModel, HEARTBEATS_DIR, type HookItem, INIT_DIRS, type Issue, type IssueFilters, IssueNotFoundError, type IssueState, type IssueTracker, type IssueUpdate, type KimiModel, LEGACY_RUNTIME_DIRS, type LinearConfig, LinearTracker, type LinkDirection, LinkManager, type MigrationResult, type ModelId, type ModelsConfig, type NewIssue, NotImplementedError, type OpenAIModel, PANOPTICON_HOME, PRDS_DIR, PRD_DRAFTS_DIR, PRD_PUBLISHED_DIR, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, PROJECT_PRDS_COMPLETED_SUBDIR, PROJECT_PRDS_PLANNED_SUBDIR, PROJECT_PRDS_SUBDIR, PROVIDERS, type PanopticonConfig, type ProviderAuthType, type ProviderCompatibility, type ProviderConfig, type ProviderName, type RallyConfig, type RefreshCacheResult, type RemoteConfig, type RemoteExeConfig, SETTINGS_FILE, SKILLS_DIR, SOURCE_AGENTS_DIR, SOURCE_DEV_SKILLS_DIR, SOURCE_RULES_DIR, SOURCE_SCRIPTS_DIR, SOURCE_SKILLS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGET, type SettingsConfig, type ShadowConfig, type Shell, type SpecialistModels, type SyncItem, type SyncOptions, type SyncPlan, type SyncResult, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, type TrackerConfig, type TrackerConfigItem, type TrackerLink, type TrackerType, type TrackersConfig, type ZAIModel, addAlias, cleanOldBackups, createBackup, createBackupTimestamp, createTracker, createTrackerFromConfig, detectShell, executeSync, findDevrootForProject, formatIssueRef, getAgentCommand, getAliasInstructions, getAllTrackers, getAvailableModels, getClaudeModelFlag, getDashboardApiUrl, getDefaultConfig, getDefaultSettings, getDevrootPath, getDirectProviders, getLinkManager, getPanopticonHome, getPrimaryTracker, getProviderEnv, getProviderForModel, getRouterProviders, getSecondaryTracker, getShellRcFile, hasAlias, isAnthropicModel, isDevMode, isPanopticonSymlink, listBackups, loadConfig, loadSettings, migrateFromPersonalSymlinks, needsRouter, parseIssueRef, planHooksSync, planSync, refreshCache, requiresRouter, restoreBackup, saveConfig, saveSettings, setupCredentialFileAuth, syncHooks, syncStatusline, validateSettings };
842
+ export { AGENTS_DIR, ARCHIVES_DIR, type AnthropicModel, type ApiKeysConfig, BACKUPS_DIR, BIN_DIR, type BackupInfo, CACHE_AGENTS_DIR, CACHE_MANIFEST, CACHE_RULES_DIR, CACHE_SKILLS_DIR, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, type Comment, type ComplexityLevel, type ComplexityModels, DOCS_DIR, type DevrootSyncItem, type GitHubConfig, GitHubTracker, type GitLabConfig, GitLabTracker, type GoogleModel, HEARTBEATS_DIR, type HookItem, INIT_DIRS, type Issue, type IssueFilters, IssueNotFoundError, type IssueState, type IssueTracker, type IssueUpdate, type KimiModel, LEGACY_RUNTIME_DIRS, type LinearConfig, LinearTracker, type LinkDirection, LinkManager, type MigrationResult, type ModelId, type ModelsConfig, type NewIssue, NotImplementedError, type OpenAIModel, PANOPTICON_HOME, PRDS_DIR, PRD_DRAFTS_DIR, PRD_PUBLISHED_DIR, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, PROJECT_PRDS_COMPLETED_SUBDIR, PROJECT_PRDS_PLANNED_SUBDIR, PROJECT_PRDS_SUBDIR, PROVIDERS, type PanopticonConfig, type ProviderAuthType, type ProviderCompatibility, type ProviderConfig, type ProviderName, type RallyConfig, type RefreshCacheResult, type RemoteConfig, type RemoteExeConfig, SETTINGS_FILE, SKILLS_DIR, SOURCE_AGENTS_DIR, SOURCE_DEV_SKILLS_DIR, SOURCE_RULES_DIR, SOURCE_SCRIPTS_DIR, SOURCE_SKILLS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGET, type SettingsConfig, type ShadowConfig, type Shell, type SpecialistModels, type SyncItem, type SyncOptions, type SyncPlan, type SyncResult, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, type TrackerConfig, type TrackerConfigItem, type TrackerLink, type TrackerType, type TrackersConfig, type ZAIModel, addAlias, cleanOldBackups, clearCredentialFileAuth, createBackup, createBackupTimestamp, createTracker, createTrackerFromConfig, detectShell, executeSync, findDevrootForProject, formatIssueRef, getAgentCommand, getAliasInstructions, getAllTrackers, getAvailableModels, getClaudeModelFlag, getDashboardApiUrl, getDefaultConfig, getDefaultSettings, getDevrootPath, getDirectProviders, getLinkManager, getPanopticonHome, getPrimaryTracker, getProviderEnv, getProviderForModel, getRouterProviders, getSecondaryTracker, getShellRcFile, hasAlias, isAnthropicModel, isDevMode, isPanopticonSymlink, listBackups, loadConfig, loadSettings, migrateFromPersonalSymlinks, needsRouter, parseIssueRef, planHooksSync, planSync, refreshCache, requiresRouter, restoreBackup, saveConfig, saveSettings, setupCredentialFileAuth, syncHooks, syncStatusline, validateSettings };
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  restoreBackup,
22
22
  syncHooks,
23
23
  syncStatusline
24
- } from "./chunk-XKT5MHPT.js";
24
+ } from "./chunk-WQG2TYCB.js";
25
25
  import "./chunk-AQXETQHW.js";
26
26
  import {
27
27
  GitHubTracker,
@@ -32,9 +32,10 @@ import {
32
32
  getAllTrackers,
33
33
  getPrimaryTracker,
34
34
  getSecondaryTracker
35
- } from "./chunk-XFR2DLMR.js";
35
+ } from "./chunk-NTO3EDB3.js";
36
36
  import {
37
37
  PROVIDERS,
38
+ clearCredentialFileAuth,
38
39
  getAgentCommand,
39
40
  getAvailableModels,
40
41
  getClaudeModelFlag,
@@ -52,7 +53,7 @@ import {
52
53
  saveSettings,
53
54
  setupCredentialFileAuth,
54
55
  validateSettings
55
- } from "./chunk-7XNJJBH6.js";
56
+ } from "./chunk-HJSM6E6U.js";
56
57
  import {
57
58
  findDevrootForProject,
58
59
  getDashboardApiUrl,
@@ -177,6 +178,7 @@ export {
177
178
  TrackerAuthError,
178
179
  addAlias,
179
180
  cleanOldBackups,
181
+ clearCredentialFileAuth,
180
182
  createBackup,
181
183
  createBackupTimestamp,
182
184
  createTracker,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Panopticon CLI - Main exports for library usage\nexport * from './lib/paths.js';\nexport * from './lib/config.js';\nexport * from './lib/shell.js';\nexport * from './lib/backup.js';\nexport * from './lib/sync.js';\nexport * from './lib/tracker/index.js';\nexport * from './lib/providers.js';\nexport * from './lib/settings.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAKA;AACA;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Panopticon CLI - Main exports for library usage\nexport * from './lib/paths.js';\nexport * from './lib/config.js';\nexport * from './lib/shell.js';\nexport * from './lib/backup.js';\nexport * from './lib/sync.js';\nexport * from './lib/tracker/index.js';\nexport * from './lib/providers.js';\nexport * from './lib/settings.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAKA;AACA;","names":[]}
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getRecentRunLogs,
3
3
  init_specialist_logs
4
- } from "./chunk-ASY7T35E.js";
4
+ } from "./chunk-AAFQANKW.js";
5
5
  import {
6
6
  getModelId,
7
7
  init_work_type_router
8
- } from "./chunk-KJ2TRXNK.js";
8
+ } from "./chunk-FTCPTHIJ.js";
9
9
  import "./chunk-JQBV3Q2W.js";
10
- import "./chunk-7XNJJBH6.js";
10
+ import "./chunk-HJSM6E6U.js";
11
11
  import {
12
12
  getProject,
13
13
  init_projects
@@ -254,4 +254,4 @@ export {
254
254
  regenerateContextDigest,
255
255
  scheduleDigestGeneration
256
256
  };
257
- //# sourceMappingURL=specialist-context-T3NBMCIE.js.map
257
+ //# sourceMappingURL=specialist-context-ZC6A4M3I.js.map
@@ -16,10 +16,10 @@ import {
16
16
  isRunLogActive,
17
17
  listRunLogs,
18
18
  parseLogMetadata
19
- } from "./chunk-ASY7T35E.js";
20
- import "./chunk-KJ2TRXNK.js";
19
+ } from "./chunk-AAFQANKW.js";
20
+ import "./chunk-FTCPTHIJ.js";
21
21
  import "./chunk-JQBV3Q2W.js";
22
- import "./chunk-7XNJJBH6.js";
22
+ import "./chunk-HJSM6E6U.js";
23
23
  import "./chunk-OMNXYPXC.js";
24
24
  import "./chunk-ZTFNYOC7.js";
25
25
  import "./chunk-ZHC57RCV.js";
@@ -42,4 +42,4 @@ export {
42
42
  listRunLogs,
43
43
  parseLogMetadata
44
44
  };
45
- //# sourceMappingURL=specialist-logs-CVKD3YJ3.js.map
45
+ //# sourceMappingURL=specialist-logs-KLGJCEUL.js.map
@@ -55,10 +55,10 @@ import {
55
55
  wakeSpecialist,
56
56
  wakeSpecialistOrQueue,
57
57
  wakeSpecialistWithTask
58
- } from "./chunk-ASY7T35E.js";
59
- import "./chunk-KJ2TRXNK.js";
58
+ } from "./chunk-AAFQANKW.js";
59
+ import "./chunk-FTCPTHIJ.js";
60
60
  import "./chunk-JQBV3Q2W.js";
61
- import "./chunk-7XNJJBH6.js";
61
+ import "./chunk-HJSM6E6U.js";
62
62
  import "./chunk-OMNXYPXC.js";
63
63
  import "./chunk-ZTFNYOC7.js";
64
64
  import "./chunk-ZHC57RCV.js";
@@ -120,4 +120,4 @@ export {
120
120
  wakeSpecialistOrQueue,
121
121
  wakeSpecialistWithTask
122
122
  };
123
- //# sourceMappingURL=specialists-TKAP6T6Z.js.map
123
+ //# sourceMappingURL=specialists-O4HWDJL5.js.map
@@ -4,7 +4,7 @@ import {
4
4
  ensureProjectCerts,
5
5
  generatePanopticonTraefikConfig,
6
6
  generateTlsConfig
7
- } from "./chunk-RBUO57TC.js";
7
+ } from "./chunk-PPRFKTVC.js";
8
8
  import "./chunk-FQ66DECN.js";
9
9
  import "./chunk-OMNXYPXC.js";
10
10
  import "./chunk-ZTFNYOC7.js";
@@ -16,4 +16,4 @@ export {
16
16
  generatePanopticonTraefikConfig,
17
17
  generateTlsConfig
18
18
  };
19
- //# sourceMappingURL=traefik-QX4ZV4YG.js.map
19
+ //# sourceMappingURL=traefik-QN7R5I6V.js.map
@@ -4,7 +4,7 @@ import {
4
4
  preTrustDirectory,
5
5
  removeWorkspace,
6
6
  stopWorkspaceDocker
7
- } from "./chunk-PI7Y3PSN.js";
7
+ } from "./chunk-GR6ZZMCX.js";
8
8
  import "./chunk-7SN4L4PH.js";
9
9
  import "./chunk-AQXETQHW.js";
10
10
  import "./chunk-ZTFNYOC7.js";
@@ -19,4 +19,4 @@ export {
19
19
  removeWorkspace,
20
20
  stopWorkspaceDocker
21
21
  };
22
- //# sourceMappingURL=workspace-manager-KLHUCIZV.js.map
22
+ //# sourceMappingURL=workspace-manager-IE4JL2JP.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panopticon-cli",
3
- "version": "0.4.33",
3
+ "version": "0.5.0",
4
4
  "description": "Multi-agent orchestration for AI coding assistants (Claude Code, Codex, Cursor, Gemini CLI)",
5
5
  "keywords": [
6
6
  "ai-agents",
package/scripts/stop-hook CHANGED
@@ -57,5 +57,12 @@ if [ -x "$SPECIALIST_HOOK" ]; then
57
57
  "$SPECIALIST_HOOK" &
58
58
  fi
59
59
 
60
+ # Chain to work-agent completion detection hook
61
+ # Detects when a work agent forgot to call "pan work done" and nudges it
62
+ WORK_AGENT_HOOK="$HOME/.panopticon/bin/work-agent-stop-hook"
63
+ if [ -x "$WORK_AGENT_HOOK" ]; then
64
+ "$WORK_AGENT_HOOK" &
65
+ fi
66
+
60
67
  # Always exit successfully
61
68
  exit 0
@@ -0,0 +1,137 @@
1
+ #!/bin/bash
2
+ # ~/.panopticon/bin/work-agent-stop-hook
3
+ # Called when any agent goes idle — detects work agents that forgot "pan work done"
4
+ #
5
+ # Uses a lightweight AI model to analyze the last N lines of terminal output
6
+ # and determine if the agent completed its work but failed to signal completion.
7
+ # If so, sends a nudge message to the agent via tmux.
8
+ #
9
+ # The model used is configurable via PANOPTICON_COMPLETION_CHECK_MODEL env var
10
+ # or defaults to the models.overrides.completion-check-hook setting in config.yaml,
11
+ # falling back to claude-haiku-4-5.
12
+
13
+ # Don't use set -e - resilient to failures, never break Claude Code execution
14
+
15
+ # Get agent ID
16
+ if [ -n "$PANOPTICON_AGENT_ID" ]; then
17
+ AGENT_ID="$PANOPTICON_AGENT_ID"
18
+ elif [ -n "$TMUX" ]; then
19
+ AGENT_ID=$(tmux display-message -p '#S' 2>/dev/null)
20
+ else
21
+ exit 0
22
+ fi
23
+
24
+ # Only run for work agents (agent-min-XXX, agent-pan-XXX, etc.)
25
+ case "$AGENT_ID" in
26
+ agent-*)
27
+ # Check it's not a specialist
28
+ case "$AGENT_ID" in
29
+ specialist-*) exit 0 ;;
30
+ esac
31
+ ;;
32
+ *)
33
+ exit 0 # Not a work agent
34
+ ;;
35
+ esac
36
+
37
+ # Extract issue ID from agent ID (e.g., "agent-min-725" -> "MIN-725")
38
+ ISSUE_ID=$(echo "$AGENT_ID" | sed 's/^agent-//' | tr '[:lower:]' '[:upper:]')
39
+
40
+ # Skip if completion marker already exists (agent already called pan work done)
41
+ COMPLETED_FILE="$HOME/.panopticon/agents/$AGENT_ID/completed"
42
+ if [ -f "$COMPLETED_FILE" ]; then
43
+ exit 0
44
+ fi
45
+
46
+ # Cooldown: don't nudge more than once per 10 minutes
47
+ NUDGE_FILE="$HOME/.panopticon/agents/$AGENT_ID/.last-completion-nudge"
48
+ if [ -f "$NUDGE_FILE" ]; then
49
+ LAST_NUDGE=$(cat "$NUDGE_FILE" 2>/dev/null || echo "0")
50
+ NOW=$(date +%s)
51
+ ELAPSED=$(( NOW - LAST_NUDGE ))
52
+ if [ "$ELAPSED" -lt 600 ]; then
53
+ exit 0 # Too soon since last nudge
54
+ fi
55
+ fi
56
+
57
+ # Capture the last 80 lines of terminal output
58
+ OUTPUT=$(tmux capture-pane -t "$AGENT_ID" -p -S -80 2>/dev/null || echo "")
59
+ if [ -z "$OUTPUT" ]; then
60
+ exit 0
61
+ fi
62
+
63
+ # Quick heuristic pre-check: skip the expensive AI call if the output clearly
64
+ # shows the agent is mid-work (e.g., running tests, editing files, reading)
65
+ if echo "$OUTPUT" | grep -qE '(Reading|Editing|Searching|Running|Compiling|Building|Installing|●.*Bash|●.*Read|●.*Edit|●.*Grep|●.*Write|●.*Glob)' | tail -5 | grep -qE '●'; then
66
+ exit 0
67
+ fi
68
+
69
+ # Check if the agent appears to be at an idle prompt (not mid-response)
70
+ if ! echo "$OUTPUT" | tail -10 | grep -qE '(^❯|Worked for)'; then
71
+ exit 0 # Agent doesn't appear to be at an idle prompt
72
+ fi
73
+
74
+ # Determine model to use for completion check
75
+ # Priority: env var > config.yaml override > default
76
+ COMPLETION_MODEL="${PANOPTICON_COMPLETION_CHECK_MODEL:-}"
77
+ if [ -z "$COMPLETION_MODEL" ]; then
78
+ CONFIG_FILE="$HOME/.panopticon/config.yaml"
79
+ if [ -f "$CONFIG_FILE" ] && command -v grep &> /dev/null; then
80
+ COMPLETION_MODEL=$(grep 'completion-check-hook:' "$CONFIG_FILE" 2>/dev/null | awk '{print $2}' | tr -d '"' || echo "")
81
+ fi
82
+ fi
83
+ COMPLETION_MODEL="${COMPLETION_MODEL:-claude-haiku-4-5}"
84
+
85
+ # Build the analysis prompt
86
+ ANALYSIS_PROMPT="You are analyzing a work agent's terminal output to determine if it finished its work but forgot to call 'pan work done'.
87
+
88
+ The agent was working on issue $ISSUE_ID. Here is the last 80 lines of its terminal output:
89
+
90
+ <terminal_output>
91
+ $OUTPUT
92
+ </terminal_output>
93
+
94
+ Respond with EXACTLY one of these words (nothing else):
95
+ - FORGOT_COMPLETION — if the agent clearly finished its implementation work (closed beads, committed code, ran tests) but stopped without calling 'pan work done'
96
+ - STILL_WORKING — if the agent appears to have more work to do (mentioned next steps, was mid-task)
97
+ - STOPPED_FOR_INPUT — if the agent stopped because it needs human input or hit a blocker
98
+ - UNCLEAR — if you cannot determine the state"
99
+
100
+ # Run the analysis using claude CLI (headless, no interactive session)
101
+ RESULT=$(echo "$ANALYSIS_PROMPT" | claude -p --model "$COMPLETION_MODEL" --max-tokens 20 2>/dev/null || echo "UNCLEAR")
102
+
103
+ # Extract just the verdict (first word of output, strip whitespace)
104
+ VERDICT=$(echo "$RESULT" | tr -d '[:space:]' | head -c 30)
105
+
106
+ # Log the check
107
+ LOG_DIR="$HOME/.panopticon/logs"
108
+ mkdir -p "$LOG_DIR"
109
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID ($ISSUE_ID) -> $VERDICT (model: $COMPLETION_MODEL)" \
110
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
111
+
112
+ if [ "$VERDICT" = "FORGOT_COMPLETION" ]; then
113
+ # Record nudge timestamp for cooldown
114
+ mkdir -p "$(dirname "$NUDGE_FILE")"
115
+ date +%s > "$NUDGE_FILE" 2>/dev/null || true
116
+
117
+ # Write the nudge message to a temp file and use load-buffer + paste-buffer
118
+ # (the reliable tmux message delivery pattern from CLAUDE.md)
119
+ NUDGE_MSG="You stopped without calling pan work done. If your implementation is complete, you MUST run this command now:
120
+
121
+ pan work done $ISSUE_ID -c \"Implementation complete\"
122
+
123
+ If you still have remaining tasks, continue working on them. Do NOT stop until all work is done AND you have called pan work done."
124
+
125
+ TMPFILE=$(mktemp)
126
+ echo "$NUDGE_MSG" > "$TMPFILE"
127
+ tmux load-buffer "$TMPFILE" 2>/dev/null
128
+ tmux paste-buffer -t "$AGENT_ID" 2>/dev/null
129
+ sleep 0.3
130
+ tmux send-keys -t "$AGENT_ID" C-m 2>/dev/null
131
+ rm -f "$TMPFILE"
132
+
133
+ echo "[$(date -Iseconds)] work-agent-stop-hook: Sent completion nudge to $AGENT_ID" \
134
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
135
+ fi
136
+
137
+ exit 0
@@ -0,0 +1,351 @@
1
+ ---
2
+ name: myn-standards
3
+ description: >
4
+ Mind Your Now coding standards, design system, and component patterns.
5
+ Auto-applied when writing or reviewing MYN code.
6
+ triggers:
7
+ - myn component
8
+ - mind your now
9
+ - myn styling
10
+ - myn design
11
+ - myn frontend
12
+ - myn ui
13
+ - notification toast
14
+ - task card
15
+ - briefing
16
+ ---
17
+
18
+ # Mind Your Now Design System & Coding Standards
19
+
20
+ ## Brand Identity
21
+
22
+ ### Brand Colors
23
+
24
+ | Name | Hex | Tailwind Token | Usage |
25
+ |------|-----|----------------|-------|
26
+ | All-Knowing Blu | `#00AEEF` | `brand-blue` | Primary brand, links, CTAs |
27
+ | Yours Truly Blu | `#80D7F7` | `brand-blue-light` | Hover states, light accents |
28
+ | Golden Hour Yellow | `#FFC60B` | `brand-yellow` | Accent, highlights, "now" in wordmark |
29
+ | Midnight Blue | `#0C4064` | `brand-dark` | Headings on light backgrounds |
30
+
31
+ ### Brand Wordmark
32
+
33
+ ```tsx
34
+ <h1>
35
+ <span className="text-blue-800">mind</span>
36
+ <span className="font-thin text-blue-200">your</span>
37
+ <span className="text-yellow-500">now</span>
38
+ </h1>
39
+ ```
40
+
41
+ ### Logo
42
+
43
+ - Asset: `/images/logo-no-text.png` (sun-burst motif)
44
+ - Always paired with the wordmark on splash/auth screens
45
+
46
+ ## Color System
47
+
48
+ ### Semantic Colors
49
+
50
+ | Token | Light | Dark | Usage |
51
+ |-------|-------|------|-------|
52
+ | `semantic-success` | `#22C55E` | `#4ADE80` | Completed, positive |
53
+ | `semantic-warning` | `#F59E0B` | `#FBBF24` | Attention needed |
54
+ | `semantic-error` | `#EF4444` | `#F87171` | Errors, overdue |
55
+ | `semantic-info` | `#3B82F6` | `#60A5FA` | Informational |
56
+
57
+ ### Priority Colors
58
+
59
+ | Priority | Hex | Token |
60
+ |----------|-----|-------|
61
+ | Critical | `#EF4444` | `priority-critical` |
62
+ | High | `#F97316` | `priority-high` |
63
+ | Medium | `#EAB308` | `priority-medium` |
64
+ | Low | `#22C55E` | `priority-low` |
65
+ | None | `#6B7280` | `priority-none` |
66
+
67
+ ### MYN Task Type Colors (Methodology)
68
+
69
+ | Type | Hex | Token |
70
+ |------|-----|-------|
71
+ | Parking Lot | `#F04F23` | `taskType-parkinglot` |
72
+ | Over the Horizon | `#F9913B` | `taskType-overthehorizon` |
73
+ | Critical Now | `#0C803D` | `taskType-critical` |
74
+ | Opportunity Now | `#107CC4` | `taskType-opportunitynow` |
75
+ | Tomorrow | `#854EB1` | `taskType-tomorrow` |
76
+
77
+ ### Shadcn/UI Semantic Tokens (CSS Variables)
78
+
79
+ ```
80
+ --background Page background (white / slate-950)
81
+ --foreground Primary text (slate-950 / slate-50)
82
+ --card Card backgrounds (white / slate-900)
83
+ --muted Muted backgrounds (slate-100 / slate-800)
84
+ --muted-foreground Secondary text (slate-500 / slate-400)
85
+ --border Borders (slate-200 / slate-700)
86
+ --primary Primary actions (blue-600 / blue-500)
87
+ --destructive Destructive actions (red-600 / red-500)
88
+ --ring Focus rings (blue-500 / blue-400)
89
+ ```
90
+
91
+ ### App Background
92
+
93
+ - Light: `#eff6ff` (blue-50)
94
+ - Dark: `#0f172a` (slate-900)
95
+ - Surfaces: `#1e293b` dark, `#334155` elevated dark
96
+
97
+ ## Typography
98
+
99
+ ### Font Stack
100
+
101
+ - **Primary**: Inter (all UI text)
102
+ - **Monospace**: SF Mono, Monaco, Cascadia Code
103
+ - **Accessibility**: Tiresias Infofont, OpenDyslexic3 (user-selectable)
104
+ - All legacy font aliases (Roboto, Lato, Montserrat, SF Pro) map to Inter
105
+
106
+ ### Type Scale
107
+
108
+ | Token | Size | Weight | Letter Spacing | Usage |
109
+ |-------|------|--------|----------------|-------|
110
+ | `display` | 2.441rem (39px) | 700 | -0.02em | Hero headlines |
111
+ | `h1` | 1.953rem (31px) | 700 | -0.01em | Page titles |
112
+ | `h2` | 1.563rem (25px) | 600 | -0.01em | Section headers |
113
+ | `h3` | 1.25rem (20px) | 600 | -- | Card headers |
114
+ | `body-lg` | 1.125rem (18px) | 400 | -- | Large body text |
115
+ | `body` | 1rem (16px) | 400 | -- | Default body text |
116
+ | `body-sm` | 0.875rem (14px) | 400 | -- | Compact text, task titles |
117
+ | `caption` | 0.75rem (12px) | 400 | -- | Labels, hints |
118
+ | `overline` | 0.625rem (10px) | 600 | 0.1em | Category labels |
119
+
120
+ ### Text Colors
121
+
122
+ ```
123
+ text-foreground Primary text
124
+ text-muted-foreground Secondary text, labels, icons
125
+ text-primary Links, emphasis
126
+ text-destructive Errors
127
+ text-card-foreground Text on cards
128
+ ```
129
+
130
+ ## Spacing & Layout
131
+
132
+ ### Spacing Scale
133
+
134
+ Standard Tailwind 4px base: `1`=4px, `2`=8px, `3`=12px, `4`=16px, `6`=24px, `8`=32px
135
+
136
+ ### Common Patterns
137
+
138
+ ```tsx
139
+ // Page container
140
+ <div className="max-w-[1320px] mx-auto pt-4 px-3 sm:px-4 lg:px-6">
141
+
142
+ // Two-column grid (sidebar visible at xl)
143
+ <div className="grid gap-7 xl:grid-cols-[minmax(0,820px)_420px]">
144
+
145
+ // Card padding
146
+ p-3 // Compact
147
+ p-4 // Standard
148
+ p-5 // Spacious
149
+
150
+ // Section gaps
151
+ mt-3 // Between compact sections
152
+ mt-4 // Between standard sections
153
+ gap-2 // Icon + text
154
+ gap-3 // Form elements
155
+ ```
156
+
157
+ ### Breakpoints
158
+
159
+ | Token | Width | Usage |
160
+ |-------|-------|-------|
161
+ | `xxs` | 350px | Small phones |
162
+ | `sm` | 640px | Small tablets |
163
+ | `md` | 768px | Tablets |
164
+ | `lg` | 1024px | Small desktops |
165
+ | `xl` | 1280px | Desktop (sidebar visible) |
166
+
167
+ ## Border & Shadow
168
+
169
+ ### Border Radius
170
+
171
+ ```
172
+ rounded-md (6px) Buttons, inputs, small cards
173
+ rounded-lg (8px) Cards, panels
174
+ rounded-xl (12px) Large cards, modals
175
+ rounded-full Pills, avatars
176
+ ```
177
+
178
+ ### Shadows
179
+
180
+ ```
181
+ shadow-sm Sidebar cards, secondary
182
+ shadow-md Main cards, primary content
183
+ shadow-lg Dropdowns, modals
184
+ shadow-xl Popovers, overlays
185
+ shadow-2xl Dialogs
186
+ ```
187
+
188
+ ### Opacity Modifiers
189
+
190
+ ```tsx
191
+ bg-muted/40 // Very subtle containers
192
+ border-border/50 // Container borders (default)
193
+ border-border/60 // Button/input borders
194
+ ring-ring/40 // Focus state ring
195
+ ```
196
+
197
+ ## Component Patterns
198
+
199
+ ### Buttons
200
+
201
+ | Size | Height | Padding | Icon | Usage |
202
+ |------|--------|---------|------|-------|
203
+ | xs | `h-7` | `px-2` | `h-3.5 w-3.5` | Inline actions |
204
+ | sm | `h-8` | `px-3` | `h-4 w-4` | Secondary actions |
205
+ | md | `h-9` | `px-3` | `h-4 w-4` | Icon buttons |
206
+ | lg | `h-10` | `px-4` | `h-5 w-5` | Primary actions |
207
+
208
+ ```tsx
209
+ // Primary
210
+ "h-10 px-4 rounded-md bg-primary text-primary-foreground hover:opacity-90"
211
+
212
+ // Secondary
213
+ "h-10 px-4 rounded-md border border-border/60 bg-card hover:bg-muted"
214
+
215
+ // Ghost
216
+ "h-9 px-3 rounded-md hover:bg-muted"
217
+
218
+ // Icon
219
+ "h-9 w-9 rounded-md hover:bg-muted text-muted-foreground"
220
+ ```
221
+
222
+ ### Cards
223
+
224
+ ```tsx
225
+ // Main card (primary, higher elevation)
226
+ <Card className="bg-card text-card-foreground rounded-lg shadow-md">
227
+
228
+ // Sidebar card (secondary, lower)
229
+ <Card className="bg-card text-card-foreground rounded-lg shadow-sm">
230
+
231
+ // Subtle container
232
+ <div className="rounded-md border border-border/50 bg-muted/40 px-3 py-2">
233
+ ```
234
+
235
+ ### Frosted Glass (Auth/Splash Screens)
236
+
237
+ ```tsx
238
+ // Blue gradient background
239
+ style={{ background: 'linear-gradient(to bottom, rgb(56, 189, 248), rgb(37, 99, 235))' }}
240
+
241
+ // Frosted glass card
242
+ <Card className="bg-white/90 backdrop-blur-sm border-blue-200 hover:shadow-lg transition-all duration-300">
243
+ ```
244
+
245
+ ### Toast Notifications
246
+
247
+ Current implementation uses Radix UI `@radix-ui/react-toast` with CVA variants:
248
+
249
+ ```tsx
250
+ // Variants: default, destructive, success, error, warning, info
251
+ // Base style:
252
+ "rounded-lg border-2 p-5 pr-7 shadow-xl backdrop-blur-sm"
253
+
254
+ // Each variant has light/dark mode colors:
255
+ // success: border-green-300 bg-green-50/95 text-green-900
256
+ // error: border-red-300 bg-red-50/95 text-red-900
257
+ // warning: border-amber-300 bg-amber-50/95 text-amber-900
258
+ // info: border-blue-300 bg-blue-50/95 text-blue-900
259
+
260
+ // Viewport: bottom-right on desktop, top on mobile
261
+ // Max width: 420px
262
+ // Animations: slide-in-from-top (mobile), slide-in-from-bottom (desktop)
263
+ // Hover: shadow-2xl + translate-y-0.5 lift
264
+ // Icons: Lucide (CheckCircle2, AlertCircle, AlertTriangle, Info) in rounded-full bg
265
+ // Close: absolute top-right, visible on hover
266
+ ```
267
+
268
+ ### Form Controls
269
+
270
+ ```tsx
271
+ // Input
272
+ "h-10 rounded-md border border-border/60 bg-card px-3 text-sm focus:ring-2 focus:ring-ring/40"
273
+
274
+ // Textarea
275
+ "rounded-md border border-border/60 bg-card p-3 text-sm min-h-[80px] focus:ring-2 focus:ring-ring/40"
276
+ ```
277
+
278
+ ## Animation System
279
+
280
+ ### Tailwind Keyframes
281
+
282
+ | Name | Duration | Usage |
283
+ |------|----------|-------|
284
+ | `wiggle` | 1s infinite | Playful attention |
285
+ | `fade-in` | 0.5s ease-out | Element entrance (translateY 10px) |
286
+ | `spin-slow` | 3s linear infinite | Loading states |
287
+ | `pulse-subtle` | 2s infinite | Gentle pulse (opacity 1→0.9) |
288
+ | `shimmer` | 2s linear infinite | Loading skeleton |
289
+ | `bounce-once` | 1s ease | Single bounce |
290
+
291
+ ### Framer Motion (Auth/Splash)
292
+
293
+ ```tsx
294
+ // Container: stagger children by 0.1s
295
+ const containerVariants = {
296
+ hidden: { opacity: 0 },
297
+ visible: { opacity: 1, transition: { staggerChildren: 0.1 } },
298
+ }
299
+
300
+ // Items: spring up from 20px below
301
+ const itemVariants = {
302
+ hidden: { y: 20, opacity: 0 },
303
+ visible: { y: 0, opacity: 1, transition: { type: 'spring', stiffness: 50 } },
304
+ }
305
+ ```
306
+
307
+ ### Task Completion
308
+
309
+ - Wavy green SVG strikethrough line + text fade
310
+ - 2s animation duration
311
+ - Do NOT modify sort logic in `sortTasksAndEvents.js`
312
+
313
+ ## Design Principles
314
+
315
+ 1. **Neutral Over Saturated** -- Use muted backgrounds, subtle borders. No saturated gradients for secondary elements.
316
+ 2. **Elevation Hierarchy** -- Primary content gets `shadow-md`, secondary gets `shadow-sm`.
317
+ 3. **Progressive Disclosure** -- Hide secondary actions until hover/focus.
318
+ 4. **Density Over Chrome** -- Tight padding, compact buttons, reduce visual noise.
319
+
320
+ ## Tech Stack
321
+
322
+ - **Framework**: React 19, Vite 7, TypeScript
323
+ - **State**: Jotai (client) + TanStack Query (server)
324
+ - **UI**: shadcn/ui (new-york style) + Material-UI (legacy, migrating away)
325
+ - **Styling**: Tailwind CSS with custom design tokens
326
+ - **Icons**: Lucide (primary), FontAwesome (legacy, GettingStarted only)
327
+ - **Animation**: Framer Motion (auth flows), Tailwind keyframes (in-app)
328
+ - **Mobile**: Capacitor for iOS/Android
329
+ - **Dark Mode**: `class` strategy via Tailwind `darkMode: 'class'`
330
+
331
+ ## File Structure
332
+
333
+ ```
334
+ src/
335
+ styles/
336
+ design-tokens.css CSS custom properties (brand, semantic, priority, task type)
337
+ notification-animations.css Toast animation keyframes
338
+ globals.css shadcn/ui CSS variables
339
+ components/
340
+ ui/ shadcn/ui base components (toast, card, button, etc.)
341
+ auth/ Auth flows (GettingStarted, EmailForm)
342
+ notifications/ NotificationItem, notification panels
343
+ lib/
344
+ utils.ts cn() helper (clsx + tailwind-merge)
345
+ ```
346
+
347
+ ## Key Files
348
+
349
+ - `tailwind.config.js` -- All design tokens, type scale, colors, animations
350
+ - `src/styles/design-tokens.css` -- CSS custom properties with dark mode overrides
351
+ - `docs/technical/frontend/UI-DESIGN-SYSTEM.md` -- Full design system documentation