prjct-cli 0.55.2 → 0.55.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.55.4] - 2026-02-05
4
+
5
+ ### Bug Fixes
6
+
7
+ - remove legacy p.*.md commands on sync
8
+
9
+
10
+ ## [0.55.3] - 2026-02-05
11
+
12
+ ### Bug Fixes
13
+
14
+ - ensure test isolation in IndexStorage tests
15
+ - remove MCP integrations, keep only Context7 (#87)
16
+
17
+
18
+ ## [0.56.0] - 2026-02-04
19
+
20
+ ### Breaking Changes
21
+
22
+ - **Removed MCP-based integrations** (Monday.com, GitHub Issues)
23
+ - Only Context7 remains as the sole MCP server (for library docs)
24
+ - Linear and JIRA use SDK/REST API directly (4x faster)
25
+
26
+ ### Features
27
+
28
+ - **Context7 auto-install**: Now automatically configured in `~/.claude/mcp.json` on `prjct init`
29
+
30
+ ### Fixed
31
+
32
+ - Templates no longer reference non-existent CLI commands (`prjct context task`, etc.)
33
+ - All workflow templates (task, done, bug, pause, resume, next, dash) now use Read/Write directly
34
+
35
+ ### Removed
36
+
37
+ - `templates/commands/monday.md` - MCP integration
38
+ - `templates/commands/github.md` - MCP integration
39
+ - `templates/_bases/tracker-base.md` - MCP base template
40
+ - `core/integrations/jira/mcp-adapter.ts` - Unused MCP adapter
41
+
3
42
  ## [0.55.2] - 2026-02-04
4
43
 
5
44
  ### Bug Fixes
@@ -184,9 +184,11 @@ describe('FileScorer', () => {
184
184
  })
185
185
 
186
186
  describe('IndexStorage', () => {
187
- const testProjectId = `test-project-${Date.now()}`
187
+ let testProjectId: string
188
188
 
189
189
  beforeEach(async () => {
190
+ // Generate unique project ID for each test to ensure isolation
191
+ testProjectId = `test-project-${Date.now()}-${Math.random().toString(36).slice(2)}`
190
192
  // Set up test directory
191
193
  const testDir = path.join(os.tmpdir(), `prjct-test-${Date.now()}`)
192
194
  pathManager.setGlobalBaseDir(testDir)
@@ -569,6 +569,36 @@ export class CommandInstaller {
569
569
  }
570
570
  }
571
571
 
572
+ /**
573
+ * Remove legacy p.*.md files from commands root directory
574
+ * These were replaced by the p/ subdirectory structure in v0.50+
575
+ */
576
+ async removeLegacyCommands(): Promise<number> {
577
+ const aiProvider = require('./ai-provider')
578
+ const activeProvider = aiProvider.getActiveProvider()
579
+ const commandsRoot = path.join(activeProvider.configDir, 'commands')
580
+
581
+ let removed = 0
582
+
583
+ try {
584
+ const files = await fs.readdir(commandsRoot)
585
+ const legacyFiles = files.filter((f) => f.startsWith('p.') && f.endsWith('.md'))
586
+
587
+ for (const file of legacyFiles) {
588
+ try {
589
+ await fs.unlink(path.join(commandsRoot, file))
590
+ removed++
591
+ } catch {
592
+ // Ignore errors removing individual files
593
+ }
594
+ }
595
+ } catch {
596
+ // Ignore errors if directory doesn't exist
597
+ }
598
+
599
+ return removed
600
+ }
601
+
572
602
  /**
573
603
  * Sync commands - intelligent update that detects and removes orphans
574
604
  */
@@ -639,9 +669,9 @@ export class CommandInstaller {
639
669
  }
640
670
  }
641
671
 
642
- // Note: We do NOT remove orphaned files
643
- // Legacy commands from older versions are preserved
644
- // to avoid breaking existing workflows
672
+ // Remove legacy p.*.md files from commands root (old naming convention)
673
+ // These were replaced by p/ subdirectory structure
674
+ await this.removeLegacyCommands()
645
675
 
646
676
  return results
647
677
  } catch (error) {
@@ -169,6 +169,9 @@ export async function run(): Promise<SetupResults> {
169
169
 
170
170
  // Install status line (Claude only)
171
171
  await installStatusLine()
172
+
173
+ // Install Context7 MCP (only MCP server prjct uses)
174
+ await installContext7MCP()
172
175
  }
173
176
  } else if (providerName === 'gemini') {
174
177
  // Gemini provider - install router and global config
@@ -875,6 +878,58 @@ echo "prjct"
875
878
  }
876
879
  }
877
880
 
881
+ /**
882
+ * Install Context7 MCP server configuration
883
+ *
884
+ * Context7 is the ONLY MCP server prjct uses - for library documentation lookup.
885
+ * All issue tracker integrations (Linear, JIRA) use SDK/REST API directly.
886
+ */
887
+ async function installContext7MCP(): Promise<void> {
888
+ try {
889
+ const claudeDir = path.join(os.homedir(), '.claude')
890
+ const mcpConfigPath = path.join(claudeDir, 'mcp.json')
891
+
892
+ // Ensure ~/.claude directory exists
893
+ if (!fs.existsSync(claudeDir)) {
894
+ fs.mkdirSync(claudeDir, { recursive: true })
895
+ }
896
+
897
+ // Context7 MCP configuration
898
+ const context7Config = {
899
+ mcpServers: {
900
+ context7: {
901
+ command: 'npx',
902
+ args: ['-y', '@upstash/context7-mcp@latest'],
903
+ },
904
+ },
905
+ }
906
+
907
+ // Check if mcp.json exists
908
+ if (fs.existsSync(mcpConfigPath)) {
909
+ // Read existing config
910
+ const existingContent = fs.readFileSync(mcpConfigPath, 'utf-8')
911
+ const existingConfig = JSON.parse(existingContent)
912
+
913
+ // Check if context7 is already configured
914
+ if (existingConfig.mcpServers?.context7) {
915
+ // Already configured, skip
916
+ return
917
+ }
918
+
919
+ // Add context7 to existing config
920
+ existingConfig.mcpServers = existingConfig.mcpServers || {}
921
+ existingConfig.mcpServers.context7 = context7Config.mcpServers.context7
922
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), 'utf-8')
923
+ } else {
924
+ // Create new mcp.json with context7
925
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), 'utf-8')
926
+ }
927
+ } catch (error) {
928
+ // Non-fatal error, just log
929
+ console.error(`Context7 MCP setup warning: ${(error as Error).message}`)
930
+ }
931
+ }
932
+
878
933
  /**
879
934
  * Install statusline modules (lib/ or components/)
880
935
  * Copies .sh files from source to destination, always overwriting for updates
@@ -19,20 +19,5 @@ export {
19
19
  } from './cache'
20
20
  // REST API client
21
21
  export { type JiraAuthMode, JiraProvider, jiraProvider } from './client'
22
- // MCP adapter (deprecated - will be removed)
23
- export {
24
- createCreateIssueInstruction,
25
- createGetIssueInstruction,
26
- // MCP instruction generators
27
- createSearchInstruction,
28
- createTransitionInstruction,
29
- createUpdateInstruction,
30
- getMCPSetupInstructions,
31
- // Utilities
32
- isMCPAvailable,
33
- JiraMCPAdapter,
34
- jiraMCPAdapter,
35
- type MCPInstruction,
36
- } from './mcp-adapter'
37
22
  // Service layer with caching (preferred API)
38
23
  export { JiraService, jiraService } from './service'
@@ -26,6 +26,7 @@ import {
26
26
  type ProjectContext,
27
27
  resolveToolIds,
28
28
  } from '../ai-tools'
29
+ import commandInstaller from '../infrastructure/command-installer'
29
30
  import configManager from '../infrastructure/config-manager'
30
31
  import pathManager from '../infrastructure/path-manager'
31
32
  import { metricsStorage } from '../storage/metrics-storage'
@@ -232,6 +233,11 @@ class SyncService {
232
233
  const duration = Date.now() - startTime
233
234
  const syncMetrics = await this.recordSyncMetrics(stats, contextFiles, agents, duration)
234
235
 
236
+ // 10. Update global config and commands (CLI does EVERYTHING)
237
+ // This ensures `prjct sync` from terminal updates global CLAUDE.md and commands
238
+ await commandInstaller.installGlobalConfig()
239
+ await commandInstaller.syncCommands()
240
+
235
241
  return {
236
242
  success: true,
237
243
  projectId: this.projectId,
@@ -5952,6 +5952,29 @@ var init_command_installer = __esm({
5952
5952
  throw error;
5953
5953
  }
5954
5954
  }
5955
+ /**
5956
+ * Remove legacy p.*.md files from commands root directory
5957
+ * These were replaced by the p/ subdirectory structure in v0.50+
5958
+ */
5959
+ async removeLegacyCommands() {
5960
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
5961
+ const activeProvider = aiProvider.getActiveProvider();
5962
+ const commandsRoot = path16.join(activeProvider.configDir, "commands");
5963
+ let removed = 0;
5964
+ try {
5965
+ const files = await fs16.readdir(commandsRoot);
5966
+ const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
5967
+ for (const file of legacyFiles) {
5968
+ try {
5969
+ await fs16.unlink(path16.join(commandsRoot, file));
5970
+ removed++;
5971
+ } catch {
5972
+ }
5973
+ }
5974
+ } catch {
5975
+ }
5976
+ return removed;
5977
+ }
5955
5978
  /**
5956
5979
  * Sync commands - intelligent update that detects and removes orphans
5957
5980
  */
@@ -6004,6 +6027,7 @@ var init_command_installer = __esm({
6004
6027
  results.errors.push({ file, error: error.message });
6005
6028
  }
6006
6029
  }
6030
+ await this.removeLegacyCommands();
6007
6031
  return results;
6008
6032
  } catch (error) {
6009
6033
  return {
@@ -19105,6 +19129,7 @@ var init_sync_service = __esm({
19105
19129
  "core/services/sync-service.ts"() {
19106
19130
  "use strict";
19107
19131
  init_ai_tools();
19132
+ init_command_installer();
19108
19133
  init_config_manager();
19109
19134
  init_path_manager();
19110
19135
  init_metrics_storage();
@@ -19203,6 +19228,8 @@ var init_sync_service = __esm({
19203
19228
  ]);
19204
19229
  const duration = Date.now() - startTime;
19205
19230
  const syncMetrics = await this.recordSyncMetrics(stats, contextFiles, agents, duration);
19231
+ await command_installer_default.installGlobalConfig();
19232
+ await command_installer_default.syncCommands();
19206
19233
  return {
19207
19234
  success: true,
19208
19235
  projectId: this.projectId,
@@ -21231,6 +21258,7 @@ async function run() {
21231
21258
  }
21232
21259
  await command_installer_default.installDocs();
21233
21260
  await installStatusLine();
21261
+ await installContext7MCP();
21234
21262
  }
21235
21263
  } else if (providerName === "gemini") {
21236
21264
  const geminiInstalled = await installGeminiRouter();
@@ -21681,6 +21709,37 @@ echo "prjct"
21681
21709
  }
21682
21710
  }
21683
21711
  }
21712
+ async function installContext7MCP() {
21713
+ try {
21714
+ const claudeDir = path44.join(os13.homedir(), ".claude");
21715
+ const mcpConfigPath = path44.join(claudeDir, "mcp.json");
21716
+ if (!fs41.existsSync(claudeDir)) {
21717
+ fs41.mkdirSync(claudeDir, { recursive: true });
21718
+ }
21719
+ const context7Config = {
21720
+ mcpServers: {
21721
+ context7: {
21722
+ command: "npx",
21723
+ args: ["-y", "@upstash/context7-mcp@latest"]
21724
+ }
21725
+ }
21726
+ };
21727
+ if (fs41.existsSync(mcpConfigPath)) {
21728
+ const existingContent = fs41.readFileSync(mcpConfigPath, "utf-8");
21729
+ const existingConfig = JSON.parse(existingContent);
21730
+ if (existingConfig.mcpServers?.context7) {
21731
+ return;
21732
+ }
21733
+ existingConfig.mcpServers = existingConfig.mcpServers || {};
21734
+ existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
21735
+ fs41.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
21736
+ } else {
21737
+ fs41.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
21738
+ }
21739
+ } catch (error) {
21740
+ console.error(`Context7 MCP setup warning: ${error.message}`);
21741
+ }
21742
+ }
21684
21743
  function installStatusLineModules(sourceDir, destDir) {
21685
21744
  if (!fs41.existsSync(sourceDir)) {
21686
21745
  return;
@@ -21777,6 +21836,7 @@ var init_setup = __esm({
21777
21836
  __name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
21778
21837
  __name(ensureStatusLineSettings, "ensureStatusLineSettings");
21779
21838
  __name(installStatusLine, "installStatusLine");
21839
+ __name(installContext7MCP, "installContext7MCP");
21780
21840
  __name(installStatusLineModules, "installStatusLineModules");
21781
21841
  __name(ensureStatusLineSymlink, "ensureStatusLineSymlink");
21782
21842
  __name(showResults, "showResults");
@@ -25161,7 +25221,7 @@ var require_package = __commonJS({
25161
25221
  "package.json"(exports, module) {
25162
25222
  module.exports = {
25163
25223
  name: "prjct-cli",
25164
- version: "0.55.2",
25224
+ version: "0.55.4",
25165
25225
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
25166
25226
  main: "core/index.ts",
25167
25227
  bin: {
@@ -873,6 +873,29 @@ var CommandInstaller = class {
873
873
  throw error;
874
874
  }
875
875
  }
876
+ /**
877
+ * Remove legacy p.*.md files from commands root directory
878
+ * These were replaced by the p/ subdirectory structure in v0.50+
879
+ */
880
+ async removeLegacyCommands() {
881
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
882
+ const activeProvider = aiProvider.getActiveProvider();
883
+ const commandsRoot = import_node_path3.default.join(activeProvider.configDir, "commands");
884
+ let removed = 0;
885
+ try {
886
+ const files = await import_promises.default.readdir(commandsRoot);
887
+ const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
888
+ for (const file of legacyFiles) {
889
+ try {
890
+ await import_promises.default.unlink(import_node_path3.default.join(commandsRoot, file));
891
+ removed++;
892
+ } catch {
893
+ }
894
+ }
895
+ } catch {
896
+ }
897
+ return removed;
898
+ }
876
899
  /**
877
900
  * Sync commands - intelligent update that detects and removes orphans
878
901
  */
@@ -925,6 +948,7 @@ var CommandInstaller = class {
925
948
  results.errors.push({ file, error: error.message });
926
949
  }
927
950
  }
951
+ await this.removeLegacyCommands();
928
952
  return results;
929
953
  } catch (error) {
930
954
  return {
@@ -876,6 +876,29 @@ var CommandInstaller = class {
876
876
  throw error;
877
877
  }
878
878
  }
879
+ /**
880
+ * Remove legacy p.*.md files from commands root directory
881
+ * These were replaced by the p/ subdirectory structure in v0.50+
882
+ */
883
+ async removeLegacyCommands() {
884
+ const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
885
+ const activeProvider = aiProvider.getActiveProvider();
886
+ const commandsRoot = import_node_path3.default.join(activeProvider.configDir, "commands");
887
+ let removed = 0;
888
+ try {
889
+ const files = await import_promises.default.readdir(commandsRoot);
890
+ const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
891
+ for (const file of legacyFiles) {
892
+ try {
893
+ await import_promises.default.unlink(import_node_path3.default.join(commandsRoot, file));
894
+ removed++;
895
+ } catch {
896
+ }
897
+ }
898
+ } catch {
899
+ }
900
+ return removed;
901
+ }
879
902
  /**
880
903
  * Sync commands - intelligent update that detects and removes orphans
881
904
  */
@@ -928,6 +951,7 @@ var CommandInstaller = class {
928
951
  results.errors.push({ file, error: error.message });
929
952
  }
930
953
  }
954
+ await this.removeLegacyCommands();
931
955
  return results;
932
956
  } catch (error) {
933
957
  return {
@@ -1168,6 +1192,7 @@ async function run() {
1168
1192
  }
1169
1193
  await command_installer_default.installDocs();
1170
1194
  await installStatusLine();
1195
+ await installContext7MCP();
1171
1196
  }
1172
1197
  } else if (providerName === "gemini") {
1173
1198
  const geminiInstalled = await installGeminiRouter();
@@ -1635,6 +1660,38 @@ echo "prjct"
1635
1660
  }
1636
1661
  }
1637
1662
  __name(installStatusLine, "installStatusLine");
1663
+ async function installContext7MCP() {
1664
+ try {
1665
+ const claudeDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".claude");
1666
+ const mcpConfigPath = import_node_path5.default.join(claudeDir, "mcp.json");
1667
+ if (!import_node_fs3.default.existsSync(claudeDir)) {
1668
+ import_node_fs3.default.mkdirSync(claudeDir, { recursive: true });
1669
+ }
1670
+ const context7Config = {
1671
+ mcpServers: {
1672
+ context7: {
1673
+ command: "npx",
1674
+ args: ["-y", "@upstash/context7-mcp@latest"]
1675
+ }
1676
+ }
1677
+ };
1678
+ if (import_node_fs3.default.existsSync(mcpConfigPath)) {
1679
+ const existingContent = import_node_fs3.default.readFileSync(mcpConfigPath, "utf-8");
1680
+ const existingConfig = JSON.parse(existingContent);
1681
+ if (existingConfig.mcpServers?.context7) {
1682
+ return;
1683
+ }
1684
+ existingConfig.mcpServers = existingConfig.mcpServers || {};
1685
+ existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
1686
+ import_node_fs3.default.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
1687
+ } else {
1688
+ import_node_fs3.default.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
1689
+ }
1690
+ } catch (error) {
1691
+ console.error(`Context7 MCP setup warning: ${error.message}`);
1692
+ }
1693
+ }
1694
+ __name(installContext7MCP, "installContext7MCP");
1638
1695
  function installStatusLineModules(sourceDir, destDir) {
1639
1696
  if (!import_node_fs3.default.existsSync(sourceDir)) {
1640
1697
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.55.2",
3
+ "version": "0.55.4",
4
4
  "description": "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {
@@ -4,35 +4,160 @@ allowed-tools: [Read, Write, Bash, Task, AskUserQuestion]
4
4
 
5
5
  # p. bug "$ARGUMENTS"
6
6
 
7
+ ## Step 1: Validate Arguments
8
+
9
+ ```
10
+ IF $ARGUMENTS is empty:
11
+ ASK: "What bug do you want to report?"
12
+ WAIT for response
13
+ DO NOT proceed with empty description
14
+ ```
15
+
16
+ ## Step 2: Resolve Project Paths
17
+
18
+ ```bash
19
+ # Get projectId from local config
20
+ cat .prjct/prjct.config.json | grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4
21
+ ```
22
+
23
+ Set `globalPath = ~/.prjct-cli/projects/{projectId}`
24
+
25
+ ## Step 3: Parse Severity from Keywords
26
+
27
+ Analyze `$ARGUMENTS` for severity indicators:
28
+ - `crash`, `down`, `broken`, `production`, `critical` → **critical**
29
+ - `error`, `fail`, `exception`, `cannot` → **high**
30
+ - `bug`, `incorrect`, `wrong`, `issue` → **medium** (default)
31
+ - `minor`, `typo`, `cosmetic`, `ui` → **low**
32
+
33
+ ## Step 4: Explore Codebase
34
+
35
+ ```
36
+ USE Task(Explore) → find affected files, recent commits related to the bug
37
+ ```
38
+
39
+ ## Step 5: Check for Active Task
40
+
41
+ READ `{globalPath}/storage/state.json`
42
+
43
+ ```
44
+ IF currentTask exists AND currentTask.status == "active":
45
+ AskUserQuestion:
46
+ question: "You have an active task. How should we handle this bug?"
47
+ header: "Bug"
48
+ options:
49
+ - label: "Pause current and fix bug (Recommended)"
50
+ description: "Save current task, start bug fix"
51
+ - label: "Queue bug for later"
52
+ description: "Add to queue, continue current task"
53
+
54
+ IF "Queue bug for later":
55
+ # Add to queue and stop
56
+ READ {globalPath}/storage/queue.json (or create empty array)
57
+ APPEND bug to queue:
58
+ {
59
+ "id": "{uuid}",
60
+ "type": "bug",
61
+ "description": "$ARGUMENTS",
62
+ "severity": "{severity}",
63
+ "createdAt": "{timestamp}",
64
+ "status": "queued"
65
+ }
66
+ WRITE {globalPath}/storage/queue.json
67
+
68
+ OUTPUT:
69
+ """
70
+ 🐛 Queued: $ARGUMENTS [{severity}]
71
+
72
+ Continue with: {currentTask.description}
73
+
74
+ Later: `p. task` to work on queued bug
75
+ """
76
+ STOP
77
+
78
+ IF "Pause current and fix bug":
79
+ # Move current task to pausedTasks
80
+ # Will be handled in Step 6
81
+ ```
82
+
83
+ ## Step 6: Create Bug Branch
84
+
85
+ ```bash
86
+ git branch --show-current
87
+ ```
88
+
89
+ ```
90
+ IF current branch == "main" OR "master":
91
+ # Create bug fix branch
92
+ slug = sanitize($ARGUMENTS) # lowercase, hyphens, max 50 chars
93
+
94
+ git checkout -b bug/{slug}
95
+
96
+ IF git command fails:
97
+ OUTPUT: "Failed to create branch. Check git status."
98
+ STOP
99
+ ```
100
+
101
+ ## Step 7: Write State
102
+
103
+ Generate UUID and timestamp:
7
104
  ```bash
8
- prjct context bug $ARGUMENTS
105
+ node -e "console.log(require('crypto').randomUUID())"
106
+ node -e "console.log(new Date().toISOString())"
9
107
  ```
10
108
 
11
- Parse severity from keywords:
12
- - crash/down/broken/production → critical
13
- - error/fail → high
14
- - bug/incorrect → medium (default)
15
- - minor/typo → low
109
+ READ current state, then update:
16
110
 
17
- USE Task(Explore) → find affected files, recent commits
111
+ ```
112
+ # If there was an active task, move it to pausedTasks
113
+ IF state.currentTask exists:
114
+ interruptedTask = state.currentTask
115
+ interruptedTask.status = "interrupted"
116
+ interruptedTask.interruptedAt = "{timestamp}"
117
+ interruptedTask.interruptedBy = "{new bug task id}"
18
118
 
19
- IF `currentTask` active:
20
- Ask: "Pause current and fix?" or "Queue for later"
21
- IF pause → save as `interruptedTask`
119
+ state.pausedTasks = state.pausedTasks || []
120
+ state.pausedTasks.push(interruptedTask)
121
+ ```
22
122
 
23
- IF on main → `git checkout -b bug/{slug}`
123
+ WRITE `{globalPath}/storage/state.json`:
124
+ ```json
125
+ {
126
+ "currentTask": {
127
+ "id": "{uuid}",
128
+ "description": "$ARGUMENTS",
129
+ "type": "bug",
130
+ "severity": "{severity}",
131
+ "status": "active",
132
+ "startedAt": "{timestamp}",
133
+ "branch": "bug/{slug}",
134
+ "affectedFiles": ["{files from exploration}"]
135
+ },
136
+ "pausedTasks": [{interruptedTask if any}]
137
+ }
138
+ ```
24
139
 
25
- UPDATE `{globalPath}/storage/state.json` with new bug task
26
- ADD to `{globalPath}/storage/queue.json`
140
+ ## Step 8: Log Event
141
+
142
+ APPEND to `{globalPath}/memory/events.jsonl`:
143
+ ```json
144
+ {"type":"bug_reported","taskId":"{uuid}","description":"$ARGUMENTS","severity":"{severity}","timestamp":"{timestamp}","branch":"bug/{slug}"}
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Output
27
150
 
28
- **Output**:
29
151
  ```
30
152
  🐛 [{severity}] $ARGUMENTS
31
153
 
32
- Affected: {files}
33
- Branch: {branch}
154
+ Affected: {files from exploration}
155
+ Branch: bug/{slug}
156
+
157
+ {IF interruptedTask: "Paused: {interruptedTask.description}"}
34
158
 
35
159
  Next:
36
- - Fix the bug → `p. done`
37
- - Queue onlyadd `--later` flag
160
+ - Fix the bug → work on code
161
+ - When fixed`p. done`
162
+ - Resume previous → `p. resume`
38
163
  ```