@jetrabbits/agentic 0.3.0 → 0.3.1

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/AGENTS.md CHANGED
@@ -16,12 +16,19 @@ project_dir/
16
16
  └── prompts/
17
17
  ```
18
18
 
19
+ ## Guidance chain
20
+
21
+ 1. Project `.agent/` baseline
22
+ 2. `.agent/rules/*` — load all
23
+ 3. `.agent/skills/*/SKILL.md` — load only the skill matching the current task
24
+ 4. `.agent/workflows/*` — load the workflow matching the triggered command
25
+
19
26
  **Discovery patterns:**
20
27
 
21
- - `project_dir/.agent/rules/*`
22
- - `project_dir/.agent/skills/*`
23
- - `project_dir/.agent/workflows/*`
24
- - `project_dir/.agent/prompts/*`
28
+ - `.agent/rules/*.md`
29
+ - `.agent/skills/*/SKILL.md`
30
+ - `.agent/workflows/*.md`
31
+ - `.agent/prompts/*.md`
25
32
 
26
33
  Prefer relative paths in references inside markdown files.
27
34
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.1
4
+
5
+ - Added project-level OpenCode plugin settings in `.agentic.json`, including Telegram `botToken` and `chatId` when `telegram-notification` is enabled.
6
+ - Renamed the OpenCode optional plugin menu entry to `telegram-notification` while preserving the old `telegram-opencode-notifier` alias for compatibility.
7
+ - Changed `telegram-notification` runtime credentials to read from the target project's `.agentic.json` instead of Telegram environment variables.
8
+ - Removed Telegram message formatting entirely: notifications are sent as plain text without `parse_mode`, MarkdownV2 escaping, or markdown-to-Telegram conversion.
9
+ - Added interactive Context7 key mode selection with English menu entries for keyless setup or entering `CONTEXT7_API_KEY`.
10
+ - Removed the post-install Context7 "add API key later" path/example guidance because key selection now happens during setup.
11
+ - Extended `agent-model-mapper` model discovery to include active providers from `~/.local/share/opencode/auth.json` and non-deprecated models from `~/.cache/opencode/models.json`.
12
+ - Added a Confirm/Cancel save step after OpenCode role model selection before writing `.opencode/opencode.json`.
13
+ - Preserved OpenCode plugin settings across manifest replay/re-install so automated sync does not prompt again or lose project-level credentials.
14
+ - Updated OpenCode, Context7, Telegram, and lifecycle docs plus deterministic e2e coverage for the new configuration flow.
15
+
3
16
  ## v0.3.0
4
17
 
5
18
  - Added per-agent doctor timeouts with elapsed-time and exit-status logging while keeping install non-fatal.
package/MEMORY.md CHANGED
@@ -1,113 +1,67 @@
1
1
  # MEMORY — MCP context providers
2
2
 
3
- Guidance for using MemPalace and Context7 MCP servers across all agent sessions.
4
-
5
- ---
6
-
7
- ## Provider roles
8
-
9
- | Provider | Purpose |
10
- |---|---|
11
- | **MemPalace** | Project-specific knowledge: architecture decisions, domain rules, conventions, known issues, integration contracts |
12
- | **Context7** | Framework, library, SDK, and API reference documentation |
13
-
14
- Use both when available. They are complementary, not interchangeable.
15
-
16
- ---
3
+ Use MCP context only when it improves accuracy. Keep searches narrow.
17
4
 
18
5
  ## Context7
19
6
 
20
- - Use Context7 for framework, library, SDK, API, and setup documentation before relying on model memory.
21
- - Resolve the library or framework identity first, then request focused docs for the exact task and version when version matters.
22
- - If Context7 is unavailable, state that explicitly and fall back to local docs or official project documentation.
23
-
24
- ---
7
+ - Use Context7 for external framework, library, SDK, API, and setup docs.
8
+ - Resolve the exact package/framework first; ask for focused docs only.
9
+ - If Context7 is unavailable, use local `docs/**`, then official upstream docs.
25
10
 
26
11
  ## MemPalace
27
12
 
28
- ### Loading context session start
29
-
30
- Query MemPalace **before** reading any source files. Orientation queries to run at the start of every session:
13
+ MemPalace stores project memory by wing. The current project wing is the sanitized project directory basename. Cross-project Markdown knowledge belongs in `shared_docs`.
31
14
 
32
- ```
33
- mempalace_search({ "query": "project architecture decisions" })
34
- mempalace_search({ "query": "domain entities and relationships" })
35
- mempalace_search({ "query": "known constraints and non-negotiables" })
36
- ```
15
+ ### Cheap search pattern
37
16
 
38
- Before touching any subsystem, query for accumulated knowledge about it:
17
+ Do not run broad startup searches. Search only for the task at hand:
39
18
 
40
- ```
41
- mempalace_search({ "query": "<module or service name> design decisions" })
42
- mempalace_search({ "query": "<module or service name> known issues" })
19
+ ```json
20
+ mempalace_search({
21
+ "query": "short exact keywords",
22
+ "wing": "<current_project_wing>",
23
+ "limit": 3,
24
+ "max_distance": 0.55
25
+ })
43
26
  ```
44
27
 
45
- ### Writing facts — when to store
28
+ Rules:
46
29
 
47
- Store a fact **immediately** when you discover or confirm any of the following. Do not wait until the end of the session — subsequent steps in the same session benefit from facts stored earlier.
30
+ - Keep `query` short; put background in `context` only if needed.
31
+ - Use `wing` whenever you know it.
32
+ - Use `limit: 3` by default; raise it only when evidence is thin.
33
+ - Use `max_distance` around `0.4-0.6` for precise fact lookup.
34
+ - Search `shared_docs` only for reusable docs or cross-project behavior.
35
+ - Call `mempalace_list_wings` or `mempalace_list_rooms` only when the wing or room is unknown.
36
+ - Add `room` only after confirming the room name.
48
37
 
49
- | Trigger | What to store |
50
- |---|---|
51
- | Architecture decision made or confirmed | Decision, alternatives considered, rationale |
52
- | Non-obvious module dependency or integration point | What connects to what and why |
53
- | Business rule or domain constraint clarified | The rule in plain language, where it is enforced |
54
- | Recurring bug pattern or root cause identified | Pattern description, affected area, mitigation |
55
- | API contract or data shape locked down | Shape, version, owning service |
56
- | Performance characteristic or known bottleneck noted | Where, measured or estimated, relevant thresholds |
57
- | Convention or team agreement not captured in docs | The agreement and its scope |
58
- | Environment or deployment constraint discovered | What the constraint is and which target it affects |
38
+ ### Writing facts
59
39
 
60
- ### Writing facts examples
40
+ Use `mempalace_store` proactively when a durable fact is discovered, decided, or corrected. Do not wait for a later search to make project knowledge persistent.
61
41
 
62
- ```
63
- mempalace_store({
64
- "type": "architecture_decision",
65
- "title": "Auth uses JWT with 15-min expiry, refresh via Redis",
66
- "body": "Decided in task TASK-88. Rationale: stateless verification at API gateway; Redis holds refresh token allowlist for revocation support.",
67
- "tags": ["auth", "jwt", "redis", "architecture"]
68
- })
69
- ```
42
+ Store only durable, self-contained facts:
70
43
 
71
- ```
72
- mempalace_store({
73
- "type": "domain_rule",
74
- "title": "Orders cannot transition from CANCELLED back to any active state",
75
- "body": "Enforced in OrderStateMachine.apply(). No UI path or API endpoint bypasses this; confirmed with product owner in TASK-102.",
76
- "tags": ["orders", "state-machine", "domain-rule"]
77
- })
78
- ```
44
+ - architecture decisions and rationale;
45
+ - domain rules and API/data contracts;
46
+ - non-obvious integrations or constraints;
47
+ - known issues, bottlenecks, and mitigations;
48
+ - team conventions not already captured in `docs/**`.
79
49
 
80
- ```
81
- mempalace_store({
82
- "type": "known_issue",
83
- "title": "ReportService N+1 on invoice line items — not yet fixed",
84
- "body": "Affects reports with >50 invoices. Tracked in TASK-119. Workaround: batch fetch via InvoiceRepository.findByReportId().",
85
- "tags": ["reporting", "performance", "n+1"]
86
- })
87
- ```
50
+ Store one fact per call, tagged with project/module/domain nouns. Write project facts to the current project wing. Write to `shared_docs` only when the knowledge is intentionally reusable across projects.
88
51
 
89
- ```
52
+ ```json
90
53
  mempalace_store({
91
- "type": "convention",
92
- "title": "Feature flags go through FeatureToggleService — no direct env checks in domain code",
93
- "body": "Established to keep domain layer portable. All flag reads must go through FeatureToggleService.isEnabled(flag, context).",
94
- "tags": ["conventions", "feature-flags"]
54
+ "wing": "<current_project_wing>",
55
+ "room": "<known_room_if_confirmed>",
56
+ "text": "Durable fact stated as a complete sentence with enough context to stand alone.",
57
+ "tags": ["project", "module", "domain"]
95
58
  })
96
59
  ```
97
60
 
98
- ### Quality bar for stored facts
99
-
100
- - **Concrete, not vague.** "Auth uses JWT" is a fact. "Auth is secure" is not.
101
- - **Self-contained.** The fact must make sense without the surrounding chat context.
102
- - **Tagged for retrieval.** Include module names, domain nouns, and problem-type tags.
103
- - **One fact per store call.** Do not bundle multiple unrelated facts into one entry.
104
-
105
- ---
106
-
107
- ## Fallback order
61
+ ## Fallback
108
62
 
109
- When MCP providers are unavailable, fall back in this order:
63
+ If MCP providers are unavailable, use:
110
64
 
111
- 1. Local `docs/**` in the project repository
112
- 2. Official upstream documentation
113
- 3. Model knowledge (least preferred state explicitly when used)
65
+ 1. local `docs/**`;
66
+ 2. official upstream documentation;
67
+ 3. model knowledge, explicitly marked as fallback.
package/Makefile CHANGED
@@ -1,11 +1,30 @@
1
- .PHONY: help install dev test test-cli test-tui test-cross test-doctor test-markers test-opencode-plugins test-telegram-plugin test-real-agent-doctor test-real-blackbox test-real-opencode-mapper test-coverage lint fmt clean build assess-areas
1
+ .PHONY: help install dev test test-all test-cli test-tui test-cross test-doctor test-markers test-opencode-plugins test-telegram-plugin test-ubuntu-blackbox test-real-agent-doctor test-real-blackbox test-real-blackbox-codex test-real-blackbox-opencode test-real-blackbox-telegram test-real-opencode-mapper test-coverage _test-coverage-steps lint fmt clean build assess-areas
2
+
3
+ define timed_step
4
+ @label='$(1)'; \
5
+ start=$$(date +%s); \
6
+ timestamp=$$(date '+%Y-%m-%d %H:%M:%S'); \
7
+ printf '%s [make-timing] START %s\n' "$$timestamp" "$$label"; \
8
+ $(2); \
9
+ status=$$?; \
10
+ end=$$(date +%s); \
11
+ elapsed=$$((end - start)); \
12
+ timestamp=$$(date '+%Y-%m-%d %H:%M:%S'); \
13
+ if [ "$$status" -eq 0 ]; then \
14
+ printf '%s [make-timing] OK %s elapsed=%ss\n' "$$timestamp" "$$label" "$$elapsed"; \
15
+ else \
16
+ printf '%s [make-timing] FAIL %s elapsed=%ss exit=%s\n' "$$timestamp" "$$label" "$$elapsed" "$$status"; \
17
+ fi; \
18
+ exit "$$status"
19
+ endef
2
20
 
3
21
  help:
4
22
  @printf '%s\n' \
5
23
  "Available targets:" \
6
24
  " install Install local development prerequisites" \
7
25
  " dev Show local development entrypoints" \
8
- " test Run end-to-end tests (all groups)" \
26
+ " test Run fast deterministic end-to-end tests" \
27
+ " test-all Run fast tests, real blackbox, and coverage" \
9
28
  " test-cli Run CLI end-to-end tests" \
10
29
  " test-tui Run TUI end-to-end tests" \
11
30
  " test-cross Run cross-mode end-to-end tests" \
@@ -13,8 +32,12 @@ help:
13
32
  " test-markers Run generated marker and idempotency tests" \
14
33
  " test-opencode-plugins Run OpenCode plugin deterministic tests" \
15
34
  " test-telegram-plugin Run Telegram plugin deterministic tests" \
35
+ " test-ubuntu-blackbox Run make test in a clean Docker Ubuntu image" \
16
36
  " test-real-agent-doctor Run real agent doctor checks" \
17
37
  " test-real-blackbox Run real Codex/OpenCode/Telegram blackbox tests" \
38
+ " test-real-blackbox-codex Run real Codex blackbox test" \
39
+ " test-real-blackbox-opencode Run real OpenCode blackbox test" \
40
+ " test-real-blackbox-telegram Run real OpenCode Telegram blackbox test" \
18
41
  " test-real-opencode-mapper Run real OpenCode mapper input blackbox" \
19
42
  " test-coverage Run traced e2e coverage for agentic" \
20
43
  " lint Run prompt and catalog validation" \
@@ -30,48 +53,83 @@ dev:
30
53
  @printf '%s\n' "Use ./agentic tui or ./agentic install ..."
31
54
 
32
55
  test:
33
- bash tests/e2e/cli.e2e.sh
34
- bash tests/e2e/tui.e2e.sh
35
- bash tests/e2e/cross.e2e.sh
36
- bash tests/e2e/doctor.e2e.sh
37
- bash tests/e2e/markers.e2e.sh
38
- bash tests/e2e/opencode_plugins.e2e.sh
39
- bash tests/e2e/telegram_plugin.e2e.sh
40
- bash tests/e2e/real_agent_blackbox.e2e.sh
41
- $(MAKE) test-coverage
56
+ $(call timed_step,test-cli,bash tests/e2e/cli.e2e.sh)
57
+ $(call timed_step,test-tui,bash tests/e2e/tui.e2e.sh)
58
+ $(call timed_step,test-cross,bash tests/e2e/cross.e2e.sh)
59
+ $(call timed_step,test-opencode-plugins,bash tests/e2e/opencode_plugins.e2e.sh)
60
+ $(call timed_step,test-telegram-plugin,bash tests/e2e/telegram_plugin.e2e.sh)
61
+
62
+ test-all:
63
+ $(call timed_step,test,$(MAKE) test)
64
+ $(call timed_step,test-doctor,bash tests/e2e/doctor.e2e.sh)
65
+ $(call timed_step,test-markers,bash tests/e2e/markers.e2e.sh)
66
+ $(call timed_step,test-real-blackbox-codex,AGENTIC_REAL_BLACKBOX_ONLY=codex bash tests/e2e/real_agent_blackbox.e2e.sh)
67
+ $(call timed_step,test-real-blackbox-opencode,AGENTIC_REAL_BLACKBOX_ONLY=opencode bash tests/e2e/real_agent_blackbox.e2e.sh)
68
+ $(call timed_step,test-real-opencode-mapper,AGENTIC_REAL_BLACKBOX_ONLY=opencode-mapper bash tests/e2e/real_agent_blackbox.e2e.sh)
69
+ $(call timed_step,test-real-blackbox-telegram,AGENTIC_REAL_BLACKBOX_ONLY=telegram bash tests/e2e/real_agent_blackbox.e2e.sh)
70
+ $(call timed_step,test-coverage,$(MAKE) test-coverage)
42
71
 
43
72
  test-cli:
44
- bash tests/e2e/cli.e2e.sh
73
+ $(call timed_step,test-cli,bash tests/e2e/cli.e2e.sh)
45
74
 
46
75
  test-tui:
47
- bash tests/e2e/tui.e2e.sh
76
+ $(call timed_step,test-tui,bash tests/e2e/tui.e2e.sh)
48
77
 
49
78
  test-cross:
50
- bash tests/e2e/cross.e2e.sh
79
+ $(call timed_step,test-cross,bash tests/e2e/cross.e2e.sh)
51
80
 
52
81
  test-doctor:
53
- bash tests/e2e/doctor.e2e.sh
82
+ $(call timed_step,test-doctor,bash tests/e2e/doctor.e2e.sh)
54
83
 
55
84
  test-markers:
56
- bash tests/e2e/markers.e2e.sh
85
+ $(call timed_step,test-markers,bash tests/e2e/markers.e2e.sh)
57
86
 
58
87
  test-opencode-plugins:
59
- bash tests/e2e/opencode_plugins.e2e.sh
88
+ $(call timed_step,test-opencode-plugins,bash tests/e2e/opencode_plugins.e2e.sh)
60
89
 
61
90
  test-telegram-plugin:
62
- bash tests/e2e/telegram_plugin.e2e.sh
91
+ $(call timed_step,test-telegram-plugin,bash tests/e2e/telegram_plugin.e2e.sh)
92
+
93
+ test-ubuntu-blackbox:
94
+ $(call timed_step,test-ubuntu-blackbox,bash tests/e2e/ubuntu_blackbox.e2e.sh)
63
95
 
64
96
  test-real-agent-doctor:
65
- bash tests/e2e/real_agent_doctor.e2e.sh
97
+ $(call timed_step,test-real-agent-doctor,bash tests/e2e/real_agent_doctor.e2e.sh)
66
98
 
67
99
  test-real-blackbox:
68
- bash tests/e2e/real_agent_blackbox.e2e.sh
100
+ $(call timed_step,test-real-blackbox-codex,AGENTIC_REAL_BLACKBOX_ONLY=codex bash tests/e2e/real_agent_blackbox.e2e.sh)
101
+ $(call timed_step,test-real-blackbox-opencode,AGENTIC_REAL_BLACKBOX_ONLY=opencode bash tests/e2e/real_agent_blackbox.e2e.sh)
102
+ $(call timed_step,test-real-opencode-mapper,AGENTIC_REAL_BLACKBOX_ONLY=opencode-mapper bash tests/e2e/real_agent_blackbox.e2e.sh)
103
+ $(call timed_step,test-real-blackbox-telegram,AGENTIC_REAL_BLACKBOX_ONLY=telegram bash tests/e2e/real_agent_blackbox.e2e.sh)
104
+
105
+ test-real-blackbox-codex:
106
+ $(call timed_step,test-real-blackbox-codex,AGENTIC_REAL_BLACKBOX_ONLY=codex bash tests/e2e/real_agent_blackbox.e2e.sh)
107
+
108
+ test-real-blackbox-opencode:
109
+ $(call timed_step,test-real-blackbox-opencode,AGENTIC_REAL_BLACKBOX_ONLY=opencode bash tests/e2e/real_agent_blackbox.e2e.sh)
110
+
111
+ test-real-blackbox-telegram:
112
+ $(call timed_step,test-real-blackbox-telegram,AGENTIC_REAL_BLACKBOX_ONLY=telegram bash tests/e2e/real_agent_blackbox.e2e.sh)
69
113
 
70
114
  test-real-opencode-mapper:
71
- AGENTIC_REAL_BLACKBOX_ONLY=opencode-mapper bash tests/e2e/real_agent_blackbox.e2e.sh
115
+ $(call timed_step,test-real-opencode-mapper,AGENTIC_REAL_BLACKBOX_ONLY=opencode-mapper bash tests/e2e/real_agent_blackbox.e2e.sh)
72
116
 
73
117
  test-coverage:
74
- AGENTIC_COVERAGE_TRACE_FILE=$$(mktemp /tmp/agentic-coverage.XXXXXX) bash -c 'AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/agentic.e2e.sh >/tmp/agentic-coverage-agentic.log 2>&1 && AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/tui.e2e.sh >/tmp/agentic-coverage-tui.log 2>&1 && AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/cross.e2e.sh >/tmp/agentic-coverage-cross.log 2>&1 && AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/markers.e2e.sh >/tmp/agentic-coverage-markers.log 2>&1 && AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/cli.e2e.sh >/tmp/agentic-coverage-cli.log 2>&1 && AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/doctor.e2e.sh >/tmp/agentic-coverage-doctor.log 2>&1 && bash tests/e2e/coverage_parse.sh "$$AGENTIC_COVERAGE_TRACE_FILE"'
118
+ @if [ -n "$${AGENTIC_COVERAGE_TRACE_FILE:-}" ]; then \
119
+ trace_file="$$AGENTIC_COVERAGE_TRACE_FILE"; \
120
+ else \
121
+ trace_file="$$(mktemp /tmp/agentic-coverage.XXXXXX)"; \
122
+ fi; \
123
+ $(MAKE) _test-coverage-steps AGENTIC_COVERAGE_TRACE_FILE="$$trace_file"
124
+
125
+ _test-coverage-steps:
126
+ $(call timed_step,test-coverage-agentic,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/agentic.e2e.sh >/tmp/agentic-coverage-agentic.log 2>&1)
127
+ $(call timed_step,test-coverage-tui,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/tui.e2e.sh >/tmp/agentic-coverage-tui.log 2>&1)
128
+ $(call timed_step,test-coverage-cross,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/cross.e2e.sh >/tmp/agentic-coverage-cross.log 2>&1)
129
+ $(call timed_step,test-coverage-markers,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/markers.e2e.sh >/tmp/agentic-coverage-markers.log 2>&1)
130
+ $(call timed_step,test-coverage-cli,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/cli.e2e.sh >/tmp/agentic-coverage-cli.log 2>&1)
131
+ $(call timed_step,test-coverage-doctor,AGENTIC_COVERAGE_TRACE_FILE="$(AGENTIC_COVERAGE_TRACE_FILE)" AGENTIC_TEST_CLI="$(CURDIR)/tests/e2e/coverage_shim.sh" bash tests/e2e/doctor.e2e.sh >/tmp/agentic-coverage-doctor.log 2>&1)
132
+ $(call timed_step,test-coverage-parse,bash tests/e2e/coverage_parse.sh "$(AGENTIC_COVERAGE_TRACE_FILE)")
75
133
 
76
134
  lint:
77
135
  bash -n agentic