panopticon-cli 0.3.7 → 0.4.4

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 (37) hide show
  1. package/README.md +1610 -121
  2. package/dist/agents-B5NRTVHK.js +40 -0
  3. package/dist/chunk-7HHDVXBM.js +349 -0
  4. package/dist/chunk-7HHDVXBM.js.map +1 -0
  5. package/dist/chunk-H45CLB7E.js +2044 -0
  6. package/dist/chunk-H45CLB7E.js.map +1 -0
  7. package/dist/{chunk-C6A7S65K.js → chunk-ITI4IC5A.js} +188 -43
  8. package/dist/chunk-ITI4IC5A.js.map +1 -0
  9. package/dist/cli/index.js +8007 -2781
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/dashboard/public/assets/index-BDd8hGYb.css +32 -0
  12. package/dist/dashboard/public/assets/index-sFwLPko-.js +556 -0
  13. package/dist/dashboard/public/index.html +3 -2
  14. package/dist/dashboard/server.js +39015 -69826
  15. package/dist/index.d.ts +136 -1
  16. package/dist/index.js +36 -4
  17. package/package.json +10 -3
  18. package/scripts/git-hooks/post-checkout +109 -0
  19. package/templates/claude-md/sections/beads.md +1 -2
  20. package/templates/claude-md/sections/warnings.md +46 -2
  21. package/templates/context/CLAUDE.md.template +22 -0
  22. package/templates/context/REOPEN_PROMPT.md.template +75 -0
  23. package/templates/docker/dotnet/docker-compose.yml +2 -0
  24. package/templates/docker/monorepo/docker-compose.yml +4 -0
  25. package/templates/docker/nextjs/docker-compose.yml +1 -0
  26. package/templates/docker/python-fastapi/docker-compose.yml +3 -0
  27. package/templates/docker/react-vite/docker-compose.yml +1 -0
  28. package/templates/docker/spring-boot/docker-compose.yml +3 -0
  29. package/dist/chunk-BH6BR26M.js +0 -173
  30. package/dist/chunk-BH6BR26M.js.map +0 -1
  31. package/dist/chunk-C6A7S65K.js.map +0 -1
  32. package/dist/chunk-P5TQ5C3J.js +0 -103
  33. package/dist/chunk-P5TQ5C3J.js.map +0 -1
  34. package/dist/dashboard/public/assets/index-CUoYoWX_.css +0 -32
  35. package/dist/dashboard/public/assets/index-CY0Ew5B9.js +0 -423
  36. package/dist/projects-54CV437J.js +0 -34
  37. /package/dist/{projects-54CV437J.js.map → agents-B5NRTVHK.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ declare const TRAEFIK_DYNAMIC_DIR: string;
12
12
  declare const TRAEFIK_CERTS_DIR: string;
13
13
  declare const CERTS_DIR: string;
14
14
  declare const CONFIG_FILE: string;
15
+ declare const SETTINGS_FILE: string;
15
16
  declare const CLAUDE_DIR: string;
16
17
  declare const CODEX_DIR: string;
17
18
  declare const CURSOR_DIR: string;
@@ -44,6 +45,16 @@ declare const CLAUDE_MD_TEMPLATES: string;
44
45
  declare const SOURCE_TEMPLATES_DIR: string;
45
46
  declare const SOURCE_TRAEFIK_TEMPLATES: string;
46
47
  declare const SOURCE_SCRIPTS_DIR: string;
48
+ declare const SOURCE_SKILLS_DIR: string;
49
+ declare const SOURCE_DEV_SKILLS_DIR: string;
50
+ /**
51
+ * Detect if running in development mode (from npm link or panopticon repo)
52
+ *
53
+ * Dev mode is detected if:
54
+ * 1. Running from the panopticon source directory (npm link)
55
+ * 2. The SOURCE_DEV_SKILLS_DIR exists (only present in repo, not in npm package)
56
+ */
57
+ declare function isDevMode(): boolean;
47
58
  declare const INIT_DIRS: string[];
48
59
 
49
60
  /**
@@ -272,6 +283,7 @@ interface SyncPlan {
272
283
  skills: SyncItem[];
273
284
  commands: SyncItem[];
274
285
  agents: SyncItem[];
286
+ devSkills: SyncItem[];
275
287
  }
276
288
  /**
277
289
  * Check if a path is a Panopticon-managed symlink
@@ -507,4 +519,127 @@ declare class LinkManager {
507
519
  }
508
520
  declare function getLinkManager(): LinkManager;
509
521
 
510
- export { AGENTS_DIR, BACKUPS_DIR, BIN_DIR, type BackupInfo, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, CODEX_DIR, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, CURSOR_DIR, type Comment, GEMINI_DIR, type GitHubConfig, GitHubTracker, type GitLabConfig, GitLabTracker, HEARTBEATS_DIR, type HookItem, INIT_DIRS, type Issue, type IssueFilters, IssueNotFoundError, type IssueState, type IssueTracker, type IssueUpdate, type LinearConfig, LinearTracker, type LinkDirection, LinkManager, type NewIssue, NotImplementedError, PANOPTICON_HOME, type PanopticonConfig, type RallyConfig, type Runtime, SKILLS_DIR, SOURCE_SCRIPTS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGETS, type Shell, 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, addAlias, cleanOldBackups, createBackup, createBackupTimestamp, createTracker, createTrackerFromConfig, detectShell, executeSync, formatIssueRef, getAliasInstructions, getAllTrackers, getDefaultConfig, getLinkManager, getPrimaryTracker, getSecondaryTracker, getShellRcFile, hasAlias, isPanopticonSymlink, listBackups, loadConfig, parseIssueRef, planHooksSync, planSync, restoreBackup, saveConfig, syncHooks };
522
+ type AnthropicModel = 'claude-opus-4-5' | 'claude-sonnet-4-5' | 'claude-haiku-4-5';
523
+ type OpenAIModel = 'gpt-5.2-codex' | 'o3-deep-research' | 'gpt-4o' | 'gpt-4o-mini';
524
+ type GoogleModel = 'gemini-3-pro-preview' | 'gemini-3-flash-preview' | 'gemini-2.5-pro' | 'gemini-2.5-flash';
525
+ type ZAIModel = 'glm-4.7' | 'glm-4.7-flash';
526
+ type KimiModel = 'kimi-k2' | 'kimi-k2.5';
527
+ type ModelId = AnthropicModel | OpenAIModel | GoogleModel | ZAIModel | KimiModel;
528
+ type ComplexityLevel = 'trivial' | 'simple' | 'medium' | 'complex' | 'expert';
529
+ interface SpecialistModels {
530
+ review_agent: ModelId;
531
+ test_agent: ModelId;
532
+ merge_agent: ModelId;
533
+ }
534
+ type ComplexityModels = {
535
+ [K in ComplexityLevel]: ModelId;
536
+ };
537
+ interface ModelsConfig {
538
+ specialists: SpecialistModels;
539
+ planning_agent: ModelId;
540
+ complexity: ComplexityModels;
541
+ }
542
+ interface ApiKeysConfig {
543
+ openai?: string;
544
+ google?: string;
545
+ zai?: string;
546
+ kimi?: string;
547
+ }
548
+ interface SettingsConfig {
549
+ models: ModelsConfig;
550
+ api_keys: ApiKeysConfig;
551
+ }
552
+ /**
553
+ * Load settings from ~/.panopticon/settings.json
554
+ * Returns default settings if file doesn't exist or is invalid
555
+ * Also loads API keys from environment variables as fallback
556
+ */
557
+ declare function loadSettings(): SettingsConfig;
558
+ /**
559
+ * Save settings to ~/.panopticon/settings.json
560
+ * Writes with pretty formatting (2-space indent)
561
+ */
562
+ declare function saveSettings(settings: SettingsConfig): void;
563
+ /**
564
+ * Validate settings structure and model IDs
565
+ * Returns error message if invalid, null if valid
566
+ */
567
+ declare function validateSettings(settings: SettingsConfig): string | null;
568
+ /**
569
+ * Get a deep copy of the default settings
570
+ */
571
+ declare function getDefaultSettings(): SettingsConfig;
572
+ /**
573
+ * Get available models for a provider based on configured API keys
574
+ * Returns empty array if provider API key is not configured
575
+ */
576
+ declare function getAvailableModels(settings: SettingsConfig): {
577
+ anthropic: AnthropicModel[];
578
+ openai: OpenAIModel[];
579
+ google: GoogleModel[];
580
+ zai: ZAIModel[];
581
+ kimi: KimiModel[];
582
+ };
583
+
584
+ /**
585
+ * Provider Configuration and Compatibility
586
+ *
587
+ * Defines which LLM providers are compatible with Claude Code's API format.
588
+ * - Direct providers: Implement Anthropic-compatible API (no router needed)
589
+ * - Router providers: Require claude-code-router for API translation
590
+ */
591
+
592
+ type ProviderName = 'anthropic' | 'kimi' | 'openai' | 'google' | 'zai';
593
+ /**
594
+ * Provider compatibility types
595
+ * - direct: Anthropic-compatible API, use ANTHROPIC_BASE_URL directly
596
+ * - router: Incompatible API, requires claude-code-router for translation
597
+ */
598
+ type ProviderCompatibility = 'direct' | 'router';
599
+ /**
600
+ * Provider configuration
601
+ */
602
+ interface ProviderConfig {
603
+ name: ProviderName;
604
+ displayName: string;
605
+ compatibility: ProviderCompatibility;
606
+ baseUrl?: string;
607
+ models: ModelId[];
608
+ tested: boolean;
609
+ description: string;
610
+ }
611
+ /**
612
+ * All provider configurations
613
+ */
614
+ declare const PROVIDERS: Record<ProviderName, ProviderConfig>;
615
+ /**
616
+ * Get provider for a given model ID
617
+ */
618
+ declare function getProviderForModel(modelId: ModelId): ProviderConfig;
619
+ /**
620
+ * Check if a provider requires claude-code-router
621
+ */
622
+ declare function requiresRouter(provider: ProviderName): boolean;
623
+ /**
624
+ * Get all providers that require router (have router compatibility)
625
+ */
626
+ declare function getRouterProviders(): ProviderConfig[];
627
+ /**
628
+ * Get all direct-compatible providers
629
+ */
630
+ declare function getDirectProviders(): ProviderConfig[];
631
+ /**
632
+ * Check if any configured providers require router
633
+ * Used to determine if router installation is needed
634
+ */
635
+ declare function needsRouter(apiKeys: {
636
+ openai?: string;
637
+ google?: string;
638
+ zai?: string;
639
+ }): boolean;
640
+ /**
641
+ * Get environment variables for spawning agent with specific provider
642
+ */
643
+ declare function getProviderEnv(provider: ProviderConfig, apiKey: string): Record<string, string>;
644
+
645
+ export { AGENTS_DIR, type AnthropicModel, type ApiKeysConfig, BACKUPS_DIR, BIN_DIR, type BackupInfo, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, CODEX_DIR, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, CURSOR_DIR, type Comment, type ComplexityLevel, type ComplexityModels, GEMINI_DIR, 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, type LinearConfig, LinearTracker, type LinkDirection, LinkManager, type ModelId, type ModelsConfig, type NewIssue, NotImplementedError, type OpenAIModel, PANOPTICON_HOME, PROVIDERS, type PanopticonConfig, type ProviderCompatibility, type ProviderConfig, type ProviderName, type RallyConfig, type Runtime, SETTINGS_FILE, SKILLS_DIR, SOURCE_DEV_SKILLS_DIR, SOURCE_SCRIPTS_DIR, SOURCE_SKILLS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGETS, type SettingsConfig, 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, formatIssueRef, getAliasInstructions, getAllTrackers, getAvailableModels, getDefaultConfig, getDefaultSettings, getDirectProviders, getLinkManager, getPrimaryTracker, getProviderEnv, getProviderForModel, getRouterProviders, getSecondaryTracker, getShellRcFile, hasAlias, isDevMode, isPanopticonSymlink, listBackups, loadConfig, loadSettings, needsRouter, parseIssueRef, planHooksSync, planSync, requiresRouter, restoreBackup, saveConfig, saveSettings, syncHooks, validateSettings };
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  restoreBackup,
33
33
  saveConfig,
34
34
  syncHooks
35
- } from "./chunk-C6A7S65K.js";
35
+ } from "./chunk-ITI4IC5A.js";
36
36
  import {
37
37
  AGENTS_DIR,
38
38
  BACKUPS_DIR,
@@ -50,16 +50,32 @@ import {
50
50
  HEARTBEATS_DIR,
51
51
  INIT_DIRS,
52
52
  PANOPTICON_HOME,
53
+ PROVIDERS,
54
+ SETTINGS_FILE,
53
55
  SKILLS_DIR,
56
+ SOURCE_DEV_SKILLS_DIR,
54
57
  SOURCE_SCRIPTS_DIR,
58
+ SOURCE_SKILLS_DIR,
55
59
  SOURCE_TEMPLATES_DIR,
56
60
  SOURCE_TRAEFIK_TEMPLATES,
57
61
  SYNC_TARGETS,
58
62
  TEMPLATES_DIR,
59
63
  TRAEFIK_CERTS_DIR,
60
64
  TRAEFIK_DIR,
61
- TRAEFIK_DYNAMIC_DIR
62
- } from "./chunk-P5TQ5C3J.js";
65
+ TRAEFIK_DYNAMIC_DIR,
66
+ getAvailableModels,
67
+ getDefaultSettings,
68
+ getDirectProviders,
69
+ getProviderEnv,
70
+ getProviderForModel,
71
+ getRouterProviders,
72
+ isDevMode,
73
+ loadSettings,
74
+ needsRouter,
75
+ requiresRouter,
76
+ saveSettings,
77
+ validateSettings
78
+ } from "./chunk-7HHDVXBM.js";
63
79
  export {
64
80
  AGENTS_DIR,
65
81
  BACKUPS_DIR,
@@ -83,8 +99,12 @@ export {
83
99
  LinkManager,
84
100
  NotImplementedError,
85
101
  PANOPTICON_HOME,
102
+ PROVIDERS,
103
+ SETTINGS_FILE,
86
104
  SKILLS_DIR,
105
+ SOURCE_DEV_SKILLS_DIR,
87
106
  SOURCE_SCRIPTS_DIR,
107
+ SOURCE_SKILLS_DIR,
88
108
  SOURCE_TEMPLATES_DIR,
89
109
  SOURCE_TRAEFIK_TEMPLATES,
90
110
  SYNC_TARGETS,
@@ -104,20 +124,32 @@ export {
104
124
  formatIssueRef,
105
125
  getAliasInstructions,
106
126
  getAllTrackers,
127
+ getAvailableModels,
107
128
  getDefaultConfig,
129
+ getDefaultSettings,
130
+ getDirectProviders,
108
131
  getLinkManager,
109
132
  getPrimaryTracker,
133
+ getProviderEnv,
134
+ getProviderForModel,
135
+ getRouterProviders,
110
136
  getSecondaryTracker,
111
137
  getShellRcFile,
112
138
  hasAlias,
139
+ isDevMode,
113
140
  isPanopticonSymlink,
114
141
  listBackups,
115
142
  loadConfig,
143
+ loadSettings,
144
+ needsRouter,
116
145
  parseIssueRef,
117
146
  planHooksSync,
118
147
  planSync,
148
+ requiresRouter,
119
149
  restoreBackup,
120
150
  saveConfig,
121
- syncHooks
151
+ saveSettings,
152
+ syncHooks,
153
+ validateSettings
122
154
  };
123
155
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panopticon-cli",
3
- "version": "0.3.7",
3
+ "version": "0.4.4",
4
4
  "description": "Multi-agent orchestration for AI coding assistants (Claude Code, Codex, Cursor, Gemini CLI)",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -24,6 +24,11 @@
24
24
  "url": "https://github.com/eltmon/panopticon-cli/issues"
25
25
  },
26
26
  "type": "module",
27
+ "workspaces": [
28
+ "packages/shared",
29
+ "src/dashboard/server",
30
+ "src/dashboard/frontend"
31
+ ],
27
32
  "bin": {
28
33
  "pan": "./dist/cli/index.js",
29
34
  "panopticon": "./dist/cli/index.js"
@@ -33,6 +38,7 @@
33
38
  "files": [
34
39
  "dist",
35
40
  "templates",
41
+ "scripts/git-hooks",
36
42
  "README.md",
37
43
  "LICENSE"
38
44
  ],
@@ -48,7 +54,7 @@
48
54
  "build:dashboard:server": "cd src/dashboard/server && npm run build",
49
55
  "typecheck": "tsc --noEmit",
50
56
  "lint": "eslint src/",
51
- "test": "vitest --run --no-file-parallelism",
57
+ "test": "vitest --run --no-file-parallelism && cd src/dashboard/frontend && npm test",
52
58
  "test:unit": "vitest run tests/unit",
53
59
  "test:integration": "vitest run tests/integration",
54
60
  "test:e2e": "vitest run tests/e2e",
@@ -69,13 +75,14 @@
69
75
  "conf": "^12.0.0",
70
76
  "execa": "^8.0.1",
71
77
  "inquirer": "^9.3.8",
78
+ "js-yaml": "^4.1.1",
72
79
  "ora": "^8.2.0",
73
- "rally": "^2.1.3",
74
80
  "yaml": "^2.8.2"
75
81
  },
76
82
  "devDependencies": {
77
83
  "@types/better-sqlite3": "^7.6.13",
78
84
  "@types/inquirer": "^9.0.9",
85
+ "@types/js-yaml": "^4.0.9",
79
86
  "@types/node": "^20.10.0",
80
87
  "@vitest/coverage-v8": "^1.0.4",
81
88
  "eslint": "^8.55.0",
@@ -0,0 +1,109 @@
1
+ #!/bin/bash
2
+ #
3
+ # Git post-checkout hook to guard main project directories
4
+ # Prevents accidental checkouts away from main in the primary project directory
5
+ #
6
+ # Install: ln -sf /path/to/panopticon/scripts/git-hooks/post-checkout .git/hooks/post-checkout
7
+ # Or: pan projects add /path/to/project (auto-installs hooks)
8
+ #
9
+ # This hook only activates in the MAIN project directory (not worktrees).
10
+ # Worktrees can freely checkout any branch - that's their purpose.
11
+ #
12
+ # Auto-revert behavior:
13
+ # - Agents (PANOPTICON_AGENT=1): Always auto-revert (agents should never checkout in main)
14
+ # - Manual (PANOPTICON_AUTO_REVERT_CHECKOUT=1): Opt-in auto-revert for humans
15
+ # - Default: Warn only, don't revert
16
+
17
+ # Get the previous and new HEAD refs
18
+ PREV_HEAD=$1
19
+ NEW_HEAD=$2
20
+ IS_BRANCH_CHECKOUT=$3 # 1 if branch checkout, 0 if file checkout
21
+
22
+ # Only care about branch checkouts
23
+ if [ "$IS_BRANCH_CHECKOUT" != "1" ]; then
24
+ exit 0
25
+ fi
26
+
27
+ # Check if we're in a worktree (worktrees have .git as a file, not directory)
28
+ if [ -f ".git" ]; then
29
+ # This is a worktree - allow any checkout
30
+ exit 0
31
+ fi
32
+
33
+ # Check if .git is a directory (main repo)
34
+ if [ ! -d ".git" ]; then
35
+ # Not a git repo at all
36
+ exit 0
37
+ fi
38
+
39
+ # Get current branch name
40
+ CURRENT_BRANCH=$(git branch --show-current 2>/dev/null)
41
+
42
+ # If we're on main or master, all good
43
+ if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then
44
+ exit 0
45
+ fi
46
+
47
+ # We're in the main project directory and NOT on main - this is bad!
48
+ echo ""
49
+ echo "╔══════════════════════════════════════════════════════════════════════════════╗"
50
+ echo "║ ⚠️ WARNING: Main project directory is not on 'main' branch! ║"
51
+ echo "╠══════════════════════════════════════════════════════════════════════════════╣"
52
+ echo "║ ║"
53
+ echo "║ Current branch: $CURRENT_BRANCH"
54
+ echo "║ Location: $(pwd)"
55
+ echo "║ ║"
56
+ echo "║ The main project directory should ALWAYS stay on 'main'. ║"
57
+ echo "║ All feature work should happen in workspaces (git worktrees). ║"
58
+ echo "║ ║"
59
+ echo "║ To fix this: ║"
60
+ echo "║ git checkout main ║"
61
+ echo "║ ║"
62
+ echo "║ To work on a feature: ║"
63
+ echo "║ pan workspace create ISSUE-ID ║"
64
+ echo "║ ║"
65
+ echo "╚══════════════════════════════════════════════════════════════════════════════╝"
66
+ echo ""
67
+
68
+ # Auto-revert for agents and planning sessions
69
+ # They should NEVER be checking out in main project
70
+ IS_PANOPTICON_SESSION=0
71
+
72
+ # Check explicit environment variables
73
+ if [ "$PANOPTICON_AGENT" = "1" ] || [ -n "$PANOPTICON_AGENT_ID" ]; then
74
+ IS_PANOPTICON_SESSION=1
75
+ fi
76
+
77
+ # Check for planning session
78
+ if [ "$PANOPTICON_PLANNING" = "1" ] || [ -n "$PANOPTICON_PLANNING_ISSUE" ]; then
79
+ IS_PANOPTICON_SESSION=1
80
+ fi
81
+
82
+ # Check tmux session name pattern (agent-* or planning-* or specialist-*)
83
+ if [ -n "$TMUX" ]; then
84
+ TMUX_SESSION=$(tmux display-message -p '#{session_name}' 2>/dev/null || true)
85
+ case "$TMUX_SESSION" in
86
+ agent-*|planning-*|specialist-*)
87
+ IS_PANOPTICON_SESSION=1
88
+ ;;
89
+ esac
90
+ fi
91
+
92
+ if [ "$IS_PANOPTICON_SESSION" = "1" ]; then
93
+ echo "🤖 Panopticon session detected - auto-reverting to main branch..."
94
+ git checkout main --quiet
95
+ echo "✓ Reverted to main branch. Agents/planning must use workspaces for feature branches."
96
+ exit 0
97
+ fi
98
+
99
+ # Check for manual auto-revert environment variable
100
+ if [ "$PANOPTICON_AUTO_REVERT_CHECKOUT" = "1" ]; then
101
+ echo "Auto-reverting to main branch (PANOPTICON_AUTO_REVERT_CHECKOUT=1)..."
102
+ git checkout main --quiet
103
+ echo "Reverted to main branch."
104
+ exit 0
105
+ fi
106
+
107
+ # Return success but with warning - don't block the checkout
108
+ # The warning is enough for humans to notice
109
+ exit 0
@@ -3,12 +3,11 @@
3
3
  Use beads for persistent task tracking that survives compaction.
4
4
 
5
5
  ```bash
6
- bd ready # Find unblocked work
6
+ bd list # See all tasks
7
7
  bd show <id> # Get full context
8
8
  bd update <id> --status in_progress # Start work
9
9
  bd comments add <id> "note" # Add progress (CRITICAL)
10
10
  bd close <id> --reason "..." # Complete
11
- bd sync # Persist to git
12
11
  ```
13
12
 
14
13
  **ALWAYS** add comments as you work - they survive context compaction.
@@ -4,6 +4,41 @@
4
4
  - **DO NOT** push to main/master branch directly
5
5
  - **ALWAYS** check for existing patterns before introducing new ones
6
6
 
7
+ ## CRITICAL: Workspace Isolation
8
+
9
+ **You are working in an ISOLATED WORKSPACE. Your working directory MUST be:**
10
+
11
+ ```
12
+ {{WORKSPACE_PATH}}
13
+ ```
14
+
15
+ **Before making ANY file changes:**
16
+ 1. Run `pwd` to verify you're in the workspace
17
+ 2. All file paths should be relative to the workspace OR absolute paths within the workspace
18
+ 3. NEVER use paths like `/home/.../projects/panopticon/src/...` (main project)
19
+ 4. ALWAYS use paths like `./src/...` or `{{WORKSPACE_PATH}}/src/...` (workspace)
20
+
21
+ **If you see yourself working in the main project directory instead of the workspace, STOP and correct your working directory.**
22
+
23
+ ## NEVER Defer Work (CRITICAL)
24
+
25
+ **You MUST complete ALL work in the issue scope. NEVER defer tasks to "future PRs".**
26
+
27
+ ❌ **NEVER say things like:**
28
+ - "Deferred for future PR"
29
+ - "Left as TODO for follow-up"
30
+ - "Out of scope, will address later"
31
+ - "Dashboard integration deferred"
32
+ - "Tests deferred for future work"
33
+
34
+ ✅ **Instead:**
35
+ - Complete the full scope of the issue
36
+ - If scope is too large, ask the user to split the issue BEFORE starting
37
+ - If blocked, report the blocker and wait for guidance
38
+ - If you run out of context, use `/work-tell` to hand off with full notes
39
+
40
+ **The issue is NOT complete until ALL requirements are implemented, tested, and working.**
41
+
7
42
  ## Completion Requirements (CRITICAL)
8
43
 
9
44
  **You are NOT done until ALL of these are true:**
@@ -18,9 +53,18 @@
18
53
  # 1. Run tests
19
54
  npm test # or: mvn test, cargo test, etc.
20
55
 
21
- # 2. Stage and commit ALL changes
56
+ # 2. Stage and commit ALL changes with Co-Authored-By line
57
+ # CRITICAL: Use YOUR EXACT MODEL ID in the Co-Authored-By line
58
+ # You have access to your model ID - it's shown in your system context
22
59
  git add -A
23
- git commit -m "feat: description (ISSUE-XXX)"
60
+ git commit -m "feat: description (ISSUE-XXX)
61
+
62
+ Co-Authored-By: Claude <your-exact-model-id-here> <noreply@anthropic.com>"
63
+
64
+ # Example for claude-sonnet-4-5-20250929:
65
+ # git commit -m "feat: add specialist completion API
66
+ #
67
+ # Co-Authored-By: Claude claude-sonnet-4-5-20250929 <noreply@anthropic.com>"
24
68
 
25
69
  # 3. Push to remote
26
70
  git push -u origin $(git branch --show-current)
@@ -67,6 +67,28 @@ Before marking this issue complete:
67
67
  - [ ] No console errors or warnings
68
68
  - [ ] Documentation updated if needed
69
69
 
70
+ ## Responding to Review Feedback
71
+
72
+ If you receive feedback from review-agent indicating issues to fix:
73
+
74
+ 1. **Read the feedback carefully** - Understand each issue raised
75
+ 2. **Fix all issues** - Address every item in the feedback
76
+ 3. **Test your fixes** - Ensure tests still pass
77
+ 4. **Commit and push** - Push your fixes to the remote branch
78
+ 5. **Request re-review** - Run this command:
79
+ ```bash
80
+ pan work request-review {{ISSUE_ID}} -m "Fixed: [brief summary of what you fixed]"
81
+ ```
82
+
83
+ **Circuit breaker**: You can auto-request re-review up to 3 times. After that, a human must click "Review" in the dashboard.
84
+
85
+ **Example**:
86
+ ```bash
87
+ pan work request-review PAN-123 -m "Fixed: added real tests instead of placeholders"
88
+ ```
89
+
90
+ This will queue the review-agent to re-review your changes.
91
+
70
92
  ## Emergency Recovery
71
93
 
72
94
  If you're resuming after a crash:
@@ -0,0 +1,75 @@
1
+ # Reopened Issue: {{ISSUE_ID}}
2
+
3
+ ## ⚠️ Important: This is Follow-up Work
4
+
5
+ This issue was previously completed and merged. It has been **reopened** for additional work.
6
+
7
+ ## What This Means
8
+
9
+ You are NOT starting from scratch. Instead:
10
+
11
+ 1. **Previous work exists** - Code has already been written, tested, and merged
12
+ 2. **Build on what's there** - Extend, fix, or enhance the existing implementation
13
+ 3. **Preserve functionality** - Don't break what's already working
14
+ 4. **Understand the context** - Review what was done before planning new work
15
+
16
+ ## Your Mission
17
+
18
+ **{{ISSUE_ID}}**: {{ISSUE_TITLE}}
19
+
20
+ ### Why It Was Reopened
21
+
22
+ {{REOPEN_REASON}}
23
+
24
+ ### What Was Previously Accomplished
25
+
26
+ {{PREVIOUS_WORK_SUMMARY}}
27
+
28
+ ### Original Issue Description
29
+
30
+ {{ISSUE_DESCRIPTION}}
31
+
32
+ ## Getting Started
33
+
34
+ 1. **Read `.planning/REOPEN.md`** - Detailed context about previous work
35
+ 2. **Read `.planning/STATE.md`** - Full implementation history
36
+ 3. **Review the codebase** - Understand what was built:
37
+ {{KEY_FILES}}
38
+ 4. **Check for new requirements** - Look for:
39
+ - New comments on the GitHub issue
40
+ - User feedback or bug reports
41
+ - Additional acceptance criteria
42
+ 5. **Plan your approach** - Identify what needs to be added/fixed
43
+ 6. **Implement carefully** - Build on the existing foundation
44
+ 7. **Test thoroughly** - Ensure both old and new functionality works
45
+ 8. **Request review** - When complete, run `pan work request-review {{ISSUE_ID}}`
46
+
47
+ ## Critical Guidelines
48
+
49
+ - **Don't duplicate work** - Check if functionality already exists
50
+ - **Don't break existing tests** - All {{EXISTING_TESTS}} existing tests must still pass
51
+ - **Follow existing patterns** - Match the code style and architecture
52
+ - **Update existing docs** - Don't create duplicate documentation
53
+ - **Respect git history** - Review commits to understand design decisions
54
+
55
+ ## Workspace Info
56
+
57
+ - **Branch**: {{BRANCH_NAME}}
58
+ - **Workspace**: {{WORKSPACE_PATH}}
59
+ - **Previous commits**: {{COMMIT_COUNT}} commits on this branch
60
+ - **Tests**: {{TEST_COUNT}} tests currently passing
61
+
62
+ ## Review Workflow
63
+
64
+ This reopened issue can go through the standard review workflow:
65
+
66
+ 1. Complete your work
67
+ 2. Commit and push: `git push -u origin {{BRANCH_NAME}}`
68
+ 3. Request review: `pan work request-review {{ISSUE_ID}} -m "Completed follow-up work"`
69
+ 4. Review-agent will review
70
+ 5. Test-agent will run tests
71
+ 6. Human will approve and merge
72
+
73
+ ---
74
+
75
+ **Remember**: This is iterative development. You're adding to something that already works, not building from zero.
@@ -2,6 +2,7 @@ version: '3.8'
2
2
 
3
3
  services:
4
4
  app:
5
+ restart: unless-stopped
5
6
  build:
6
7
  context: .
7
8
  dockerfile: Dockerfile.dev
@@ -27,6 +28,7 @@ services:
27
28
  - "traefik.http.services.${COMPOSE_PROJECT_NAME:-dotnet}.loadbalancer.server.port=5000"
28
29
 
29
30
  sqlserver:
31
+ restart: unless-stopped
30
32
  image: mcr.microsoft.com/mssql/server:2022-latest
31
33
  environment:
32
34
  - ACCEPT_EULA=Y
@@ -2,6 +2,7 @@ version: '3.8'
2
2
 
3
3
  services:
4
4
  frontend:
5
+ restart: unless-stopped
5
6
  build:
6
7
  context: .
7
8
  dockerfile: Dockerfile.frontend
@@ -24,6 +25,7 @@ services:
24
25
  - "traefik.http.services.${COMPOSE_PROJECT_NAME:-app}-frontend.loadbalancer.server.port=5173"
25
26
 
26
27
  backend:
28
+ restart: unless-stopped
27
29
  build:
28
30
  context: .
29
31
  dockerfile: Dockerfile.backend
@@ -50,6 +52,7 @@ services:
50
52
  - "traefik.http.services.${COMPOSE_PROJECT_NAME:-app}-api.loadbalancer.server.port=3001"
51
53
 
52
54
  postgres:
55
+ restart: unless-stopped
53
56
  image: postgres:16-alpine
54
57
  environment:
55
58
  - POSTGRES_DB=${DB_NAME:-appdb}
@@ -68,6 +71,7 @@ services:
68
71
  - app-network
69
72
 
70
73
  redis:
74
+ restart: unless-stopped
71
75
  image: redis:7-alpine
72
76
  ports:
73
77
  - "${REDIS_PORT:-6379}:6379"
@@ -2,6 +2,7 @@ version: '3.8'
2
2
 
3
3
  services:
4
4
  app:
5
+ restart: unless-stopped
5
6
  build:
6
7
  context: .
7
8
  dockerfile: Dockerfile.dev
@@ -2,6 +2,7 @@ version: '3.8'
2
2
 
3
3
  services:
4
4
  app:
5
+ restart: unless-stopped
5
6
  build:
6
7
  context: .
7
8
  dockerfile: Dockerfile.dev
@@ -27,6 +28,7 @@ services:
27
28
  - "traefik.http.services.${COMPOSE_PROJECT_NAME:-fastapi}.loadbalancer.server.port=8000"
28
29
 
29
30
  postgres:
31
+ restart: unless-stopped
30
32
  image: postgres:16-alpine
31
33
  environment:
32
34
  - POSTGRES_DB=${DB_NAME:-appdb}
@@ -45,6 +47,7 @@ services:
45
47
  - app-network
46
48
 
47
49
  redis:
50
+ restart: unless-stopped
48
51
  image: redis:7-alpine
49
52
  ports:
50
53
  - "${REDIS_PORT:-6379}:6379"
@@ -2,6 +2,7 @@ version: '3.8'
2
2
 
3
3
  services:
4
4
  app:
5
+ restart: unless-stopped
5
6
  build:
6
7
  context: .
7
8
  dockerfile: Dockerfile.dev