esedre 0.1.8 → 0.1.10

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 ADDED
@@ -0,0 +1,68 @@
1
+ # Changelog
2
+
3
+ All notable changes to Esedre are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.10] - 2026-09-26
9
+
10
+ ### Added
11
+ - **Single-Step Ticket Creation (`--detail` & `--file`)**: `ese create` accepts `--detail "<md>"` and `--file <path>` to populate `detail.md` specifications during ticket creation without requiring a secondary `ese plan` call.
12
+ - **MCP `esedre_create_ticket` Specification Markdown**: Added optional `detail` parameter to the MCP create tool for agents to mint tickets with full specifications in a single turn.
13
+ - **`ese refresh` CLI Alias**: Added `refresh` as a direct alias for `ese snapshot` to regenerate the `.esedre/snapshot.json` projection.
14
+
15
+ ### Fixed
16
+ - **Windows CMD Batch Label Syntax Error**: Refactored `WRAPPER_CMD` (`ese.cmd` / `esedre.cmd`) to eliminate parenthesized `if (...)` blocks around `goto` statements, converted jump points to top-level labels, and prefixed all batch script invocations with `call` to prevent `'The system cannot find the batch label specified - done'` crashes on Windows.
17
+ - **PowerShell Console Stream UTF-8 Encoding**: Enforced `[Console]::OutputEncoding`, `[Console]::InputEncoding`, and `$OutputEncoding = UTF-8` in `ese.ps1` to prevent Unicode characters (en-dashes, quotes) from rendering as mojibake.
18
+ - **Structured JSON Output for `ese plan --json`**: Corrected `ese plan <id> --json` to emit a machine-readable JSON payload (`{ success, ticketId, project, planMarkdown, sha1 }`) instead of ANSI terminal text.
19
+
20
+ ## [0.1.9] - 2026-09-25
21
+
22
+ ### Added
23
+ - **Smart npm Publish Lifecycle Wrapper (`npm run pub`)**: Upfront authentication pre-check (`npm whoami`) with automatic interactive login before compilation, executing full prepublish test/lint/build lifecycle.
24
+ - **Multi-Layer Zero-Crawl Protection**: Edge and Vite middleware security preventing search spiders and AI crawler cataloging on development tunnels (`esedre.aroomwithamoose.com`).
25
+ - **Canonical Apex Ecosystem Links**: Standardized all portfolio ecosystem references to canonical apex `https://arwam.com`.
26
+
27
+ ## [0.1.8] - 2026-09-11
28
+
29
+ ### Added
30
+ - **Dynamic Configuration & Manifest Reloading**: 3-second TTL polling (`ensureFreshConfig`) reloading external hubs and manifests in real time without daemon restarts.
31
+
32
+ ### Changed
33
+ - **Gateway Server Portfolio Decoupling**: Background daemon and gateway cluster (`ese start`) serve unconstrained portfolio views across all registered data hubs regardless of which workspace directory the server was launched from.
34
+ - **Slug Normalization**: Removed redundant `slug` field from `ProjectDescriptor`, manifests, and storage adapters in favor of canonical case-remembering `code`.
35
+
36
+ ## [0.1.7] - 2026-09-11
37
+
38
+ ### Added
39
+ - **Case-Remembering Project Resolution**: Preserves canonical casing for project codes up to 8 characters on disk and manifests while supporting case-insensitive lookups across CLI, MCP, and REST endpoints.
40
+ - **Workspaceless & Multi-Hub Project Init**: `ese init --project <Code> [--hub <name|path>]` creates projects directly in configured hubs without overwriting existing workspace configurations.
41
+
42
+ ## [0.1.6] - 2026-09-10
43
+
44
+ ### Added
45
+ - **Multi-Manifest Detection in `ese init`**: Auto-detects project codes and names from `Cargo.toml`, `pyproject.toml`, `settings.gradle.kts`, `app/build.gradle.kts`, and `go.mod`.
46
+ - **Global Port Settings**: Centralized port configuration in `~/.esedre/config.json` with CLI overrides and workspace inheritance.
47
+ - **Agent Project Allow-List Isolation**: Multi-tenant workspace scoping strictly limiting CLI and MCP access to declared `allowedProjects`.
48
+
49
+ ## [0.1.5] - 2026-09-09
50
+
51
+ ### Added
52
+ - **Interactive Web UI Assets & Previews**: Standalone React 19 web dashboard assets, dark and light preview cards, and documentation guides.
53
+
54
+ ## [0.1.4] - 2026-09-08
55
+
56
+ ### Added
57
+ - **MPL-2.0 License Transition**: Open source licensing under Mozilla Public License 2.0.
58
+ - **LLM Agent Long-Term Grounding Mission**: Formalized ground-truth architecture providing persistent context across compaction events.
59
+
60
+ ## [0.1.1] - 2026-09-08
61
+
62
+ ### Added
63
+ - **Project Onboarding & Configuration Tools**: Initial interactive setup via `ese configure` and `ese init`.
64
+
65
+ ## [0.1.0] - 2026-09-08
66
+
67
+ ### Added
68
+ - Initial release of the Esedre ticketing engine, CLI (`ese` / `esedre`), background daemon, and Model Context Protocol (MCP) server.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-blue.svg)](LICENSE)
10
10
  [![Tests](https://img.shields.io/badge/Tests-100%25%20Passing-emerald.svg)](tests/)
11
- [![Website: www.arwam.com](https://img.shields.io/badge/Website-www.arwam.com-cyan.svg)](https://www.arwam.com)
11
+ [![Website: arwam.com](https://img.shields.io/badge/Website-arwam.com-cyan.svg)](https://arwam.com)
12
12
 
13
13
  ---
14
14
 
@@ -115,10 +115,10 @@ Core day-to-day workflow commands for scoping, viewing, planning, and verifying
115
115
  | `list` | `ese list [-p\|--project <code\|all>] [-s\|--status <status>] [-t\|--type <type>] [--json]` | List roadmap tickets with optional filters. Defaults to the active project. |
116
116
  | `get` | `ese get <id> [--json]` | View ticket specifications, feature breakdown, comments, and SHA-1 hash. |
117
117
  | `plan` | `ese plan <id> [--set "<markdown>"] [--file <path>] [--last-hash <h>]` | Read or update the active implementation plan markdown. |
118
- | `create` | `ese create --title "..." [-p\|--project <code>] [-t\|--type <type>]` | Create a new ticket with auto-sequential ID. Title strictly capped at 48 chars. |
118
+ | `create` | `ese create --title "..." [-p\|--project <code>] [-t\|--type <type>] [--detail "<md>"] [--file <path>]` | Create a new ticket with auto-sequential ID and optional specification markdown. Title strictly capped at 48 chars. |
119
119
  | `update` | `ese update <id> [-s\|--status <status>] [-t\|--type <type>] [--title "..."] [--last-hash <h>]` | Update ticket status, type, or title with optimistic concurrency protection. |
120
120
  | `comment` | `ese comment <id> ["<text>"] [--text "..."] [--author "..."]` | Append a developer or LLM agent note to ticket history. |
121
- | `snapshot` | `ese snapshot [--project <code>] [--json]` | Generate lean projection `.esedre/snapshot.json` for zero-latency agent context. |
121
+ | `snapshot`, `refresh` | `ese snapshot [--project <code>] [--json]` | Generate or refresh projection `.esedre/snapshot.json` for zero-latency agent context. |
122
122
  | `projects` | `ese projects [--json]` | List registered projects within authorized scope. |
123
123
 
124
124
  ### Service Daemon Commands
@@ -186,7 +186,7 @@ To connect Esedre to **Google Antigravity**, **Claude Code**, **Cursor**, or any
186
186
  - `esedre_list_tickets`: List tickets with optional project, status, category, or search filter.
187
187
  - `esedre_get_ticket`: Retrieve full specification, summary, comments, revision, and content hash (`sha1`).
188
188
  - `esedre_get_plan` & `esedre_save_plan`: Inspect and update implementation plans with optimistic concurrency (`lastHash`).
189
- - `esedre_create_ticket`: Mint new roadmap tickets with project code validation (up to 8 chars).
189
+ - `esedre_create_ticket`: Mint new roadmap tickets with project code validation (up to 8 chars) and optional specification detail markdown.
190
190
  - `esedre_update_ticket`: Modify status, title, complexity, or effort with optimistic concurrency (`lastHash`).
191
191
  - `esedre_add_comment`: Append developer or LLM agent verification notes.
192
192
 
@@ -281,6 +281,7 @@ npm run build
281
281
 
282
282
  ---
283
283
 
284
- ## 📄 License
284
+ ## 📄 License & Changelog
285
285
 
286
- [Mozilla Public License 2.0 (MPL-2.0)](LICENSE) © [ARWAM](https://www.arwam.com)
286
+ - **License**: [Mozilla Public License 2.0 (MPL-2.0)](LICENSE) © [ARWAM](https://arwam.com)
287
+ - **Changelog**: See [CHANGELOG.md](CHANGELOG.md) for detailed release notes and version history.
package/dist/esedre.mjs CHANGED
@@ -9,7 +9,7 @@ import fs3 from "node:fs";
9
9
  import path3 from "node:path";
10
10
 
11
11
  // src/types.ts
12
- var CURRENT_ESEDRE_VERSION = "0.1.8";
12
+ var CURRENT_ESEDRE_VERSION = "0.1.10";
13
13
  var EsedreConflictError = class extends Error {
14
14
  constructor(ticketId, currentHash, lastHash) {
15
15
  super(
@@ -1428,7 +1428,62 @@ ${formattedList}`
1428
1428
  projectId: targetLoc.project.id,
1429
1429
  project: targetLoc.project.code
1430
1430
  };
1431
- const detailMd = `# Ticket #${nextId}: ${meta.title}
1431
+ const rawDetail = (input.detailMarkdown || input.detail)?.trim();
1432
+ let detailMd;
1433
+ if (rawDetail) {
1434
+ if (/^#\s+[^\n]+/m.test(rawDetail)) {
1435
+ let processed = rawDetail.replace(/^#\s+[^\n]+/m, `# Ticket #${nextId}: ${meta.title}`);
1436
+ if (!/\*\*(?:Type|Category)\*\*:/i.test(processed)) {
1437
+ const metaBlock = `
1438
+ **Category**: ${meta.category}
1439
+ **Complexity**: ${meta.complexity}
1440
+ **Estimated Effort**: ${meta.estimatedEffort}
1441
+ `;
1442
+ processed = processed.replace(/^(# Ticket[^\n]+\n)/m, `$1${metaBlock}`);
1443
+ }
1444
+ if (!/(?:##|###)\s*(?:Summary|Rationale)/i.test(processed)) {
1445
+ const summaryBlock = `
1446
+ ### Summary
1447
+ ${input.summary || "Summary to be defined."}
1448
+ `;
1449
+ processed = processed.replace(/^((?:# Ticket[^\n]+\n)(?:\*\*[^\n]+\n)*)/m, `$1${summaryBlock}`);
1450
+ }
1451
+ detailMd = processed.endsWith("\n") ? processed : `${processed}
1452
+ `;
1453
+ } else {
1454
+ const hasSummary = /(?:##|###)\s*(?:Summary|Rationale)/i.test(rawDetail);
1455
+ const hasBreakdown = /(?:##|###)\s*Feature Breakdown/i.test(rawDetail);
1456
+ let body = "";
1457
+ if (!hasSummary) {
1458
+ body += `### Summary
1459
+ ${input.summary || "Summary to be defined."}
1460
+
1461
+ `;
1462
+ }
1463
+ if (!hasBreakdown && !rawDetail.startsWith("#")) {
1464
+ body += `### Feature Breakdown
1465
+ ${rawDetail}
1466
+
1467
+ ### Technical Details & Architecture
1468
+ - Architecture specifications to be documented.
1469
+
1470
+ ### Open Questions & Decisions
1471
+ - None recorded at initialization.
1472
+ `;
1473
+ } else {
1474
+ body += `${rawDetail}
1475
+ `;
1476
+ }
1477
+ detailMd = `# Ticket #${nextId}: ${meta.title}
1478
+ **Category**: ${meta.category}
1479
+ **Complexity**: ${meta.complexity}
1480
+ **Estimated Effort**: ${meta.estimatedEffort}
1481
+
1482
+ ${body.trim()}
1483
+ `;
1484
+ }
1485
+ } else {
1486
+ detailMd = `# Ticket #${nextId}: ${meta.title}
1432
1487
  **Category**: ${meta.category}
1433
1488
  **Complexity**: ${meta.complexity}
1434
1489
  **Estimated Effort**: ${meta.estimatedEffort}
@@ -1446,6 +1501,7 @@ ${input.summary || "Summary to be defined."}
1446
1501
  ### Open Questions & Decisions
1447
1502
  - None recorded at initialization.
1448
1503
  `;
1504
+ }
1449
1505
  writeSafeFile(path3.join(ticketDir, "meta.json"), JSON.stringify(meta, null, 2) + "\n");
1450
1506
  writeSafeFile(path3.join(ticketDir, "detail.md"), detailMd);
1451
1507
  const created = await this.getTicket(`${targetLoc.project.code}-${nextId}`);
@@ -2066,6 +2122,7 @@ Status: ${ticket.meta.status}`;
2066
2122
  complexity: { type: "string", description: "Complexity (e.g. Low, Medium, High)" },
2067
2123
  effort: { type: "string", description: "Estimated effort (e.g. 2.0 - 4.0 hours)" },
2068
2124
  summary: { type: "string", description: "Initial feature summary" },
2125
+ detail: { type: "string", description: "Initial specification, feature breakdown, or technical detail markdown" },
2069
2126
  author: { type: "string", description: "Submitting author name" }
2070
2127
  },
2071
2128
  required: ["title"]
@@ -2156,6 +2213,8 @@ Status: ${ticket.meta.status}`;
2156
2213
  complexity: args.complexity,
2157
2214
  estimatedEffort: args.effort,
2158
2215
  summary: args.summary,
2216
+ detail: args.detail || args.detailMarkdown,
2217
+ detailMarkdown: args.detailMarkdown || args.detail,
2159
2218
  submittedBy: args.author || "Agent"
2160
2219
  });
2161
2220
  return created;
@@ -2770,33 +2829,44 @@ function classifyContent(currentContent, latestTemplate, historicHashes) {
2770
2829
  var WRAPPER_CMD = `@echo off
2771
2830
  REM Esedre Autonomous Ticketing & Project Planning Engine Wrapper (Windows CMD)
2772
2831
  setlocal
2832
+
2773
2833
  where ese >nul 2>nul
2774
- if %ERRORLEVEL% equ 0 (
2775
- ese %*
2776
- goto :done
2777
- )
2834
+ if %ERRORLEVEL% equ 0 goto use_ese
2835
+
2778
2836
  where esedre >nul 2>nul
2779
- if %ERRORLEVEL% equ 0 (
2780
- esedre %*
2781
- goto :done
2782
- )
2783
- if exist "%~dp0..\\..\\esedre\\dist\\esedre.mjs" (
2784
- node "%~dp0..\\..\\esedre\\dist\\esedre.mjs" %*
2785
- goto :done
2786
- )
2787
- if exist "%~dp0..\\esedre\\dist\\esedre.mjs" (
2788
- node "%~dp0..\\esedre\\dist\\esedre.mjs" %*
2789
- goto :done
2790
- )
2791
- if exist "%~dp0..\\node_modules\\.bin\\ese.cmd" (
2792
- call "%~dp0..\\node_modules\\.bin\\ese.cmd" %*
2793
- goto :done
2794
- )
2795
- if exist "%~dp0..\\node_modules\\.bin\\esedre.cmd" (
2796
- call "%~dp0..\\node_modules\\.bin\\esedre.cmd" %*
2797
- goto :done
2798
- )
2799
- npx --yes esedre %*
2837
+ if %ERRORLEVEL% equ 0 goto use_esedre
2838
+
2839
+ if exist "%~dp0..\\..\\esedre\\dist\\esedre.mjs" goto use_sibling_dist
2840
+ if exist "%~dp0..\\esedre\\dist\\esedre.mjs" goto use_local_dist
2841
+ if exist "%~dp0..\\node_modules\\.bin\\ese.cmd" goto use_node_modules_ese
2842
+ if exist "%~dp0..\\node_modules\\.bin\\esedre.cmd" goto use_node_modules_esedre
2843
+
2844
+ call npx --yes esedre %*
2845
+ goto done
2846
+
2847
+ :use_ese
2848
+ call ese %*
2849
+ goto done
2850
+
2851
+ :use_esedre
2852
+ call esedre %*
2853
+ goto done
2854
+
2855
+ :use_sibling_dist
2856
+ node "%~dp0..\\..\\esedre\\dist\\esedre.mjs" %*
2857
+ goto done
2858
+
2859
+ :use_local_dist
2860
+ node "%~dp0..\\esedre\\dist\\esedre.mjs" %*
2861
+ goto done
2862
+
2863
+ :use_node_modules_ese
2864
+ call "%~dp0..\\node_modules\\.bin\\ese.cmd" %*
2865
+ goto done
2866
+
2867
+ :use_node_modules_esedre
2868
+ call "%~dp0..\\node_modules\\.bin\\esedre.cmd" %*
2869
+ goto done
2800
2870
 
2801
2871
  :done
2802
2872
  endlocal
@@ -2804,6 +2874,14 @@ exit /b %ERRORLEVEL%
2804
2874
  `;
2805
2875
  var WRAPPER_PS1 = `# Esedre Autonomous Ticketing & Project Planning Engine Wrapper (PowerShell)
2806
2876
  $ErrorActionPreference = "Stop"
2877
+
2878
+ # Ensure UTF-8 console output and pipeline encoding on Windows
2879
+ try {
2880
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
2881
+ [Console]::InputEncoding = [System.Text.Encoding]::UTF8
2882
+ $OutputEncoding = [System.Text.Encoding]::UTF8
2883
+ } catch {}
2884
+
2807
2885
  $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
2808
2886
 
2809
2887
  if (Get-Command "ese" -ErrorAction SilentlyContinue) {
@@ -2865,8 +2943,15 @@ exec npx --yes esedre "$@"
2865
2943
  var ESE_WRAPPER_CMD = `@echo off
2866
2944
  REM Ese CLI short alias wrapper for Esedre (Windows CMD)
2867
2945
  call "%~dp0esedre.cmd" %*
2946
+ exit /b %ERRORLEVEL%
2868
2947
  `;
2869
2948
  var ESE_WRAPPER_PS1 = `# Ese CLI short alias wrapper for Esedre (PowerShell)
2949
+ try {
2950
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
2951
+ [Console]::InputEncoding = [System.Text.Encoding]::UTF8
2952
+ $OutputEncoding = [System.Text.Encoding]::UTF8
2953
+ } catch {}
2954
+
2870
2955
  $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
2871
2956
  & (Join-Path $scriptDir "esedre.ps1") @args
2872
2957
  exit $LASTEXITCODE
@@ -2878,7 +2963,9 @@ exec "$DIR/esedre" "$@"
2878
2963
  `;
2879
2964
  var HISTORIC_SKILL_HASHES = [
2880
2965
  "8611116c276fdfb598b965c716b251ce7c77c7f7",
2881
- "05f129fb6e06a18df00215af105567abcbf0bc67"
2966
+ "05f129fb6e06a18df00215af105567abcbf0bc67",
2967
+ "5d330ecf8fc96f383946e0351adb60378afa70f0",
2968
+ "23716c9db561e52e5115dc364fe154d3a7bc1e23"
2882
2969
  ];
2883
2970
  var ESEDRE_SKILL_TEMPLATE = `---
2884
2971
  name: esedre
@@ -2889,9 +2976,18 @@ description: Tooling and workflow reference for interacting with the Esedre deve
2889
2976
 
2890
2977
  Esedre is the developer ticketing and LLM coding partner coordination platform. The engine codebase resides in the standalone repository \`aellinsar/esedre\` (\`../esedre\`), and operates on decoupled ticket repositories (such as \`aellinsar/esedre-data\` configured in \`.esedre/esedre.json\`). Interact with tickets via in-repo shell wrappers in \`.esedre/\` (\`.esedre/ese\`), or the global \`ese\` CLI.
2891
2978
 
2892
- ## 0. Instant Zero-Latency Context (\`.esedre/snapshot.json\`)
2979
+ ## 0. Authoritative Ingress Hierarchy & Zero-Latency Context (\`.esedre/snapshot.json\`)
2893
2980
 
2894
- Before querying tickets over the network or CLI, check \`.esedre/snapshot.json\` in the workspace root. It provides a local read-only projection containing all active and completed tickets, summaries, implementation plans, revision numbers, completion dates (\`completedAt\`), and staleness metrics (\`daysSinceUpdate\`).
2981
+ All ticket discovery, inspection, and state management strictly follow this positive ingress hierarchy:
2982
+
2983
+ 1. **Step 1 (Default for Read-Only Inspection) - Local Snapshot Projection**:
2984
+ Always read \`.esedre/snapshot.json\` in the workspace root first. It provides an immediate, zero-latency local projection containing all active and completed tickets, summaries, implementation plans, revision numbers, completion dates (\`completedAt\`), and staleness metrics (\`daysSinceUpdate\`).
2985
+ 2. **Step 2 (Dynamic Queries & State Mutations) - Esedre MCP Tools**:
2986
+ Use first-class MCP tools when active in the session (\`esedre_list_tickets\`, \`esedre_get_ticket\`, \`esedre_get_plan\`, \`esedre_save_plan\`, \`esedre_update_ticket\`, \`esedre_add_comment\`).
2987
+ 3. **Step 3 (Terminal & Script Fallback) - In-Repo CLI Wrapper**:
2988
+ Use \`.esedre/ese\` (\`.esedre/ese get\`, \`.esedre/ese plan\`, \`.esedre/ese update\`, \`.esedre/ese snapshot\`, \`.esedre/ese refresh\`).
2989
+ 4. **Storage Boundary**:
2990
+ Backing ticket hubs (such as \`esedre-data\`) represent data storage managed by the engine. All agent interactions with roadmap tickets flow through the snapshot projection, MCP tools, or CLI wrappers.
2895
2991
 
2896
2992
  ## 1. Model Context Protocol (MCP) Tools
2897
2993
 
@@ -2903,7 +2999,7 @@ When Esedre MCP is active in your agent session (\`.agents/mcp_config.json\`), u
2903
2999
  | \`esedre_get_ticket\` | Full specification, summary, comments, revision & sha1 | \`ticketId\` (numeric e.g. \`96\` or compound e.g. \`Profe-96\`) |
2904
3000
  | \`esedre_get_plan\` | Active implementation plan markdown | \`ticketId\` (numeric or compound) |
2905
3001
  | \`esedre_save_plan\` | Save implementation plan markdown with OCC | \`ticketId\`, \`planMarkdown\`, \`lastHash\` |
2906
- | \`esedre_create_ticket\` | Mint a new ticket with auto sequential ID | \`title\` (max 48 chars), \`type\`, \`project\`, \`effort\`, \`summary\` |
3002
+ | \`esedre_create_ticket\` | Mint a new ticket with auto sequential ID | \`title\` (max 48 chars), \`type\`, \`project\`, \`effort\`, \`summary\`, \`detail\` |
2907
3003
  | \`esedre_update_ticket\` | Update ticket attributes with OCC | \`ticketId\`, \`status\`, \`type\`, \`title\`, \`complexity\`, \`effort\`, \`inDevelopment\`, \`featureFlag\`, \`lastHash\` |
2908
3004
  | \`esedre_add_comment\` | Append developer or agent comment | \`ticketId\`, \`text\`, \`author\` |
2909
3005
 
@@ -2930,7 +3026,7 @@ Both \`esedre\` and \`ese\` work interchangeably:
2930
3026
 
2931
3027
  ### Create a Ticket
2932
3028
  \`\`\`bash
2933
- .esedre/ese create --title "..." [-p|--project <code>] [-t|--type Feature] [--complexity Medium] [--effort "2.0 - 4.0 hours"] [--json]
3029
+ .esedre/ese create --title "..." [-p|--project <code>] [-t|--type Feature] [--complexity Medium] [--effort "2.0 - 4.0 hours"] [--detail "<md>"] [--file <path>] [--json]
2934
3030
  \`\`\`
2935
3031
 
2936
3032
  ### Update Ticket Status & Attributes
@@ -2949,6 +3045,7 @@ Both \`esedre\` and \`ese\` work interchangeably:
2949
3045
  ### Regenerate Snapshot
2950
3046
  \`\`\`bash
2951
3047
  .esedre/ese snapshot
3048
+ .esedre/ese refresh
2952
3049
  \`\`\`
2953
3050
 
2954
3051
  ### Server Lifecycle & Daemon Management
@@ -3300,6 +3397,18 @@ function configureWorkspace(targetDir, options = {}) {
3300
3397
  };
3301
3398
  }
3302
3399
  var initWorkspace = configureWorkspace;
3400
+ var ESEDRE_HUB_AGENTS_TEMPLATE = `# Agent Guidelines: esedre-data
3401
+
3402
+ ## 1. Role & Storage Boundary
3403
+ - **Backing Storage Repository**: \`esedre-data\` is a dedicated, decoupled data hub storing raw tickets, metadata manifests, and implementation plans managed by the Esedre engine.
3404
+ - **Authorized Ingress Channels**: Ticket discovery, read-only inspection, status updates, and plan authoring strictly ingress through the Esedre application layer in consuming project workspaces:
3405
+ 1. **Local Workspace Snapshot**: Check the consuming workspace's \`.esedre/snapshot.json\` first for instant, zero-latency read access to ticket summaries, plans, and statuses.
3406
+ 2. **Esedre MCP Tools**: Use \`esedre_get_ticket\`, \`esedre_list_tickets\`, \`esedre_get_plan\`, \`esedre_save_plan\`, and \`esedre_update_ticket\`.
3407
+ 3. **Esedre CLI**: Execute \`.esedre/ese get <id>\`, \`.esedre/ese list\`, or \`.esedre/ese plan\` from within the relevant project workspace.
3408
+
3409
+ ## 2. Ingress Redirection Protocol
3410
+ When inspecting or managing tickets for any project (such as \`Profe\`, \`Esedre\`, or \`Alce\`), navigate to that project's workspace and utilize its local \`.esedre/snapshot.json\`, Esedre MCP tools, or \`.esedre/ese\` CLI wrapper.
3411
+ `;
3303
3412
  function initHub(targetDir) {
3304
3413
  const resolved = path6.resolve(targetDir);
3305
3414
  if (!fs6.existsSync(resolved)) {
@@ -3317,9 +3426,16 @@ function initHub(targetDir) {
3317
3426
  fs6.writeFileSync(projectsJsonPath, "[]\n", "utf-8");
3318
3427
  projectsJsonCreated = true;
3319
3428
  }
3429
+ const agentsMdPath = path6.join(resolved, "AGENTS.md");
3430
+ let agentsMdCreated = false;
3431
+ if (!fs6.existsSync(agentsMdPath)) {
3432
+ fs6.writeFileSync(agentsMdPath, ESEDRE_HUB_AGENTS_TEMPLATE, "utf-8");
3433
+ agentsMdCreated = true;
3434
+ }
3320
3435
  return {
3321
3436
  projectsJsonCreated,
3322
3437
  projectsDirCreated,
3438
+ agentsMdCreated,
3323
3439
  hubDir: resolved.replace(/\\/g, "/")
3324
3440
  };
3325
3441
  }
@@ -3885,7 +4001,7 @@ ${colors.bold}ROADMAP COMMANDS (Pair Programming & LLM Agents):${colors.reset}
3885
4001
  ${colors.bold}plan${colors.reset} <id> [--file <path> | --set "<markdown>"] [--last-hash <sha1>] [--json]
3886
4002
  View or update implementation plan with optimistic concurrency control.
3887
4003
 
3888
- ${colors.bold}create${colors.reset} --title "..." [-p|--project <code>] [-t|--type <type>] [--complexity <c>] [--effort "<e>"] [--summary "<s>"] [--json]
4004
+ ${colors.bold}create${colors.reset} --title "..." [-p|--project <code>] [-t|--type <type>] [--complexity <c>] [--effort "<e>"] [--summary "<s>"] [--detail "<md>"] [--file <path>] [--json]
3889
4005
  Mint a new roadmap ticket with sequential numeric ID.
3890
4006
 
3891
4007
  ${colors.bold}update${colors.reset} <id> [-s|--status <status>] [-t|--type <type>] [--title "..."] [--complexity <c>] [--effort "<e>"] [--in-dev] [--flag <name>] [--last-hash <sha1>] [--force] [--json]
@@ -3894,7 +4010,7 @@ ${colors.bold}ROADMAP COMMANDS (Pair Programming & LLM Agents):${colors.reset}
3894
4010
  ${colors.bold}comment${colors.reset} <id> ["<text>"] [--text "..."] [--author "..."] [--json]
3895
4011
  Append a research finding, test verification, or note to ticket history.
3896
4012
 
3897
- ${colors.bold}snapshot${colors.reset} [--project <code>] [--json]
4013
+ ${colors.bold}snapshot, refresh${colors.reset} [--project <code>] [--json]
3898
4014
  Generate lean read-only projection snapshot (.esedre/snapshot.json) for zero-latency agent context.
3899
4015
 
3900
4016
  ${colors.bold}SERVICE DAEMON COMMANDS:${colors.reset}
@@ -3938,6 +4054,8 @@ ${colors.bold}OPTIONS:${colors.reset}
3938
4054
  -t, --type <type> Ticket type ('Feature', 'Platform', 'Tools', 'Idea', 'Bug').
3939
4055
  -s, --status <stat> Ticket status ('Planned', 'In Development', 'Completed', 'Rejected').
3940
4056
  -q, --search <query> Case-insensitive substring search query.
4057
+ --detail "<md>" Specification markdown for ticket detail during create.
4058
+ --file <path> Path to markdown file for detail (create) or implementation plan (plan).
3941
4059
  --json Output raw machine-readable JSON (strongly recommended for autonomous LLM coding agents).
3942
4060
  --last-hash <hash> Optimistic concurrency control: last known sha1 hash of the ticket from 'get'.
3943
4061
  --force Bypass optimistic concurrency last-hash conflict checks on writes.
@@ -4450,6 +4568,7 @@ ${colors.bold}Commands:${colors.reset}`);
4450
4568
  }
4451
4569
  return;
4452
4570
  }
4571
+ case "refresh":
4453
4572
  case "snapshot": {
4454
4573
  const projectCode = flags["project"] || discovered.config?.projectCode;
4455
4574
  if (!projectCode) {
@@ -4656,12 +4775,27 @@ ${colors.dim}Total: ${tickets.length} tickets${colors.reset}`);
4656
4775
  content = fs9.readFileSync(filePath, "utf-8");
4657
4776
  }
4658
4777
  await storage.savePlan(id, content, lastHash);
4659
- console.log(`${colors.green}\u2714 Implementation plan saved for Ticket #${id}${colors.reset}`);
4778
+ if (isJson) {
4779
+ const updated = await storage.getTicket(id);
4780
+ console.log(JSON.stringify({
4781
+ success: true,
4782
+ ticketId: id,
4783
+ project: updated?.projectDescriptor?.code || updated?.meta?.project || "UNASSIGNED",
4784
+ planMarkdown: content,
4785
+ sha1: updated?.sha1 || updated?.meta?.sha1
4786
+ }, null, 2));
4787
+ } else {
4788
+ console.log(`${colors.green}\u2714 Implementation plan saved for Ticket #${id}${colors.reset}`);
4789
+ }
4660
4790
  return;
4661
4791
  }
4662
4792
  const plan = await storage.getPlan(id);
4663
4793
  if (!plan) {
4664
- console.log(`${colors.dim}No implementation plan found for Ticket #${id}.${colors.reset}`);
4794
+ if (isJson) {
4795
+ console.log(JSON.stringify({ ticketId: id, planMarkdown: null }, null, 2));
4796
+ } else {
4797
+ console.log(`${colors.dim}No implementation plan found for Ticket #${id}.${colors.reset}`);
4798
+ }
4665
4799
  return;
4666
4800
  }
4667
4801
  if (isJson) {
@@ -4694,6 +4828,21 @@ ${colors.dim}Total: ${tickets.length} tickets${colors.reset}`);
4694
4828
  console.error(`${colors.red}Error: ${val.error}${colors.reset}`);
4695
4829
  process.exit(1);
4696
4830
  }
4831
+ const detailArg = flags["detail"];
4832
+ const fileArg = flags["file"];
4833
+ let detailMarkdown = detailArg;
4834
+ if (fileArg) {
4835
+ const filePath = path9.resolve(fileArg);
4836
+ if (!fs9.existsSync(filePath)) {
4837
+ if (isJson) {
4838
+ console.error(JSON.stringify({ error: `Detail file "${fileArg}" not found` }));
4839
+ } else {
4840
+ console.error(`${colors.red}Error: Detail file "${fileArg}" not found.${colors.reset}`);
4841
+ }
4842
+ process.exit(1);
4843
+ }
4844
+ detailMarkdown = fs9.readFileSync(filePath, "utf-8");
4845
+ }
4697
4846
  const created = await storage.createTicket({
4698
4847
  title,
4699
4848
  type,
@@ -4702,7 +4851,9 @@ ${colors.dim}Total: ${tickets.length} tickets${colors.reset}`);
4702
4851
  complexity,
4703
4852
  estimatedEffort,
4704
4853
  summary,
4705
- submittedBy
4854
+ submittedBy,
4855
+ detail: detailMarkdown,
4856
+ detailMarkdown
4706
4857
  });
4707
4858
  if (isJson) {
4708
4859
  console.log(JSON.stringify(created, null, 2));
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "esedre",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Esedre: Developer roadmap, ticketing, and LLM coding partner coordination platform",
5
- "homepage": "https://www.arwam.com",
5
+ "homepage": "https://arwam.com",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/Aellinsar/esedre.git"
@@ -27,6 +27,7 @@
27
27
  "files": [
28
28
  "dist",
29
29
  "README.md",
30
+ "CHANGELOG.md",
30
31
  "LICENSE",
31
32
  "docs/assets"
32
33
  ],