Quellcode durchsuchen

Merge pull request #396 from alvinunreal/sess-docs

Session docs
Alvin vor 3 Monaten
Ursprung
Commit
9f0cd6addb

+ 0 - 114
.slim/cartography.json

@@ -1,114 +0,0 @@
-{
-  "metadata": {
-    "version": "1.0.0",
-    "last_run": "2026-03-24T08:10:21.042130Z",
-    "root": "/Users/xp/repos/oh-my-opencode-slim",
-    "include_patterns": [
-      "src/**/*.ts",
-      "src/**/*.tsx",
-      "package.json",
-      "tsconfig.json"
-    ],
-    "exclude_patterns": [
-      "**/*.test.ts",
-      "**/*.spec.ts",
-      "tests/**",
-      "__tests__/**",
-      "docs/**",
-      "dist/**",
-      "node_modules/**",
-      "*.md",
-      "LICENSE"
-    ],
-    "exceptions": []
-  },
-  "file_hashes": {
-    "package.json": "3ed7adb5b811b2e9fce30fc71a2cda10",
-    "src/agents/designer.ts": "ea6af83207f143260a775d79ab229407",
-    "src/agents/explorer.ts": "efb5fddccfe5990f5d5eb8cf8c2f11a8",
-    "src/agents/fixer.ts": "3fa80ddb759a226d3810c93c477df3bf",
-    "src/agents/index.ts": "f8fff7a5be2831f21c540a75a58f5e5f",
-    "src/agents/librarian.ts": "8a85df35044c719b6615d6afdbe26f04",
-    "src/agents/oracle.ts": "d6a40e69fad62a4f95568f3e9314a06a",
-    "src/agents/orchestrator.ts": "70af086905ed0bea4df638cde556419e",
-    "src/background/background-manager.ts": "709ed0b365a58657d5ad39e1be695755",
-    "src/background/index.ts": "c20308c54093f4578e3f5145307e1a42",
-    "src/background/tmux-session-manager.ts": "0154310123bba1960af707258edea859",
-    "src/cli/config-io.ts": "c0de208f76aadd5d8a561ae8eb89bc42",
-    "src/cli/config-manager.ts": "7f2960f55aaebab21d822c586c2b12eb",
-    "src/cli/custom-skills.ts": "ebc821917095f9950163c811ac3b9af7",
-    "src/cli/index.ts": "a5ede09909809dd0988bc670d62afe22",
-    "src/cli/install.ts": "d69b94f93a6847a85d920c456f8c7d25",
-    "src/cli/model-key-normalization.ts": "7f988cc8109c95382b9ece9730e2a7a5",
-    "src/cli/paths.ts": "6047308b0ce5455823a8882ce1261b2e",
-    "src/cli/providers.ts": "8604bbe572dade63827d4a622f79626a",
-    "src/cli/skills.ts": "dc89ba9bb9fef7682a16088218045b18",
-    "src/cli/system.ts": "6f2db45c5c48fb889934ca1e7298987f",
-    "src/cli/types.ts": "a63fcf385f251ed56bba95ac0576a19b",
-    "src/config/agent-mcps.ts": "f65c01e9a29fd9c2ff5658ce30c89f98",
-    "src/config/constants.ts": "56c46fe52adc0160283428e687ba1697",
-    "src/config/index.ts": "7ec846841f7fe8fcc6d4bc5d5120412d",
-    "src/config/loader.ts": "44e7721b31f84e60c425a6161d08bc72",
-    "src/config/schema.ts": "d4f5cf4e457e06811e0ef7de26c16f77",
-    "src/config/utils.ts": "bc3af4a86874329f638a374ac7c00701",
-    "src/hooks/auto-update-checker/cache.ts": "2d49b0e0ea0f1a36b2ae79f43d163b45",
-    "src/hooks/auto-update-checker/checker.ts": "0cd527f77d797a663476224d77ac44f4",
-    "src/hooks/auto-update-checker/constants.ts": "c46dcf24c3184965314f008ede59b7c7",
-    "src/hooks/auto-update-checker/index.ts": "22ff46cdeb63b0ce4fa3a2fa060ca56c",
-    "src/hooks/auto-update-checker/types.ts": "2c4bec82d99722a7e6789029fc6688c5",
-    "src/hooks/chat-headers.ts": "2586390fd72f4e19da4d06a6e770aa8f",
-    "src/hooks/delegate-task-retry/guidance.ts": "a121a7fc081422351f4d5b2044aa6024",
-    "src/hooks/delegate-task-retry/hook.ts": "709bd483063a2090fff5b1048861b5c1",
-    "src/hooks/delegate-task-retry/index.ts": "7b78edb6f10cfee10b2c117ca2287378",
-    "src/hooks/delegate-task-retry/patterns.ts": "5e4919da29af630e4e2ec37df0b58025",
-    "src/hooks/foreground-fallback/index.ts": "154b2a954447c70e2bccc68b58262d62",
-    "src/hooks/index.ts": "ce7d6cdbb898d42edea40cbf73439f6d",
-    "src/hooks/json-error-recovery/hook.ts": "55f1268777de23ed5546c8f2f0a5b424",
-    "src/hooks/json-error-recovery/index.ts": "c54900170ea905776e973e30b5dd95f4",
-    "src/hooks/phase-reminder/index.ts": "149b0c497c579b993edcee3d918ac50e",
-    "src/hooks/post-read-nudge/index.ts": "54bc3808ebd322ed5adc5de0295dedb8",
-    "src/index.ts": "8d759f53782523f8431be6d79aac9039",
-    "src/mcp/context7.ts": "4e02e8ef204b6eb7e99a3209078428b5",
-    "src/mcp/grep-app.ts": "f76cb0ffb3484b16d55f27729e80e864",
-    "src/mcp/index.ts": "d19746215624f8dfdcb21b6a1ad552c0",
-    "src/mcp/types.ts": "a67078f79aa8b99c41fb5be5d9fa9319",
-    "src/mcp/websearch.ts": "a01f59b67867b173919f7a52b7e43052",
-    "src/tools/ast-grep/cli.ts": "7ba3609dee64dd13a0a620bf69260700",
-    "src/tools/ast-grep/constants.ts": "ef016f4d4c5a6861fed9c28e968cad07",
-    "src/tools/ast-grep/downloader.ts": "c5b3d9b861acd9d971e5df1f5112b928",
-    "src/tools/ast-grep/index.ts": "842b8f43bd1ebc7e2e33a9f7fa0d3fec",
-    "src/tools/ast-grep/tools.ts": "3f7c2c65cffd5273b0cd6c849800176d",
-    "src/tools/ast-grep/types.ts": "34ad28b5b1e9617b584f082dba9a427c",
-    "src/tools/ast-grep/utils.ts": "1dd3b2133c4b8c847a26eea0423bc0b2",
-    "src/tools/background.ts": "213c131b32ea7cd8d4678eee4a76987f",
-    "src/tools/index.ts": "bc2699bbb686af17c7faf8554879a98f",
-    "src/utils/agent-variant.ts": "1ab47427e7e8381ae13f09fd499d8755",
-    "src/utils/env.ts": "b76fbfea11c340337f6bdd8a9c87bb69",
-    "src/utils/index.ts": "be0d778f15ae5b14f1dfb598611fc9ed",
-    "src/utils/internal-initiator.ts": "64f4189f18ade892f92c0b30188dcd30",
-    "src/utils/logger.ts": "779c3886f558ddb6a3b268c249ecfc4e",
-    "src/utils/polling.ts": "b1d9c52df1fae7391234d0f5476d53b5",
-    "src/utils/tmux.ts": "918006a6c388b8b408dc1d3e5849cf56",
-    "src/utils/zip-extractor.ts": "9af9d8584db77a5257d333314b48557c",
-    "tsconfig.json": "1d2bb6e93a43366843785a156c8e538a"
-  },
-  "folder_hashes": {
-    "src/hooks": "fa80831df761066009b2d70ef6ea1bea",
-    "src/background": "990c2be92ac5340871183c2743d2a768",
-    "src/hooks/post-read-nudge": "09c49463c10a4d193adcb78028f46cde",
-    "src/utils": "7e0b2eb258e4f61927ef2c9ea5cf6660",
-    "src": "fc99fc198ac16f70d78fa77f2cbbbf05",
-    "src/hooks/delegate-task-retry": "2624117607d8404122e82836c4c74114",
-    "src/hooks/phase-reminder": "c9bcdbf6e74b079a368fc68bf46de086",
-    "src/cli": "f2568e30f6af8d82c4e0d145dd8a9220",
-    "src/hooks/json-error-recovery": "c8a245f5f48918279aa3d7724a573c75",
-    "src/mcp": "f9241cd556adebddc643d71ee55ee2a8",
-    "src/hooks/foreground-fallback": "7d31d4b918d1e1e1b674dece98e10c4d",
-    "src/tools": "e008189e552e226da488a42075d5ec07",
-    "src/tools/ast-grep": "bc2c805d1593254804e74a5ea20c7cad",
-    "src/hooks/auto-update-checker": "34086e02a2cc2f000e2826091fcfb94d",
-    ".": "0943d5256e32e055bfeb16724fd66fb4",
-    "src/agents": "56493588858687537daaa3105c0405e0",
-    "src/config": "50adc10efa4196609e8cc2105ba8eba2"
-  }
-}

+ 37 - 31
.slim/codemap.json

@@ -1,7 +1,7 @@
 {
   "metadata": {
     "version": "1.0.0",
-    "last_run": "2026-04-21T21:00:06.931Z",
+    "last_run": "2026-04-23T20:44:47.448Z",
     "root": "/Users/alvin/repos/oh-my-opencode-slim",
     "include_patterns": [
       "src/**/*.ts",
@@ -28,9 +28,9 @@
   },
   "file_hashes": {
     "AGENTS.md": "30d65f029344f61705af6d525ad7801f",
-    "README.md": "9ff6c095c6f7f01a388e396ec3abd667",
+    "README.md": "3f415941772613de8f934d29f75a6f98",
     "biome.json": "b68da34425b83fddbde5718ac6eb82f9",
-    "package.json": "853c68d57c768448c020e55ca2342e94",
+    "package.json": "2b227b7342d04a033c142fcf0945d629",
     "scripts/generate-schema.ts": "007f340e39adf6c3fd76feda72b71df1",
     "scripts/verify-opencode-host-smoke.ts": "a87fdb08b123501edf81618a49bc421d",
     "scripts/verify-release-artifact.ts": "83259be1926459412809013ce16e6fbb",
@@ -39,11 +39,11 @@
     "src/agents/designer.ts": "7d4e2654d89be9bfa99deb0a2802db5c",
     "src/agents/explorer.ts": "4dc3878a5e90eb5a16aefd9ecd4261df",
     "src/agents/fixer.ts": "f5f1b428de434ee5911001ec1b5b8b54",
-    "src/agents/index.ts": "5c724aa87941d6218c03409cef913607",
+    "src/agents/index.ts": "74925084d05aa1541257e0379257f216",
     "src/agents/librarian.ts": "e62049e08902ae4138d08ce0ec5bd9e8",
     "src/agents/observer.ts": "57444137950f44a0fa6a874f2699e7e6",
     "src/agents/oracle.ts": "9aab904d02bacb93f821d9c9c8f70ccf",
-    "src/agents/orchestrator.ts": "7d1546ff75e4a8a49d6b0495a6bd6765",
+    "src/agents/orchestrator.ts": "3f12e529cc328696363f2cf6c30da2d6",
     "src/cli/config-io.ts": "e9048becbe09e618f07853ea9050b840",
     "src/cli/config-manager.ts": "7f2960f55aaebab21d822c586c2b12eb",
     "src/cli/custom-skills.ts": "da74e53dfd5f570e97a99ea4fd1d0440",
@@ -56,13 +56,13 @@
     "src/cli/system.ts": "b5464d7661ab1c8e196159641ee3bbed",
     "src/cli/types.ts": "6b3468226ad733b8c4a601677a98a11e",
     "src/config/agent-mcps.ts": "d62ecc6f60c7005ca00996aa1a5749c8",
-    "src/config/constants.ts": "bdcaf65a5746b9051f978d70ca24c39c",
-    "src/config/council-schema.ts": "9c2a543fc1428260b1cfd35d31cd4408",
+    "src/config/constants.ts": "b8dad0bac96f4d99dd27a2ecb753cb68",
+    "src/config/council-schema.ts": "4e9d5603725b7b3730685c03292f5b44",
     "src/config/index.ts": "34949877c248cc5fbc3699fd7c5c70f2",
-    "src/config/loader.ts": "8419310b841733920d03b99d6204387e",
-    "src/config/schema.ts": "567a9eeb9c24163c2a16cedc63620252",
+    "src/config/loader.ts": "7b67eb3eabb97af42409f5d5ac49f5fc",
+    "src/config/schema.ts": "e99dd75e09539cefa1fb339177365b22",
     "src/config/utils.ts": "b49d30f4c667a30cfa4627aa842b454b",
-    "src/council/council-manager.ts": "2b38ff66df1e40b1f15959efda0809bf",
+    "src/council/council-manager.ts": "8b3aa710b2af2afae0c572ffd7c4959e",
     "src/council/index.ts": "24cab5b06b4bfd91d2496692650eb18a",
     "src/hooks/apply-patch/codec.ts": "fce9edab08aab27b5c09bdb46c201203",
     "src/hooks/apply-patch/errors.ts": "fd2c9d9d185494f2f8b22862bd14700b",
@@ -87,16 +87,17 @@
     "src/hooks/delegate-task-retry/index.ts": "7b78edb6f10cfee10b2c117ca2287378",
     "src/hooks/delegate-task-retry/patterns.ts": "5e4919da29af630e4e2ec37df0b58025",
     "src/hooks/filter-available-skills/index.ts": "4cac7bea2a22f57d602de1df22203baa",
-    "src/hooks/foreground-fallback/index.ts": "31c859cf0d0e4998c6d4d99670c100b9",
-    "src/hooks/image-hook.ts": "94e07e33eac132eeb339d4b51f7dfca8",
-    "src/hooks/index.ts": "569c94462498575319218d2b9ac62895",
+    "src/hooks/foreground-fallback/index.ts": "b6de8168b13f4c38c5d17fe1686ee62f",
+    "src/hooks/image-hook.ts": "ac70a5c1fed09a250f6d7a91966a3881",
+    "src/hooks/index.ts": "7e7f54a4b02f5a9c57643ffa28fe653a",
     "src/hooks/json-error-recovery/hook.ts": "55f1268777de23ed5546c8f2f0a5b424",
     "src/hooks/json-error-recovery/index.ts": "c54900170ea905776e973e30b5dd95f4",
     "src/hooks/phase-reminder/index.ts": "55c78ab86f3b26a071c8e2f639831b8b",
     "src/hooks/post-file-tool-nudge/index.ts": "7a23d01b3396c4018015e0e90629c45d",
+    "src/hooks/task-session-manager/index.ts": "a9d701588ceefa4b40454e27c1ed2ea1",
     "src/hooks/todo-continuation/index.ts": "4bc29a79ce7d85acc120c87a02cd09d2",
     "src/hooks/todo-continuation/todo-hygiene.ts": "08374710c80e24ca55b78a1ff5ed7a81",
-    "src/index.ts": "71860a08236a119da95f0b9161b52d26",
+    "src/index.ts": "fa92b5f3491ff9a2ba8a1ccf3e631ba2",
     "src/interview/dashboard.ts": "dbe6703d036ff16952c98f5cc0066e5c",
     "src/interview/document.ts": "c8c35c9042fdef497925c89ce1dba1b4",
     "src/interview/helpers.ts": "b95a7e299bb4ab38ab66a272b3ba3612",
@@ -105,9 +106,9 @@
     "src/interview/parser.ts": "f555be74e939ac8a0e9eaf8fe2b38e11",
     "src/interview/prompts.ts": "ff6e3cd2e95c407662b143af8db615fc",
     "src/interview/server.ts": "486e31b94f0353a838a017510931bc50",
-    "src/interview/service.ts": "ea6bba2240a5e50b88a8adaf1d1d64e3",
+    "src/interview/service.ts": "5c9031b5b9b94c91f21032b3c275e365",
     "src/interview/types.ts": "2614f59dcf6fbbf1d7285644f98149a6",
-    "src/interview/ui.ts": "5f03d5500ed3bd9e5e0fd7449353dc20",
+    "src/interview/ui.ts": "c00692ea35dc56e752f51369b6bfdcbb",
     "src/mcp/context7.ts": "4e02e8ef204b6eb7e99a3209078428b5",
     "src/mcp/grep-app.ts": "f76cb0ffb3484b16d55f27729e80e864",
     "src/mcp/index.ts": "92464b907264ebd630e12a42ae6eee67",
@@ -115,7 +116,7 @@
     "src/mcp/websearch.ts": "7c507eff1d6f9c01d3ccb928ea648ca7",
     "src/multiplexer/factory.ts": "5ca22092bbe54953c620aed005485398",
     "src/multiplexer/index.ts": "252b8f5d0d6f8e6c3408eed47791bf67",
-    "src/multiplexer/session-manager.ts": "efbf78b5bc36cc9c5d8fec59b174a191",
+    "src/multiplexer/session-manager.ts": "d8224fb123d1a7073e9c0df768a98335",
     "src/multiplexer/tmux/index.ts": "7873a9b809fa16f3266d16bc2d8f702c",
     "src/multiplexer/types.ts": "2269f67f16fad8f60d92fb389cf3519b",
     "src/multiplexer/zellij/index.ts": "16b9534fafc904e84faaf862d3a67d37",
@@ -128,8 +129,9 @@
     "src/tools/ast-grep/tools.ts": "3f7c2c65cffd5273b0cd6c849800176d",
     "src/tools/ast-grep/types.ts": "34ad28b5b1e9617b584f082dba9a427c",
     "src/tools/ast-grep/utils.ts": "1dd3b2133c4b8c847a26eea0423bc0b2",
-    "src/tools/council.ts": "013b780b8f862d799d9a98adcd26b170",
-    "src/tools/index.ts": "065498f03cdc5cc66d7215f65b4ef3c7",
+    "src/tools/council.ts": "965ad3c843761781125da5be502ab43e",
+    "src/tools/index.ts": "a0d1c024ac6519e0db49c0e771c6d95b",
+    "src/tools/preset-manager.ts": "ad0249f2b5d05793b235898a8d361cb4",
     "src/tools/smartfetch/binary.ts": "a65d816f46ebef11c39bda1764f82bb7",
     "src/tools/smartfetch/cache.ts": "9a4e272b897b6914f0925919357bfce1",
     "src/tools/smartfetch/constants.ts": "1ba20e00a4d3f4717eba62f381f9cd4c",
@@ -142,44 +144,48 @@
     "src/utils/agent-variant.ts": "7bf26b256814b18ac04b374586a44c77",
     "src/utils/compat.ts": "806de91aefa1d164b004c6ca465d8700",
     "src/utils/env.ts": "b76fbfea11c340337f6bdd8a9c87bb69",
-    "src/utils/index.ts": "cc35eee0a38f8dd094af5e3b26757804",
+    "src/utils/index.ts": "670f25ee2b0a191e4af7ffce628dc230",
     "src/utils/internal-initiator.ts": "64f4189f18ade892f92c0b30188dcd30",
     "src/utils/logger.ts": "a73dd89ea1e97870b93d3387be122baf",
     "src/utils/polling.ts": "b1d9c52df1fae7391234d0f5476d53b5",
+    "src/utils/session-manager.ts": "8e1e6a41e16bffeec299c715eb4017c5",
     "src/utils/session.ts": "a6d5dfb749b70bb3b96fee2d0428e1f9",
     "src/utils/subagent-depth.ts": "f925bd47ed5ffb67039508bedb14ac25",
+    "src/utils/system-collapse.ts": "e805ef4cf7fdd97316c739756b7f0a96",
+    "src/utils/task.ts": "802eefa5a13ec0bb294a862f5366363e",
     "src/utils/zip-extractor.ts": "11e6d1913e049f46099bb61d4a77e62b",
     "tsconfig.json": "1d2bb6e93a43366843785a156c8e538a"
   },
   "folder_hashes": {
-    ".": "f879a605b798ed78508909223b340fd9",
+    ".": "c3aff2cb0efa4fafbc9d620ecc930e73",
     "scripts": "7ebdcbc44fd1e155c3ef2cc3baecb925",
-    "src": "70818eb0b5ea3938cf5f818a8c0ac5a7",
-    "src/agents": "75a55d6aeb126a4965a0fef62730c375",
+    "src": "b02fb0301ebce2f90dc183bc31378f58",
+    "src/agents": "20a86940e26e67b4401b185542fabb41",
     "src/cli": "1b78a40dfdd03912f257532127f810b4",
-    "src/config": "9f3223e021a667d6d3e717e29e2eec0c",
-    "src/council": "ec4aa430a77af9d5ca82daa6a20583e7",
-    "src/hooks": "f3062ab5f4ec3f58637f7a2e6cdef26d",
+    "src/config": "911b54439938cefeb9e2734d131dff4c",
+    "src/council": "02508e6e9fd78d68b4e5e25e0bc58a6c",
+    "src/hooks": "cde4c1076282de769271e6975659f95e",
     "src/hooks/apply-patch": "d3bd03747a4c2ecd199fb68706d4c8d2",
     "src/hooks/auto-update-checker": "c407065b8052ab293b8c78e643a19297",
     "src/hooks/delegate-task-retry": "c2c138123a5bea46d53ded27049e0002",
     "src/hooks/filter-available-skills": "42214100c13e02e3b197f1e7cb1b586a",
-    "src/hooks/foreground-fallback": "ce1e432e5df74b621af88100e27bc9e9",
+    "src/hooks/foreground-fallback": "deaf94fe467f76ef44535beedea50f6e",
     "src/hooks/json-error-recovery": "c8a245f5f48918279aa3d7724a573c75",
     "src/hooks/phase-reminder": "80f01bd7edd895fcd3950a44b21a4d3a",
     "src/hooks/post-file-tool-nudge": "e01c0aa6e649ec049c068d6a1b2006f9",
+    "src/hooks/task-session-manager": "0c73238a14d84eb1d204f9cc0044180d",
     "src/hooks/todo-continuation": "f3622b6cc650fcd74043cde96b56b9f3",
-    "src/interview": "10923d6ce307cebd04a2f5027e222e91",
+    "src/interview": "3920f8d94c932173803d6fdd8506b9b3",
     "src/mcp": "5f5fc5fbb54bf9944063483cee8be88f",
-    "src/multiplexer": "1ab1795813a0596bda3358cea39f4d7c",
+    "src/multiplexer": "f543dda4ba0043e6c5e4ea0c07e11a77",
     "src/multiplexer/tmux": "796d0d51b317bdb05c54dcf257fb5597",
     "src/multiplexer/zellij": "35ab5e99b43ac4da5a085d1e331da37b",
     "src/skills": "c93b75814e75bc85966fba4513b81b24",
     "src/skills/codemap": "1e82ef833612703b786daceb091f2422",
     "src/skills/simplify": "9c745d8113135e3103af5f1a49d67dfe",
-    "src/tools": "100379388fab4d60ef65482afd46b034",
+    "src/tools": "028b6df5f9ed6b309f7b67317ec3f2f9",
     "src/tools/ast-grep": "2d4ad34fd02c6d068766dd38e826f2a8",
     "src/tools/smartfetch": "ff5047fb784b3d868e3908099591a117",
-    "src/utils": "78d596e8f807bda028667382a9a0752d"
+    "src/utils": "5e4fae8a6e05d3506f79edda3211ffe9"
   }
 }

+ 4 - 6
README.md

@@ -67,9 +67,6 @@ The default generated configuration looks like this:
 {
   "$schema": "https://unpkg.com/oh-my-opencode-slim@latest/oh-my-opencode-slim.schema.json",
   "preset": "openai",
-  "sessionManager": {
-    "maxSessionsPerAgent": 2
-  },
   "presets": {
     "openai": {
       "orchestrator": { "model": "openai/gpt-5.4", "variant": "high", "skills": ["*"], "mcps": ["*", "!context7"] },
@@ -83,9 +80,9 @@ The default generated configuration looks like this:
 }
 ```
 
-`sessionManager.maxSessionsPerAgent` controls how many resumable child sessions
-the orchestrator remembers per specialist type inside the current parent
-session.
+Session management is enabled by default even though it is not shown in the
+starter config. See **[Session Management](docs/session-management.md)** if you
+want to customize how many resumable child-agent sessions are remembered.
 
 ### For Alternative Providers
 
@@ -480,6 +477,7 @@ Use this section as a map: start with installation, then jump to features, confi
 | **[Council](docs/council.md)** | Run multiple models in parallel and synthesize a single answer with `@council` |
 | **[Interview](docs/interview.md)** | Turn rough ideas into a structured markdown spec through a browser-based Q&A flow |
 | **[Multiplexer Integration](docs/multiplexer-integration.md)** | Watch agents work live in Tmux or Zellij panes |
+| **[Session Management](docs/session-management.md)** | Reuse recent child-agent sessions with short aliases instead of starting over |
 | **[Todo Continuation](docs/todo-continuation.md)** | Auto-continue orchestrator sessions with cooldowns and safety checks |
 | **[Preset Switching](docs/preset-switching.md)** | Switch agent model presets at runtime with `/preset` |
 | **[Codemap](docs/codemap.md)** | Generate hierarchical codemaps to understand large codebases faster |

+ 20 - 16
codemap.md

@@ -7,8 +7,8 @@
 - define orchestrator and specialist agents,
 - load layered plugin configuration and per-agent permissions,
 - expose additional tools and MCP integrations,
-- manage delegated session orchestration and terminal multiplexer visualization,
-- inject workflow-enforcement hooks,
+- manage delegated/resumable session orchestration and terminal multiplexer visualization,
+- inject workflow-enforcement hooks plus runtime command handlers,
 - ship install-time skills and a bootstrap CLI.
 
 This codemap intentionally covers the plugin repository itself and excludes the nested `opencode/` upstream checkout.
@@ -18,7 +18,7 @@ This codemap intentionally covers the plugin repository itself and excludes the
 | Path | Role |
 |---|---|
 | `package.json` | Package manifest, dependency graph, release scripts, published file list. |
-| `src/index.ts` | Main plugin bootstrap: wires agents, tools, MCPs, hooks, council/session managers, multiplexer session mirroring, interview manager, and config merge behavior. |
+| `src/index.ts` | Main plugin bootstrap: wires agents, tools, MCPs, hooks, council/session managers, multiplexer session mirroring, interview/preset managers, task-session tracking, and config merge behavior. |
 | `src/cli/index.ts` | CLI entrypoint for installation/bootstrap workflows. |
 | `src/config/schema.ts` | Source-of-truth runtime config schema used by validation and schema generation. |
 | `scripts/generate-schema.ts` | Generates `oh-my-opencode-slim.schema.json` from the Zod config schema. |
@@ -27,33 +27,34 @@ This codemap intentionally covers the plugin repository itself and excludes the
 
 | Directory | Responsibility Summary | Detailed Map |
 |---|---|---|
-| `src/` | Main application surface that composes plugin bootstrap, runtime modules, and installer-facing code. | [View Map](src/codemap.md) |
-| `src/agents/` | Agent factory layer for orchestrator and specialists, including MCP assignment and permission shaping. | [View Map](src/agents/codemap.md) |
+| `src/` | Main application surface that composes plugin bootstrap, runtime model chains, hook orchestration, task-session aliasing, and installer-facing code. | [View Map](src/codemap.md) |
+| `src/agents/` | Agent factory layer for orchestrator and specialists, including prompt/model overrides, display-name normalization, MCP assignment, and permission shaping. | [View Map](src/agents/codemap.md) |
 | `src/cli/` | Installer, config editing, provider preset generation, and built-in skill installation. | [View Map](src/cli/codemap.md) |
-| `src/config/` | Configuration schema, loaders, constant tables, and agent/MCP policy helpers. | [View Map](src/config/codemap.md) |
-| `src/council/` | Multi-model council orchestration and synthesis fallback flow. | [View Map](src/council/codemap.md) |
-| `src/hooks/` | Aggregated runtime hook surface for prompt transforms, recovery logic, nudges, and lifecycle policies. | [View Map](src/hooks/codemap.md) |
+| `src/config/` | Configuration schema, layered loaders, preset merging, compatibility migrations, constant tables, and agent/MCP policy helpers. | [View Map](src/config/codemap.md) |
+| `src/council/` | Multi-model council orchestration with preset resolution, councillor execution modes, retries, timeout handling, and synthesis fallback flow. | [View Map](src/council/codemap.md) |
+| `src/hooks/` | Aggregated runtime hook surface for prompt transforms, recovery logic, task-session aliasing, nudges, and lifecycle policies. | [View Map](src/hooks/codemap.md) |
 | `src/hooks/apply-patch/` | Structured `apply_patch` parsing, matching, recovery, and rewrite pipeline. | [View Map](src/hooks/apply-patch/codemap.md) |
 | `src/hooks/auto-update-checker/` | Startup update detection, cache handling, and optional install prompt flow. | [View Map](src/hooks/auto-update-checker/codemap.md) |
 | `src/hooks/delegate-task-retry/` | Post-tool retry guidance for failed delegation attempts. | [View Map](src/hooks/delegate-task-retry/codemap.md) |
 | `src/hooks/filter-available-skills/` | Skill-visibility filtering based on agent permission policy. | [View Map](src/hooks/filter-available-skills/codemap.md) |
-| `src/hooks/foreground-fallback/` | Interactive-session fallback control path for rate-limit or degraded foreground execution. | [View Map](src/hooks/foreground-fallback/codemap.md) |
+| `src/hooks/foreground-fallback/` | Interactive-session fallback control path for rate-limit or degraded foreground execution with event-driven agent mapping. | [View Map](src/hooks/foreground-fallback/codemap.md) |
 | `src/hooks/json-error-recovery/` | JSON/tool-output recovery helpers for malformed model responses. | [View Map](src/hooks/json-error-recovery/codemap.md) |
 | `src/hooks/phase-reminder/` | Message-transform reminder enforcing orchestrator workflow phases. | [View Map](src/hooks/phase-reminder/codemap.md) |
 | `src/hooks/post-file-tool-nudge/` | Post-read/write reminder path that nudges delegation-aware next steps. | [View Map](src/hooks/post-file-tool-nudge/codemap.md) |
+| `src/hooks/task-session-manager/` | Resumable `task` session tracking, short alias resolution, prompt injection, and stale-session cleanup. | [View Map](src/hooks/task-session-manager/codemap.md) |
 | `src/hooks/todo-continuation/` | Auto-continue behavior for outstanding todo execution. | [View Map](src/hooks/todo-continuation/codemap.md) |
-| `src/interview/` | `/interview` feature: prompt/state orchestration, persistence, local UI, and dashboard mode. | [View Map](src/interview/codemap.md) |
+| `src/interview/` | `/interview` feature: per-session and dashboard prompt/state orchestration, persistence, local UI, and cross-process coordination. | [View Map](src/interview/codemap.md) |
 | `src/mcp/` | Built-in MCP registry and per-provider MCP definitions. | [View Map](src/mcp/codemap.md) |
-| `src/multiplexer/` | Terminal multiplexer abstraction layer with backend selection, session mirroring, and shutdown lifecycle orchestration. | [View Map](src/multiplexer/codemap.md) |
+| `src/multiplexer/` | Terminal multiplexer abstraction layer with backend selection, session mirroring, polling fallback, and shutdown lifecycle orchestration. | [View Map](src/multiplexer/codemap.md) |
 | `src/multiplexer/tmux/` | tmux backend implementation for pane lifecycle and layout management. | [View Map](src/multiplexer/tmux/codemap.md) |
 | `src/multiplexer/zellij/` | zellij backend implementation for tab/pane lifecycle. | [View Map](src/multiplexer/zellij/codemap.md) |
 | `src/skills/` | Bundled install-time OpenCode skills shipped as static payloads. | [View Map](src/skills/codemap.md) |
 | `src/skills/codemap/` | Repository-mapping skill package and codemap state-management script. | [View Map](src/skills/codemap/codemap.md) |
 | `src/skills/simplify/` | Behavior-preserving simplification skill package. | [View Map](src/skills/simplify/codemap.md) |
-| `src/tools/` | Tool export surface for AST-grep, smartfetch, and council orchestration with strict schema-based execution paths. | [View Map](src/tools/codemap.md) |
+| `src/tools/` | Tool and runtime-command export surface for AST-grep, smartfetch, council orchestration, and `/preset` switching. | [View Map](src/tools/codemap.md) |
 | `src/tools/ast-grep/` | AST-grep binary management and AST-aware search/replace tool flow. | [View Map](src/tools/ast-grep/codemap.md) |
 | `src/tools/smartfetch/` | Fetch/extract/cache pipeline for web content and secondary-model summarization. | [View Map](src/tools/smartfetch/codemap.md) |
-| `src/utils/` | Cross-cutting helpers for logging, session metadata, subagent depth tracking, environment, and runtime operations. | [View Map](src/utils/codemap.md) |
+| `src/utils/` | Cross-cutting helpers for logging, session metadata, resumable task aliases, system-message normalization, subagent depth tracking, environment, and runtime operations. | [View Map](src/utils/codemap.md) |
 | `scripts/` | Build/release validation and generated-artifact maintenance scripts. | [View Map](scripts/codemap.md) |
 
 ## Runtime Control Flow
@@ -64,15 +65,16 @@ This codemap intentionally covers the plugin repository itself and excludes the
    - Agent definitions are produced by `src/agents/`.
    - Tool factories from `src/tools/` and MCP definitions from `src/mcp/` are registered.
    - Hooks from `src/hooks/` are attached.
-   - Delegation/council orchestration, multiplexer session mirroring, and interview support are initialized.
+   - Delegation/council orchestration, multiplexer session mirroring, interview support, task-session aliasing, and runtime preset handling are initialized.
 
 2. **Interactive request handling**
    - The orchestrator prompt drives routing decisions.
    - Tool calls resolve through `src/tools/` or built-in OpenCode tools.
-   - Hooks can transform prompts/messages or repair tool failures before/after execution.
+   - Hooks can transform prompts/messages, normalize system message arrays, repair tool failures, or intercept runtime commands before/after execution.
 
 3. **Delegated execution**
    - OpenCode child sessions are created by delegation/council flows and tracked by plugin utilities.
+   - `src/hooks/task-session-manager/` remembers reusable child sessions and injects short aliases into the orchestrator prompt.
    - `src/multiplexer/` optionally mirrors those sessions into tmux/zellij panes.
    - Results flow back into the parent session through notifications/output polling.
 
@@ -86,8 +88,10 @@ This codemap intentionally covers the plugin repository itself and excludes the
 - `src/index.ts` is the central composition root for nearly every runtime subsystem.
 - `src/config/` feeds `src/agents/`, session/delegation utilities, and MCP registration.
 - `src/cli/skills.ts` and `src/cli/custom-skills.ts` bridge install-time skill packaging with runtime permission policy.
-- Session/delegation utilities depend on `src/multiplexer/` and cooperate with helpers in `src/utils/`.
+- Session/delegation utilities depend on `src/multiplexer/` and cooperate with helpers in `src/utils/` for depth tracking, result extraction, task output parsing, and alias state.
 - `src/tools/council.ts` delegates into `src/council/`.
+- `src/tools/preset-manager.ts` hooks command execution and updates runtime agent models from configured presets.
+- `src/hooks/task-session-manager/` depends on `src/utils/session-manager.ts` and `src/utils/task.ts` to support child-session reuse.
 - `src/hooks/filter-available-skills/` and agent permission logic rely on shared skill names from the CLI/config layer.
 - `src/interview/` hooks into plugin command/event surfaces exposed by `src/index.ts`.
 

+ 6 - 20
docs/configuration.md

@@ -108,7 +108,7 @@ Presets can also be switched at runtime without restarting using the `/preset` c
 | `tmux.enabled` | boolean | `false` | Legacy alias for `multiplexer.type = "tmux"` |
 | `tmux.layout` | string | `"main-vertical"` | Legacy alias for `multiplexer.layout` |
 | `tmux.main_pane_size` | number | `60` | Legacy alias for `multiplexer.main_pane_size` |
-| `sessionManager.maxSessionsPerAgent` | integer | `2` | Maximum remembered resumable child sessions per specialist type in the current orchestrator session (1–10) |
+| `sessionManager.maxSessionsPerAgent` | integer | `2` | Maximum remembered resumable child sessions per specialist type in the current orchestrator session (1–10). See [Session Management](session-management.md) |
 | `disabled_mcps` | string[] | `[]` | MCP server IDs to disable globally |
 | `fallback.enabled` | boolean | `false` | Enable model failover on timeout/error |
 | `fallback.timeoutMs` | number | `15000` | Time before aborting and trying next model |
@@ -171,26 +171,12 @@ automatically.
 > `"oh-my-opencode-slim@1.0.1"`) are the true version lock. Those stay pinned
 > regardless of `autoUpdate`.
 
-### Session Manager
+### Session Management
 
-The session manager is enabled by default. It keeps a small in-memory working
-set of resumable child sessions for orchestrator-managed delegations, scoped to
-the current parent orchestrator session.
-
-```jsonc
-{
-  "sessionManager": {
-    "maxSessionsPerAgent": 2
-  }
-}
-```
-
-Notes:
-
-- Only orchestrator-managed `task` delegations participate
-- Manual `@agent` calls do not reuse this registry
-- Sessions are kept in memory only and disappear on restart
-- When a remembered session is missing, the next delegation falls back to a fresh child session
+Session management is enabled by default and does not need to be present in the
+starter config. Add `sessionManager` only if you want to tune how many resumable
+child-agent sessions are remembered. See [Session Management](session-management.md)
+for the concept, defaults, and examples.
 
 ### Agent Display Names
 

+ 145 - 0
docs/session-management.md

@@ -0,0 +1,145 @@
+# Session Management
+
+Session management lets the orchestrator keep track of recent delegated child
+sessions so follow-up work can continue in the right specialist context instead
+of starting from scratch every time.
+
+It is enabled by default. You do not need to add anything to your config unless
+you want to change how many sessions are remembered.
+
+---
+
+## Why It Exists
+
+Delegation works best when specialists can continue a thread they already
+understand:
+
+- Explorer can continue investigating the same part of the codebase.
+- Oracle can keep reviewing the same architecture/debugging thread.
+- Fixer can continue a scoped implementation or test update.
+- Librarian can continue the same documentation/API research.
+
+Without session management, follow-up delegations usually create fresh child
+sessions. That works, but the specialist may need repeated context. With session
+management, the orchestrator can reuse recent child sessions when it makes sense.
+
+---
+
+## How It Feels in Practice
+
+When a child task runs, the plugin remembers it under a short alias such as:
+
+```text
+exp-1
+ora-1
+fix-2
+```
+
+The orchestrator sees a compact reminder in its system context, for example:
+
+```text
+### Resumable Sessions
+explorer: exp-1 Search routing files
+oracle: ora-1 Review auth architecture
+```
+
+On a related follow-up, the orchestrator can reuse that session instead of
+launching a fresh one. If the remembered child session no longer exists, the
+plugin drops the stale entry and falls back to a new session automatically.
+
+---
+
+## Scope and Safety
+
+Session management is intentionally narrow:
+
+- It only applies to orchestrator-managed `task` delegations.
+- It is scoped to the current parent orchestrator session.
+- It is in-memory only and disappears when OpenCode/plugin state restarts.
+- It does not change manual `@agent` calls.
+- It keeps only a small number of recent sessions per specialist type.
+- Missing or deleted child sessions are cleaned up automatically.
+
+This keeps the feature useful for continuity without turning child sessions into
+long-lived global state.
+
+---
+
+## Default Behavior
+
+By default, the plugin remembers **2 recent child sessions per specialist type**.
+
+That means the generated starter config can stay clean:
+
+```jsonc
+{
+  "preset": "openai",
+  "presets": {
+    "openai": {
+      "orchestrator": { "model": "openai/gpt-5.4" },
+      "explorer": { "model": "openai/gpt-5.4-mini" },
+      "fixer": { "model": "openai/gpt-5.4-mini" }
+    }
+  }
+}
+```
+
+Session management still works because the runtime falls back to the built-in
+default.
+
+---
+
+## Configuration
+
+Only add `sessionManager` if you want to change the default limit:
+
+```jsonc
+{
+  "sessionManager": {
+    "maxSessionsPerAgent": 2
+  }
+}
+```
+
+### `sessionManager.maxSessionsPerAgent`
+
+| Type | Default | Range | Meaning |
+|------|---------|-------|---------|
+| integer | `2` | `1`–`10` | Number of recent resumable child sessions remembered per specialist type in the current parent session |
+
+Use a higher value if you often run several parallel threads per specialist. Use
+a lower value if you want fewer aliases in the orchestrator context.
+
+---
+
+## When To Tune It
+
+Most users should leave the default alone.
+
+Consider changing it when:
+
+- You frequently run multiple independent Explorer/Oracle/Fixer threads in one
+  long orchestrator session.
+- You want the orchestrator prompt to stay smaller and prefer only one remembered
+  thread per specialist.
+- You are debugging session reuse behavior and want a predictable small window.
+
+Example with a smaller memory window:
+
+```jsonc
+{
+  "sessionManager": {
+    "maxSessionsPerAgent": 1
+  }
+}
+```
+
+Example with a larger memory window:
+
+```jsonc
+{
+  "sessionManager": {
+    "maxSessionsPerAgent": 4
+  }
+}
+```

+ 74 - 57
src/agents/codemap.md

@@ -2,90 +2,107 @@
 
 ## Responsibility
 
-`src/agents/` defines all built-in and user-defined AI agents and the registry that converts configuration into OpenCode SDK agent definitions.
+`src/agents/` defines built-in specialists plus custom agents and converts
+configuration into OpenCode SDK registration data.
 
 Responsibilities:
 
-- Construct orchestrator + specialist agents with prompt customization and runtime overrides.
-- Apply model/temperature/variant/options override behavior, including fallback arrays.
-- Resolve permissions and tool access (skills + MCPs + council tool gate).
-- Expose internal-only and user-facing agent visibility/state to OpenCode.
+- Build orchestrator and specialist agent definitions from factory functions.
+- Resolve overrides for model, variant, temperature, options, prompt, and display
+  name.
+- Normalize/validate custom agent names and custom-orchestrator-facing aliases.
+- Compose permissions, MCP allow-lists, and visibility metadata for OpenCode.
 
 ## Core architecture
 
-### Construction flow
+### Construction flow (`createAgents`)
 
-`createAgents(config?)`
-
-1. Read disabled set:
+1. Compute the disabled set via `getDisabledAgents()`:
    - from `config.disabled_agents`
-   - applies protected-agent guard (`orchestrator`, `councillor` cannot be disabled).
-2. Create built-in subagents from `SUBAGENT_FACTORIES`.
-3. Discover custom agents from config keys in `config.agents` that are not built-in/aliases.
-4. Load prompt overrides for each agent:
+   - with protected-agent guard (`orchestrator`, `councillor` never disabled)
+2. Build built-in subagents from `SUBAGENT_FACTORIES` (`SUBAGENT_NAMES`).
+3. Discover custom agent names from `config.agents` keys that are not built-ins
+   or aliases.
+4. Validate custom names (`/^[a-z][a-z0-9_-]*$/i`) and model presence:
+   skip with warning if `model` missing.
+5. Load prompt files for each agent:
    - `<agent>.md` replacement prompt
-   - `<agent>_append.md` appended prompt
-   - preset-scoped prompt lookup path if `preset` exists.
-5. Apply overrides (`model`, `temperature`, `variant`, `options`, `displayName`) and default permissions.
-6. Build orchestrator last using its own prompt and disabled-agent filtered orchestration prompt.
-7. Validate and apply custom display-name map to orchestrator and custom prompts.
+   - `<agent>_append.md` append prompt
+6. Apply override handling:
+   - string model → `config.model`
+   - array model → `agent._modelArray` and clear `config.model`
+   - merge `temperature`, `variant`, `options`, `displayName`.
+7. Apply permission defaults per agent (`applyDefaultPermissions`).
+8. Apply compatibility fallbacks:
+   - `fixer` may inherit `librarian` model when not explicitly configured.
+   - `council` may inherit deprecated `council.master.model` when no explicit
+     `council` override and default remains unresolved.
+9. Build orchestrator using prompt files + disabled-agent filtering.
+10. Normalize/collect display names and inject `@displayName` references into:
+    orchestrator prompt and all custom `orchestratorPrompt` snippets.
+11. Validate display-name collisions/agent-name conflicts.
+12. Return `[orchestrator, ...subagents]`.
 
-Custom agents:
+### Runtime model behavior
 
-- Require a safe name not colliding with built-ins.
-- Require explicit model (string or non-empty array).
-- Skip if model is missing.
-- Built with `buildCustomAgentDefinition(...)` and allow `prompt`/`orchestratorPrompt`/`model`-chain overrides.
+- `_modelArray` is used as the ordered runtime failover chain when supplied.
+- `orchestrator` may start unresolved (`model` undefined) to allow downstream
+  runtime resolution.
+- `subagent` overrides preserve per-model variants inside `_modelArray` while
+  optionally keeping top-level `variant` as default fallback.
 
-### Runtime model behavior
+## Delegation and registration semantics
 
-- `AgentDefinition.config.model` can be set directly, or set `_modelArray` for ordered fallback models and clear direct model so resolution occurs later.
-- `orchestrator` default model is left open for runtime resolution when unset.
-- `fixer` temporary fallback: if no override, it inherits `librarian` model.
+- `getAgentConfigs(config)` converts definitions to SDK configs and sets:
+  - `orchestrator` → `mode: primary`
+  - built-in specialists → `mode: subagent`
+  - `council` → `mode: all`
+  - `councillor` → `mode: subagent`, `hidden: true`
+- If `displayName` is set:
+  - internal key remains registered but hidden
+  - host-facing key becomes normalized display name
 
-### Delegation and visibility
+Permission defaults:
 
-- Modes set in `getAgentConfigs()`:
-  - `orchestrator` → `primary`
-  - built-in subagents → `subagent`
-  - `council` → `all` (callable directly and via delegation)
-  - `councillor` → `subagent`, `hidden: true` (internal)
-- Permission defaults:
-  - `question` defaults to `allow` unless already denied.
-  - `skill` comes from configured/default skill presets.
-  - `council_session` is `allow` only for `council`.
+- `question` defaults to `allow` unless existing explicit deny.
+- `council_session` defaults to `allow` only for `council`.
+- Nested `skill` permissions come from `getSkillPermissionsForAgent` and are
+  merged with existing permission maps.
 
 ## Capability and policy inputs
 
-- MCP list selection: `getAgentMcpList(name, config)` from `config/agent-mcps.ts`.
-- Agent metadata overrides and aliases: `config/` exports (`getAgentOverride`, `getCustomAgentNames`, `AGENT_ALIASES`).
-- Skill permissions: `cli/skills.ts`.
+- MCP allow-lists:
+  - `getAgentMcpList(name, config)` from `src/config/agent-mcps.ts`
+  - `agent-mcps` defaults in `src/config/agent-mcps.ts`
+- Agent metadata/aliases:
+  - `AGENT_ALIASES`, `SUBAGENT_NAMES`, `PROTECTED_AGENTS`
+  - `getAgentOverride`, `getCustomAgentNames` from `src/config/utils.ts`
+- Skills:
+  - `cli/skills.ts`
 
 ## Flow and integration
 
 ```text
 src/index.ts
-  └─> createAgents(config)
-      └─> [orchestrator, explorer, librarian, oracle, designer, fixer, observer, council, councillor(custom)]
-          └─> getAgentConfigs(config)
-              └─> OpenCode register
-```
+  └─> loadPluginConfig()
+      └─> createAgents(config) / getAgentConfigs(config)
+          └─> registration + runtime chat hooks
 
-```text
-loadPluginConfig()
-  └─> prompt files + overrides
-      └─> createAgents()/getAgentConfigs()
+  loadPluginConfig()
+    └─> prompt overrides + presets
+        └─> createAgents/create custom/orchestrator prompts
 ```
 
-## Key control points
+## Utilities and helpers
 
-- `src/agents/index.ts` now includes extended agent surface and custom-agent extension.
-- `orchestrator.ts` owns prompt composition and dynamic disabled-agent filtering.
-- `council.ts` + `councillor.ts` provide council-agent prompts and result formatter helpers.
+- `isSubagent(name)` — type guard for subagent names.
+- `getDisabledAgents(config)` and `getEnabledAgentNames(config)`.
+- `resolvePrompt()` in `orchestrator.ts` centralizes replacement vs append behavior.
 
 ## File structure
 
-- `index.ts` (registry, overrides, visibility, disabled/visible behavior)
-- `orchestrator.ts` (base orchestrator prompt + prompt resolution)
-- `council.ts`, `councillor.ts` (council-specific definitions + formatting helpers)
-- `observer.ts`, `explorer.ts`, `librarian.ts`, `oracle.ts`, `designer.ts`, `fixer.ts`
+- `index.ts` (agent registry, overrides, classification, custom agents)
+- `orchestrator.ts` (base prompts, prompt resolution, model-array type)
+- `council.ts`, `councillor.ts` (council tool orchestration + formatting)
+- `explorer.ts`, `librarian.ts`, `oracle.ts`, `designer.ts`, `fixer.ts`,
+  `observer.ts` (specialist factory prompts/config)

+ 30 - 13
src/codemap.md

@@ -1,24 +1,41 @@
 # src/
 
 ## Responsibility
-- `src/index.ts` delivers the oh-my-opencode-slim plugin by merging configuration, instantiating orchestrator/subagent definitions, wiring session/delegation tracking, multiplexer helpers, built-in tools, MCPs, and lifecycle hooks so OpenCode sees a single cohesive module.
-- `config/`, `agents/`, `tools/`, `multiplexer/`, `hooks/`, and `utils/` contain the reusable building blocks (loader/schema/constants, agent factories/permission helpers, tool factories, session mirroring managers, hook implementations, and logging/session/depth helpers) that power that entry point.
-- `cli/` exposes installer workflows (argument parsing + interactive prompts) that edit OpenCode config, install recommended/custom skills, and generate provider presets for this plugin.
+
+- `src/index.ts` delivers the plugin assembly layer: it loads configuration, resolves agent definitions, precomputes runtime model fallback chains, wires multiplexer/session orchestration, registers tools/MCPs/hooks, and returns the OpenCode plugin registration object.
+- `config/`, `agents/`, `tools/`, `multiplexer/`, `hooks/`, and `utils/` contain the reusable building blocks (loader/schema/constants, agent factories/permission helpers, tool factories, session mirroring managers, hook implementations, and runtime utilities) that power that entry point.
+- `hooks/task-session-manager` is now part of the core plugin flow to support resumable child task sessions with concise aliases and reminder injection for orchestrator calls.
+- `cli/` remains the installer surface (argument parsing, interactive prompts, config edits, skill/provider installation).
 
 ## Design
+
 - Agent creation follows explicit factories (`agents/index.ts`, per-agent creators under `agents/`) with override/permission helpers (`config/schema.ts`, `cli/skills.ts`, `config/agent-mcps.ts`) so defaults live in `config/constants.ts`, prompts can be swapped via `config/loader.ts`, and variant labels propagate through `utils/agent-variant.ts`.
-- Session orchestration combines `MultiplexerSessionManager` with `SubagentDepthTracker` and `multiplexer/*` so child sessions are depth-tracked, can surface in panes, and are cleaned up consistently.
-- Hooks are isolated (`hooks/auto-update-checker`, `phase-reminder`, `post-file-tool-nudge`) and exported via `hooks/index.ts`, so the plugin simply registers them via the `event`, `experimental.chat.system.transform`, `experimental.chat.messages.transform`, and `tool.execute.after` hooks defined in `index.ts`.
+- Session orchestration combines `SubagentDepthTracker`, `MultiplexerSessionManager`, `CouncilManager`, and `ForegroundFallbackManager`; these coordinate subagent depth limits, pane lifecycle, council session creation, and foreground model failover.
+- Hook composition is centralized in `src/index.ts`: lifecycle event handlers and tool transform handlers fan out to specialized hooks, then some hooks post-process system messages in-place for provider compatibility.
 - Supplemental tools bundle AST-grep search/replace, council orchestration, and web fetching behind the OpenCode `tool` interface and are mounted in `index.ts` alongside hooks and MCP helpers.
 
 ## Flow
-- Startup: `index.ts` calls `loadPluginConfig` (user + project JSON + presets) to build a `PluginConfig`, passes it to `getAgentConfigs` (which uses `createAgents`, `getAgentMcpList`, and `loadAgentPrompt`), then initializes `SubagentDepthTracker`, `MultiplexerSessionManager`, `CouncilManager`, and hook/tool registrations.
-- Plugin registration: `index.ts` registers agents, the tool map (`council`, `webfetch`, `ast_grep_*`), MCP definitions (`createBuiltinMcps`), and hooks (`createAutoUpdateCheckerHook`, `createPhaseReminderHook`, `createTodoContinuationHook`, etc.); config-driven permission policy and MCP filters are applied via `getDisabledAgents` and `config/agent-mcps.ts`.
-- Runtime: `MultiplexerSessionManager` observes `session.created` events to spawn panes via multiplexer backends and closes them on idle, deleted, or timeout states, while `SubagentDepthTracker` constrains nested delegated session creation.
-- CLI flow: `cli/install.ts` parses flags, optionally asks interactive prompts, checks OpenCode installation, appends plugin entries via `cli/config-io.ts` and `cli/paths.ts`, disables default agents, writes the lite config, and installs skills (`cli/skills.ts`, `cli/custom-skills.ts`).
+
+- Startup:
+  - `loadPluginConfig` builds effective config from user/project presets.
+  - `createAgents` + `getAgentConfigs` construct final agent registry and resolved prompts.
+  - Runtime model chains are built from configured arrays plus fallback chains.
+  - `SubagentDepthTracker`, `MultiplexerSessionManager`, `CouncilManager`, `ForegroundFallbackManager`, and hook factories are initialized before registration.
+- Plugin registration: `index.ts` merges/overlays agent configs into OpenCode's config, registers tools (`council`, `webfetch`, `ast_grep_*`, todo tools), MCPs (`createBuiltinMcps`), and all hook handlers (`event`, `tool.execute.before/after`, `experimental.chat.system/messages.transform`, `command.execute.before`, etc.).
+- Runtime event flow (`event`): updates depth tree, multiplexer pane state, auto-update checks, interview/preset state, and task-session cleanup for deleted sessions.
+- `experimental.chat.system.transform` pipeline:
+  - injects orchestrator/system-level reminders when required,
+  - applies task/session prompt enrichment from `task-session-manager`,
+  - collapses all system entries into one message via `collapseSystemInPlace` for providers that reject multi-message system arrays.
+- `tool.execute.before/after` (`task`): records pending task calls, resolves short aliases to canonical IDs, parses outputs for new task IDs, and updates/removes remembered sessions.
+- CLI flow: `cli/install.ts` parses flags, optionally prompts, checks OpenCode installation, updates config via `cli/config-io.ts` and `cli/paths.ts`, disables default agents, writes lite config, and installs skills (`cli/skills.ts`, `cli/custom-skills.ts`).
 
 ## Integration
-- Connects directly to the OpenCode plugin API (`@opencode-ai/plugin`): registers agents/tools/mcps, responds to `session.created` and `tool.execute.after` events, injects message/system transforms, and makes RPC calls via `ctx.client`/`ctx.client.session` throughout the council, multiplexer, and hook systems.
-- Integrates with the host environment: `src/multiplexer` validates pane backend availability through startup checks, and `MultiplexerSessionManager` coordinates child-session panes via shared multiplexer configuration.
-- Hooks and helpers tie into external behavior: `hooks/auto-update-checker` reads `package.json` metadata, runs safe `bun install`, and posts toasts; `hooks/phase-reminder` and `hooks/post-file-tool-nudge` enforce workflow reminders without mutating file-tool output; `utils/logger.ts` centralizes structured logging used across modules.
-- CLI utilities modify OpenCode config files (`cli/config-io.ts`, `cli/paths.ts`) and install additional skills/providers, ensuring the plugin lands with configured agents, provider presets, and permission-aware skill definitions.
+
+- Connects directly to `@opencode-ai/plugin`: returns the plugin object, mutates runtime agent configuration, handles event hooks, and routes RPC via `ctx.client`/`ctx.client.session`.
+- Integrates with host multiplexer backends through `src/multiplexer`, and with session lifecycle constraints through `SubagentDepthTracker`.
+- Hooks/handoff integration points now include:
+  - `createTaskSessionManagerHook` for resumable Task sessions,
+  - `createTodoContinuationHook`, `createPhaseReminderHook`, `createFilterAvailableSkillsHook`, and `createPostFileToolNudgeHook` for chat/tool behavior,
+  - `createInterviewManager` / `createPresetManager` command handlers.
+- Utility integration is visible at runtime through `utils/session-manager.ts` + `utils/task.ts` (task resume support), `utils/system-collapse.ts` (system message normalization), and legacy utility support (`logger`, `env`, `polling`, `session`, etc.).

+ 78 - 58
src/config/codemap.md

@@ -2,82 +2,102 @@
 
 ## Responsibility
 
-`src/config/` defines plugin schema, runtime merge behavior, config loading, and policy helpers used by every runtime subsystem.
+`src/config/` owns plugin configuration schema, load/merge pipeline, prompt
+resolution, and helper APIs used by agents, council, and runtime subsystems.
 
 ## Architecture
 
-### Core inputs and outputs
+### Core entry points
 
-- `loadPluginConfig(directory)` is the primary runtime entry.
-- Configuration shape validated by `PluginConfigSchema` and merged with project overrides.
-- Preset selection and prompt loading are both runtime-controlled.
+- `loadPluginConfig(directory)` is the top-level loader used by `src/index.ts`.
+- `PluginConfigSchema` validates and normalizes raw config, including:
+  - legacy council field deprecation capture
+  - strict guard that `prompt` / `orchestratorPrompt` are only for custom
+    agents.
+- `getAgentPrompt`/`loadAgentPrompt` and related helpers are consumed by
+  agent registry.
 
 ### Merge and load pipeline
 
-`loadPluginConfig(directory)` currently:
-
-1. Load user config from search dirs (prefers `.jsonc` then `.json`).
-2. Load project override config from `./.opencode/oh-my-opencode-slim.*`.
-3. Deep-merge nested objects (`agents`, `tmux`, `multiplexer`, `interview`, `fallback`, `council`) with project config taking precedence.
-4. Migrate legacy `tmux` to `multiplexer` when needed.
-5. Apply env preset (`OH_MY_OPENCODE_SLIM_PRESET`) over config value.
-6. Merge preset values into root `agents` (root still wins on conflict).
-
-### Prompt discovery and override semantics
-
-`loadAgentPrompt(agentName, preset?)` resolves optional agent prompts:
-
-- Checks preset-scoped prompt directory first (`<configDir>/oh-my-opencode-slim/<preset>/`).
-- Checks package-wide prompt directory fallback.
-- Loads optional replacement (`<agent>.md`) and append (`<agent>_append.md`) files.
-
-### Runtime schema surface
-
-- `agents`: per-agent overrides (`model`, `temperature`, `variant`, `options`, `skills`, `mcps`, prompts)
-- `disabled_agents`, `disabled_mcps`
-- `multiplexer`: runtime pane strategy (`auto|tmux|zellij|none`)
-- `tmux` (legacy support) + migration into multiplexer
-- `fallback`: retry/timeout policy for provider fallback and empty responses
-- `interview`: dashboard/session interview behavior
-- `council`: council preset/timeout/retry/execution-mode config
-
-`Schema notes`:
-
-- `AgentOverrideConfig` supports both string and array model formats for ordered fallback.
-- Custom prompt fields (`prompt`, `orchestratorPrompt`) are validated only for custom agents (schema-level guard).
-- Council config (`council-schema.ts`) tolerates deprecated `master` fields by marking them ignored and exposing warning metadata.
-
-## Control flow and module dependencies
+`loadPluginConfig(directory)`:
+
+1. Locate user config (prefer `.jsonc`, then `.json`) from:
+   - `OPENCODE_CONFIG_DIR`
+   - `XDG_CONFIG_HOME/opencode`
+   - `~/.config/opencode`
+2. Locate project config at
+   `<directory>/.opencode/oh-my-opencode-slim.(jsonc|json)`.
+3. Validate with schema. Invalid/malformed files are warned and ignored by
+   returning `null` for that file.
+4. Merge user+project configs where project takes precedence:
+   nested merges for `agents`, `tmux`, `multiplexer`, `interview`, `sessionManager`,
+   `fallback`, `council`.
+   top-level arrays/values are overridden.
+5. If `tmux` is enabled and no explicit `multiplexer` is configured,
+   migrate to `multiplexer` (`tmux` compatibility path).
+6. Apply env override `OH_MY_OPENCODE_SLIM_PRESET` over config file preset.
+7. If preset exists, merge preset agents into `agents` so explicit root agents
+   still win (`deepMerge(preset, config.agents)`).
+8. Return merged config object.
+
+### Prompt discovery
+
+`loadAgentPrompt(agentName, preset?)`:
+
+- Searches config directories for `oh-my-opencode-slim/` prompt roots.
+- Supports optional preset subdirectory lookup when `preset` is alphanumeric/
+  hyphen/underscore-safe.
+- For each agent:
+  - `<agent>.md` replacement prompt
+  - `<agent>_append.md` appended prompt
+- Read errors are warned and do not fail config load.
+
+### Schema surface and compatibility
+
+- Agent override schema supports:
+  - `model` string or ordered fallback array (string or `{id, variant}`)
+  - `temperature`, `variant`, `options`, `skills`, `mcps`, `displayName`
+  - custom agent prompts (`prompt`, `orchestratorPrompt`) only.
+- Multiplexer:
+  - new unified `multiplexer` schema (`auto|tmux|zellij|none`)
+  - legacy `tmux` schema retained and migrated at load time.
+- Council:
+  - `CouncilConfigSchema` now normalizes deprecated `master*` fields into
+    `_legacyMasterModel` metadata for compatibility
+  - supports presets + timeout/retry/execution mode.
+- Fallback config supports per-agent chain arrays and retry/backoff values.
+
+## Control flow and dependencies
 
 ```text
 src/index.ts
   └─> loadPluginConfig(directory)
-      └─> PluginConfig
-          ├─> createAgents(config)         (agents/index.ts)
-          ├─> fallback chain setup          (index.ts runtime)
-          ├─> interview/dashboard config    (interview/*)
-          ├─> council session config        (council/*)
-          ├─> multiplexer mode            (multiplexer/*)
+      ├─> Agent override application in src/agents/index.ts
+      ├─> MCP defaults/filters in src/config/agent-mcps.ts
+      ├─> Council session behavior in src/council/*
+      ├─> Fallback/session behavior in runtime hooks
+      └─> Multiplexer behavior in src/multiplexer/*
 ```
 
 ### Key collaborators
 
+- `constants.ts`
+  - names/aliases, orchestratable lists, default models/timeouts/modes.
 - `agent-mcps.ts`
-  - default MCP lists per agent
-  - wildcard/deny list parser (`parseList`)
-  - available MCP discovery with `disabled_mcps`
+  - `getAgentMcpList`, `parseList`, `getAvailableMcpNames`.
 - `utils.ts`
-  - `getAgentOverride` with alias compatibility (`explore` -> `explorer`, etc.)
-  - `getCustomAgentNames`
-- `constants.ts`
-  - built-in names, aliases, delegation matrices
+  - alias resolution and custom-agent key discovery.
+- `loader.ts`
+  - config IO, deep merge, preset composition, env override, prompt loading.
+- `schema.ts`, `council-schema.ts`
+  - type/shape validation + transformation.
 
 ## File structure
 
-- `index.ts` — export surface
-- `loader.ts` — load, merge, prompt-loading helpers
-- `schema.ts` — main zod schema and type exports
-- `constants.ts` — names, defaults, timeouts, delegation policy, fallback constants
-- `agent-mcps.ts` — MCP defaults and filtering
+- `index.ts` — exported config surface
+- `loader.ts` — load, merge, prompt resolution, tmux migration
+- `schema.ts` — plugin config + agent override schemas
+- `council-schema.ts` — council-specific and legacy compatibility schema
+- `constants.ts` — defaults, names, delegation rules, timeouts
+- `agent-mcps.ts` — MCP defaults and allow-list parsing
 - `utils.ts` — config helper methods
-- `council-schema.ts` — council preset/result/deprecated-field schema

+ 82 - 39
src/council/codemap.md

@@ -2,57 +2,100 @@
 
 ## Responsibility
 
-`src/council/` executes multi-LLM consensus sessions.
+`src/council/` orchestrates parallel/serial multi-LLM council sessions and produces
+normalized councillor results for the `council` agent to synthesize.
 
-It owns council orchestration and result normalization, while the actual `council` agent remains in `agents/council.ts`.
+It is intentionally execution-focused:
+
+- validate council configuration + preset selection,
+- launch and monitor councillor sub-sessions,
+- normalize outputs + retry behavior,
+- return a structured result object to the caller tool.
+
+Prompt templates and tool schemas are defined in `agents/` and `tools/`.
 
 ## Architecture
 
-- `council.ts` is a barrel that exports `CouncilManager`.
-- `council-manager.ts` is the engine:
-  - validates preset selection and depth constraints
-  - launches councillor sessions
-  - retries on empty provider responses
-  - formats outputs for synthesis by caller tool
+- `council-manager.ts` is the core engine.
+- `index.ts` is the module barrel.
+
+### council-manager responsibilities
+
+- Reads injected plugin context (`PluginInput`) and optional:
+  - config (`PluginConfig`),
+  - `SubagentDepthTracker`,
+  - `tmuxEnabled` flag for pane launch pacing.
+- Owns runtime helpers:
+  - `runCouncil()` orchestration entry,
+  - `runCouncillors()` fan-out strategy,
+  - `runCouncillorWithRetry()` and `runAgentSession()` for per-councillor lifecycle.
+- Uses shared session utilities from `utils/session.ts`:
+  - `parseModelReference` for model string validation,
+  - `promptWithTimeout` for bounded prompt calls,
+  - `extractSessionResult` to collect assistant text,
+  - `shortModelLabel` for UI-friendly model names.
+- Delegates prompt/result shaping to `formatCouncillorPrompt` and
+  `formatCouncillorResults` in `agents/council.ts`.
 
 ## Runtime flow
 
 ```text
-runCouncil(prompt, preset, parentSessionId)
-  ├─> enforce depth via SubagentDepthTracker
-  ├─> load council config
-  ├─> resolve preset (default if absent)
-  ├─> run all councillors in parallel or serial mode
-  │     - each councillor session: create -> prompt -> extract -> abort
-  │     - tmux delay + stagger delay for launch collisions
-  │     - retry on empty response up to configured retry count
-  ├─> if none completed -> error
-  └─> formatCouncillorResults(prompt, completed responses)
+runCouncil(prompt, presetName?, parentSessionId)
+  ├─> enforce max depth with SubagentDepthTracker
+  ├─> load council config from plugin config
+  ├─> resolve preset (fallback: default_preset -> "default")
+  ├─> fail fast when preset missing or empty
+  ├─> emit start notification to parent session (best-effort, non-blocking)
+  ├─> resolve runtime policy
+  │     timeout, execution mode, retry budget
+  ├─> run councillors in selected mode
+  │     - runAgentSession: create -> register depth -> optional tmux delay
+  │       -> prompt -> extract text -> session abort in finally
+  │     - runCouncillorWithRetry: retries only "Empty response from provider"
+  │       up to `councillor_retries`
+  │     - parallel mode uses indexed staggering to reduce pane launch collisions
+  ├─> aggregate results with per-councillor status
+  ├─> if no completed councillors: return failure result
+  └─> format and return results for caller synthesis
 ```
 
-Execution characteristics:
+## Error and result model
+
+- Each councillor returns status:
+  - `completed` with `result` text,
+  - `failed` with `error`,
+  - `timed_out` with timeout message.
+- Empty provider responses are treated as failures unless failover retry-on-empty is disabled
+  via `fallback.retry_on_empty`.
+- A single councillor's malformed model string is surfaced as failure for that councillor; the
+  session still proceeds with the remaining councillors.
+- Depth limit violations return a hard failure (`Subagent depth exceeded`) without starting
+  any councillor session.
+
+## Configuration semantics (delegated to schema)
+
+Validated in `config/council-schema.ts` and consumed in `runCouncil`:
 
-- Uses `councillor` agent internally (`agent: 'councillor'`), `tools.task: false`.
-- Timeout is passed per session.
-- Empty results are treated as failures unless global fallback policy disables empty-retry behavior.
-- Failed/timed out results are still returned as structured metadata (`name`, `model`, `status`, `error`).
-- On start, writes a non-blocking session note to parent session via `session.prompt`.
+- `presets` with per-preset councillor definitions,
+- `default_preset`,
+- `timeout`,
+- `councillor_execution_mode` (`parallel`/`serial`),
+- `councillor_retries`.
 
-### Configuration semantics
+Legacy schema behavior:
 
-- Preset schema in `config/council-schema.ts`:
-  - per-preset named councillors
-  - `default_preset`
-  - `timeout`
-  - `councillor_execution_mode` (`parallel`/`serial`)
-  - `councillor_retries`
-- Deprecated master fields are accepted in schema, ignored, and surfaced as runtime warnings through `getDeprecatedFields()`.
+- nested legacy `councillors` keys are unwrapped,
+- top-level `master` key is ignored at preset level,
+- deprecated `master` fields are recorded (via `_deprecated`) and surfaced to the caller
+  as warnings, while `_legacyMasterModel` is kept for fallback messaging.
 
-## Integration
+## Integration points
 
-- `tools/council.ts` defines `council_session` and is the only caller that invokes `CouncilManager.runCouncil(...)`.
-- Integrates with:
-  - `config` (for preset/timeouts/retry policy)
-  - `SubagentDepthTracker` (to prevent nested delegation explosions)
-  - session client (`client.session.*`) for sub-session lifecycle
-  - `multiplexer` settings (tmux launch delay behavior)
+- **Tool caller:** `tools/council.ts` creates `council_session` and calls
+  `runCouncil(prompt, preset, parentSessionId)`.
+- **Plugin init:** `src/index.ts` constructs `CouncilManager` with runtime config,
+  `SubagentDepthTracker`, and multiplexer capability before exposing `council_session`.
+- **Depth lifecycle:** `SubagentDepthTracker` is also used in plugin event hooks to register/
+  cleanup child sessions as they are created/deleted.
+- **Runtime constants:** `config/constants.ts` provides launch delays (`TMUX_SPAWN_DELAY_MS`,
+  `COUNCILLOR_STAGGER_MS`) used to avoid multiplexer collision.

+ 17 - 8
src/hooks/codemap.md

@@ -10,17 +10,20 @@ and managers for all hook-based runtime behaviors used by
   without depending on subfolder internals.
 - Describe lifecycle boundaries between OpenCode hook surfaces and internal state
   machines that coordinate retries, timers, and session tracking.
+- Centralize all hook feature entry points used by orchestrator tooling,
+  delegation/task workflows, and session lifecycle handlers.
 
 ## Design
 
 - `src/hooks/index.ts` re-exports per-feature factories and managers.
 - Most features implement the `create*Hook(ctx, config?)` factory pattern and
-  return one or more lifecycle callbacks.
+  return lifecycle callbacks.
 - Foreground fallback is provided as a manager class (`ForegroundFallbackManager`)
   with an explicit `handleEvent` method.
-- Each module keeps side effects behind narrow public boundaries:
-  `createDelegateTaskRetryHook`, `createJsonErrorRecoveryHook`,
-  `createTodoContinuationHook`, etc.
+- `task-session-manager` persists resumable task sessions per parent session and
+  per agent, with bounded history and aliasing.
+- Side effects are limited to exported handlers and dedicated utility functions
+  to keep hook behavior deterministic.
 - Runtime integration depends on `PluginInput.client` for session APIs and shared
   utilities (`log`, marker constants, prompt helpers).
 
@@ -45,14 +48,14 @@ and managers for all hook-based runtime behaviors used by
 
 | Hook Point | Purpose | Implementations |
 |---|---|---|
-| `tool.execute.before` | Pre-process tool inputs | `apply-patch` |
-| `tool.execute.after` | Post-process tool outputs | `delegate-task-retry`, `json-error-recovery`, `post-file-tool-nudge` |
+| `tool.execute.before` | Pre-process tool inputs | `apply-patch`, `task-session-manager` |
+| `tool.execute.after` | Post-process tool outputs | `delegate-task-retry`, `json-error-recovery`, `post-file-tool-nudge`, `task-session-manager` |
 | `experimental.chat.messages.transform` | Rewrite outbound user content | `filter-available-skills`, `phase-reminder` |
-| `experimental.chat.system.transform` | Inject system-level directives | `todo-continuation`, `post-file-tool-nudge` |
+| `experimental.chat.system.transform` | Inject system-level directives | `todo-continuation`, `post-file-tool-nudge`, `task-session-manager` |
 | `chat.headers` | Mutate request headers | `chat-headers` |
 | `chat.message` | Track runtime session/agent mapping | `todo-continuation` |
 | `command.execute.before` | Handle slash-command UX | `todo-continuation` (`auto-continue`) |
-| `event` | React to session lifecycle and runtime failures | `foreground-fallback`, `todo-continuation`, `post-file-tool-nudge`, `auto-update-checker`, multiplexer managers |
+| `event` | React to session lifecycle and runtime failures | `foreground-fallback`, `todo-continuation`, `post-file-tool-nudge`, `auto-update-checker`, multiplexer managers, `task-session-manager` |
 
 ## Implementation Notes
 
@@ -65,10 +68,16 @@ and managers for all hook-based runtime behaviors used by
   system transform, command interception, tool-after, and events. It owns
   auto-injection state, cooldown, suppress windows, and orchestration session
   tracking.
+- `createTaskSessionManagerHook` tracks task sessions for resumability: generates
+  user-facing aliases, resolves alias/task IDs before delegation, remembers fresh
+  task IDs after completion, and drops stale entries on missing-session failure,
+  renamed task IDs, or session deletion.
 
 ## Integration
 
 - `src/index.ts` is the sole runtime consumer and determines final registration
   order so composed transforms (system joins, reminder insertion, hygiene) stay
   deterministic.
+- `taskSessionManager` is registered in `tool.execute.before`, `tool.execute.after`,
+  `experimental.chat.system.transform`, and `event`, with parent/child cleanup.
 - The `src/hooks/*/codemap.md` files document each feature internals.

+ 30 - 29
src/hooks/foreground-fallback/codemap.md

@@ -3,51 +3,52 @@
 ## Responsibility
 
 Provides reactive model fallback for foreground (interactive) sessions when
-runtime rate-limit indicators are observed.
+rate-limit or provider-limit signals are observed in event streams.
 
 ## Design
 
 - `index.ts` exports:
   - `ForegroundFallbackManager`
   - `isRateLimitError(error)`
-- Manager state is session-scoped maps for:
+- Manager state is per-session maps for:
   - active model (`sessionModel`)
   - mapped agent (`sessionAgent`)
   - attempted models (`sessionTried`)
   - dedupe timestamp (`lastTrigger`)
   - in-flight fallback lock (`inProgress`)
-- Rate-limit detection uses fixed regexes over message/error text and response
-  metadata (`statusCode`, `message`, `responseBody`).
-- Fallback selection is deterministic via `resolveChain(agentName, currentModel)`:
-  1. exact agent chain (if known)
-  2. no fallback if agent known but unconfigured
-  3. infer chain from current model
-  4. deduplicated flattening of all chains as fallback.
+- Rate-limit detection is regex based and also checks structured payload fields
+  (`message`, `statusCode`, `data.message`, `data.responseBody`).
+- Fallback selection uses `resolveChain(agentName, currentModel)` with ordered
+  priority:
+  1. exact agent chain (if configured)
+  2. no-chain if agent is known but unconfigured
+  3. infer from current model
+  4. flattened fallback across all chains
+- Re-submission uses `client.session.promptAsync` with last-user message parts and
+  parsed `{ providerID, modelID }` target.
 
 ## Flow
 
-1. `handleEvent` receives each OpenCode event from the plugin’s global event
-   surface.
-2. On `message.updated`, `session.error`, or retry `session.status`, the
-   manager checks for rate-limit signatures.
-3. When matched, `tryFallback(sessionID)` runs with guards:
-   - disabled feature toggle,
-   - in-progress lock,
+1. `handleEvent` receives each plugin event.
+2. On `message.updated`, `session.error`, and retry `session.status`, it checks
+   rate-limit markers and calls `tryFallback(sessionID)` when matched.
+3. `subagent.session.created` updates session-to-agent mappings for better chain
+   resolution.
+4. `tryFallback(sessionID)` enforces:
+   - feature enablement flag,
+   - one-at-a-time lock,
    - dedupe window (`DEDUP_WINDOW_MS = 5000`).
-4. It resolves the chain, marks the current model as tried, and selects the next
-   untried model.
-5. It fetches messages, finds the last user turn, aborts the current session,
-   waits briefly (500ms), then reissues that user parts using `session.promptAsync`
-   with a parsed `{ providerID, modelID }`.
-6. On success it updates `sessionModel`; on failures, logs structured fallback
-   errors.
-7. On `session.deleted`, all per-session maps are removed to prevent memory
+5. It marks current model attempted, chooses next untried model from the chain,
+   fetches latest user message via `session.messages`, aborts the active prompt via
+   `session.abort()`, waits 500ms, and re-prompts with `promptAsync`.
+6. Success updates session model memory; failures log structured diagnostics.
+7. `session.deleted` cleanup removes all per-session bookkeeping to avoid memory
    growth.
 
 ## Integration
 
-- Wired via plugin-level `event` hook in `src/index.ts`.
-- Uses `ctx.client.session` APIs (`messages`, `abort`, `promptAsync`) and is
-  independent of delegation/council logic.
-- Intended as a runtime safety net when startup-time model selection cannot avoid
-  transient provider limits.
+- Wired through plugin-level `event` hook in `src/index.ts`.
+- Uses `ctx.client.session` APIs (`messages`, `abort`, `promptAsync`) and
+  depends on runtime fallback chains provided from configuration.
+- Designed as an interactive-session safety net when delegated/caller-side retry
+  logic is unavailable or too late.

+ 60 - 0
src/hooks/task-session-manager/codemap.md

@@ -0,0 +1,60 @@
+# src/hooks/task-session-manager/
+
+## Responsibility
+
+Provides resumable-task state for `task` tool calls so orchestrator users can
+resume work in a parent session by using short aliases (`exp-1`, `ora-2`) instead
+of raw child session IDs.
+
+## Design
+
+- `createTaskSessionManagerHook(ctx, options)` returns handlers for:
+  - `tool.execute.before`
+  - `tool.execute.after`
+  - `experimental.chat.system.transform`
+  - `event`
+- Internally uses `SessionManager` from `src/utils/session-manager.ts` to store
+  remembered task sessions with bounded per-agent history.
+- Task labels are derived from `description`/`prompt` via
+  `deriveTaskSessionLabel` and converted to compact aliases by `SessionManager`.
+- In-flight calls are tracked by `callID` in a capped ordered map (`MAX_PENDING_TASK_CALLS`)
+  to rewrite inputs and correlate outputs safely.
+- Session governance is feature-gated by `shouldManageSession(sessionID)`, allowing
+  the hook to run only for orchestrator-managed sessions.
+
+## Flow
+
+1. `tool.execute.before` receives a `task` call.
+2. If `subagent_type` is a recognized agent, it derives a short label.
+3. When `task_id` is provided, it attempts resolution against remembered aliases
+   for the current parent session/agent.
+4. On success, `args.task_id` is rewritten to the real task ID; on miss it is
+   removed to force fresh task creation.
+5. The call metadata is stored in the pending-call map to correlate the
+   subsequent post-tool event.
+6. `tool.execute.after` reads the output task ID from `task` output text.
+7. On first successful parse, it `remember()`s the task entry and associates it
+   with the alias map.
+8. If this call was a resume attempt, and the returned ID changed, the stale
+   predecessor alias is dropped.
+9. If resume returns an error like `[ERROR] Session not found`/`Session no
+   session`, the predecessor alias is dropped so future commands fall back to
+   fresh execution.
+10. `experimental.chat.system.transform` injects a rendered block from
+    `SessionManager.formatForPrompt` under `### Resumable Sessions`.
+11. On `session.deleted`, the hook clears all task state for that parent session
+    and removes any pending task call records for that parent.
+
+## Integration
+
+- Wired in `src/index.ts`:
+  - invoked in `tool.execute.before`
+  - invoked in `tool.execute.after`
+  - injected into `experimental.chat.system.transform`
+  - cleaned up in `event` on `session.deleted`
+- Exposes no side effects outside hook handling and `SessionManager`.
+- Depends on:
+  - `SessionManager` and `deriveTaskSessionLabel` (from `src/utils/session-manager.ts`)
+  - `parseTaskIdFromTaskOutput` (from `src/utils/task.ts`)
+  - plugin configuration (`maxSessionsPerAgent`) and runtime session filtering from
+    `src/index.ts` (`shouldManageSession`).

+ 119 - 100
src/interview/codemap.md

@@ -2,113 +2,132 @@
 
 ## Responsibility
 
-- Implement the `/interview` command with session prompt orchestration, interview markdown persistence, and a local HTTP interface.
-- Run in one of two modes:
-  - per-session server mode (default)
-  - shared dashboard mode (for multi-process/session sharing).
-- Keep interview lifecycle synchronized between:
-  - in-memory interview/session maps,
+- Implement the `/interview` command flow:
+  - command registration and pre-exec interception,
+  - interactive stateful interview prompts,
+  - markdown document generation/persistence,
+  - local HTTP UI server and shared dashboard mode.
+- Keep interview lifecycle synchronized across:
+  - in-memory session/interview maps,
   - markdown artifacts under `outputFolder`,
-  - dashboard cache entries for resume/recovery.
+  - dashboard cache used for cross-process recovery and browser polling.
+- Support two runtime modes:
+  - **per-session mode** (local interview server)
+  - **dashboard mode** (distributed cache + shared interview pages).
 
 ## Design
 
-- `manager.ts` is the composition root and returns:
-  - `registerCommand`
-  - `handleCommandExecuteBefore`
-  - `handleEvent`
-- It creates one `createInterviewService(ctx, interviewConfig)` and selects mode via:
-  - `interview.dashboard === true || interview.port > 0`.
-
-### `createInterviewService` (`service.ts`)
-
-- Owns interview orchestration state:
-  - `interviewsById`, `activeInterviewIds`, `sessionBusy`, `fileCache`.
-- Creates/resumes interviews via:
-  - `resolveExistingInterviewPath`, `createInterview`, `resumeInterview`.
-- Ensures markdown and URLs are prepared with `document.ts` helpers, then notifies users with `notifyInterviewUrl`.
-- Re-hydrates interview state from messages via `syncInterview`:
-  - loads new messages,
-  - parses latest `<interview_state>` using `parseAssistantState` / `findLatestAssistantState` (`parser.ts`) with zod-backed validation,
-  - rebuilds fallback state when needed,
-  - computes mode (`awaiting-agent`, `awaiting-user`, `completed`, `error`, `abandoned`).
-- Handles UI-facing mutation:
-  - `submitAnswers` validates active questions and injects answer prompts via `session.promptAsync`.
-  - `handleNudgeAction` injects either continuation questions or finalization directives.
-- Handles OpenCode events:
-  - `session.status` updates `sessionBusy`,
-  - `session.deleted` marks active interview as abandoned and cleans the maps.
-
-### `createInterviewServer` (`server.ts`)
-
-- Lightweight HTTP server used in per-session mode and for rendering UI views.
-- Routes:
-  - `GET /` and `GET /api/interviews` (dashboard list APIs)
-  - `GET /interview/{id}` (interview page)
-  - `GET /api/interviews/{id}/state`
-  - `POST /api/interviews/{id}/answers`
-  - `POST /api/interviews/{id}/nudge`
-- Converts service errors into HTTP status (`400/404/409/500`) and delegates rendering to `ui.ts`.
-
-### `dashboard.ts`
-
-- Implements shared dashboard process behavior and transport contract.
-- `createDashboardServer` maintains:
-  - random auth token and local auth file (`.dashboard-<port>.json`),
-  - session registry, manual/discovered folders, and TTL-scoped session state cache,
-  - pending answers/nudge queues with consume-on-read semantics.
-- Adds resilience:
-  - `rebuildFromFiles()` reconstructs state from markdown when sessions rejoin,
-  - session discovery via session client + folder scanners,
-  - periodic cleanup of terminal interview states.
-- Public endpoints include:
-  - `GET /api/health`, `/api/settings`, `/api/sessions`, `/api/files`,
-  - `POST /api/register`, `/api/interviews` (create), `/api/interviews/{id}/state`,
-  - `/pending` and `/nudge` GET/POST paths for agent/browser sync.
-
-### Supporting modules
-
-- `document.ts`: path normalization, markdown creation/rewrite/read, and frontmatter/title/summary extraction.
-- `parser.ts`: `parseInterviewState` + `findLatestAssistantState` state extraction pipeline.
-- `prompts.ts`: command/answer/nudge prompt builders.
-- `helpers.ts`: request parsing and HTTP response helpers.
-- `types.ts`: domain contracts and zod schemas (`InterviewRecord`, `InterviewState`, `InterviewStateEntry`, `RawInterviewStateSchema`, `RawQuestionSchema`).
+- `index.ts` exports `createInterviewManager`.
+
+- `manager.ts` (composition root)
+  - Creates `createInterviewService(ctx, interviewConfig)` once.
+  - Chooses mode via
+    `interview.dashboard === true || interview.port > 0`.
+  - In dashboard mode:
+    - calls `tryBecomeDashboard(...)` to elect one process as dashboard,
+    - non-dashboard processes read auth token via `readDashboardAuthFile(port)`,
+    - sessions are registered with `/api/register` and sync state back via `/api/interviews/{id}/state`,
+    - 10-second fallback polling keeps answer/nudge delivery active if needed.
+  - Returns event hooks:
+    `registerCommand`, `handleCommandExecuteBefore`, `handleEvent`.
+
+- `createInterviewService` (`service.ts`)
+  - Manages interview domain maps:
+    - `interviewsById`, `activeInterviewIds`, `sessionBusy`, `sessionModel`.
+  - Creates and resumes interviews:
+    - `resolveExistingInterviewPath`, `createInterview`, `resumeInterview`.
+  - Syncs state from session messages:
+    - loads messages,
+    - extracts assistant state via `findLatestAssistantState`,
+    - fallbacks through `buildFallbackState` when needed,
+    - rewrites markdown with `rewriteInterviewDocument`.
+  - Injects prompts:
+    - kickoff (`buildKickoffPrompt`),
+    - resume (`buildResumePrompt`),
+    - answer/nudge handling (`buildAnswerPrompt`, `handleNudgeAction`).
+  - Handles events:
+    - `session.status` updates busy tracking,
+    - `session.deleted` marks interview abandoned and drains maps.
+  - Pushes updates:
+    - `onStateChange` callback for dashboard mode,
+    - `onInterviewCreated` callback for immediate registration,
+    - optional `openBrowser` for initial UI open.
+
+- `createInterviewServer` (`server.ts`)
+  - Owns the per-session HTTP endpoints and HTML renderer binding.
+  - Supports:
+    - `GET /`, `GET /api/interviews`, `GET /interview/{id}`
+    - `GET /api/interviews/{id}/state`
+    - `POST /api/interviews/{id}/answers`
+    - `POST /api/interviews/{id}/nudge`
+  - Maps domain errors to HTTP status in `getSubmissionStatus`.
+
+- `dashboard.ts`
+  - Implements a shared dashboard server and state cache.
+  - Auth path:
+    - random token written to `${XDG_DATA_HOME}/opencode/.dashboard-<port>.json`,
+    - validated via cookie, query token, or Bearer header.
+  - In-memory state/cache contracts:
+    - `sessions` registry,
+    - `stateCache` keyed by interview ID,
+    - pending answers and nudge actions with consume-on-read semantics.
+  - Recovery/scan:
+    - periodic `rebuildFromFiles()` from markdown frontmatter,
+    - session directory discovery via SDK + manual folders,
+    - file scanning in known directories and cached file lists.
+  - TTL cleanup removes terminal states after 24h.
+
+- Supporting modules:
+  - `document.ts`: markdown/file helpers (`slugify`, path resolution, frontmatter,
+    title/summary extraction).
+  - `parser.ts`: assistant state parse pipeline (`parseInterviewState`,
+    `findLatestAssistantState`, `buildFallbackState`).
+  - `prompts.ts`: prompt templates for create/resume/answer/nudge.
+  - `helpers.ts`: request parsing and HTML/JSON response helpers.
+  - `types.ts`: domain schemas and interview contracts.
 
 ## Flow
 
-- `src/index.ts` initializes interview plugin integration through `createInterviewManager(ctx, config)`.
-
-- **Per-session mode** (`dashboard` false / port=0):
-  - service built, output folder resolved from `interview.outputFolder`,
-  - server started lazily through `createInterviewServer({ port: 0 })`,
-  - manager forwards hooks directly to service callbacks.
-
-- **Dashboard mode** (`dashboard` true or port > 0):
-  1. `createInterviewManager` calls `tryBecomeDashboard`.
-  2. If elected, process becomes dashboard:
-     - keep in-process cache via `statePushCallback` and `setOnInterviewCreated`,
-     - self-register and refresh directories with `discoverSessionDirectories` + `refreshFiles`,
-     - expose auth token for sibling sessions.
-  3. If not elected, process becomes session:
-     - reads token via `readDashboardAuthFile`,
-     - registers via `POST /api/register`,
-     - pushes state to dashboard via `POST /api/interviews/{id}/state`,
-     - sends newly created interview metadata via `POST /api/interviews`,
-     - starts periodic poll timer (10s) for `/pending` and `/nudge`.
-  4. If dashboard probe fails after retry, it falls back to local per-session server.
-
-- `handleCommandExecuteBefore`:
-  - blank argument with no active interview → asks user for idea,
-  - matching slug/path → resume flow,
-  - otherwise create new interview and inject kickoff prompt.
-
-- `handleEvent`:
-  - on `session.status.idle`: consume pending dashboard actions then refresh state,
-  - on `session.deleted`: unregister session and remove linked dashboard entries.
+- `src/index.ts` wires this folder through
+  `createInterviewManager(ctx, config)`.
+
+- **Per-session mode**
+  - service created and bound to a lazy `createInterviewServer({ port: 0 })`,
+  - command hook calls flow directly into service.
+
+- **Dashboard mode**
+  1. `createInterviewManager` invokes `tryBecomeDashboard`.
+  2. Dashboard election succeeds:
+     - dashboard keeps local cache callbacks (`setStatePushCallback`,
+       `setOnInterviewCreated`),
+     - self-registers session directory and rebuilds file-derived state.
+  3. Election fails:
+     - process becomes client session,
+     - reads token file,
+     - registers with dashboard,
+     - pushes state + interview creation over HTTP,
+     - polls `/pending` and `/nudge` on idle.
+  4. If probe+fallback fails twice, manager falls back to per-session server.
+
+- `handleCommandExecuteBefore`
+  - blank input with no active interview starts ideation,
+  - matching slug/path resumes an existing interview,
+  - otherwise creates a new interview and injects kickoff prompt.
+
+- `handleEvent`
+  - on `session.status: idle`:
+    - consume dashboard pending answers/nudge first,
+    - then refresh interview state so `sessionBusy` is reflected accurately.
+  - on `session.deleted`:
+    - unregisters session from the dashboard and local bookkeeping.
 
 ## Integration
 
-- All runtime calls remain through manager methods returned to `src/index.ts`.
-- Integrates directly with OpenCode session client for message reads and prompt injection.
-- Outputs are surfaced to users by sending interview URLs back through the same session prompt stream.
-- Dashboard and server flows are validated in `src/interview/*test.ts`.
+- Used by `src/index.ts` as the interview plugin module.
+- Uses OpenCode SDK session APIs for messages, prompts, and status events.
+- Uses local HTTP server contracts for:
+  - dashboard browsing,
+  - browser ↔ session sync endpoints,
+  - manual file/discovery settings.
+- Existing tests cover service, parser, manager, server, dashboard, and helpers
+  under `src/interview/*.test.ts`.

+ 75 - 28
src/multiplexer/codemap.md

@@ -2,40 +2,87 @@
 
 ## Responsibility
 
-- Abstract terminal multiplexer integration for delegated session visualization.
-- Resolve backend by configuration and environment (`auto`, `tmux`, `zellij`, `none`).
-- Coordinate pane lifecycle and fallback cleanup for spawned child sessions.
+- Provide multiplexer-backed visualization for spawned subagent sessions.
+- Select and instantiate terminal backend based on config/env:
+  `auto`, `tmux`, `zellij`, or `none`.
+- Manage lifecycle of child session panes with lifecycle hooks from OpenCode
+  events plus health/polling fallback.
+- Keep pane cleanup safe and graceful (best-effort interrupt + kill).
 
 ## Design
 
-- `types.ts` defines the boundary contract:
-  - `Multiplexer` (`spawnPane`, `closePane`, `applyLayout`, `isAvailable`, `isInsideSession`).
-  - `PaneResult` and `MultiplexerFactory`.
-  - `isServerRunning(serverUrl, timeoutMs?, maxAttempts?)` and `getAutoMultiplexerType` helpers.
-- `factory.ts` selects concrete implementation in `getMultiplexer(config)`:
-  - explicit `tmux`/`zellij` backends
-  - `auto` mode using `TMUX` / `ZELLIJ` env detection
-  - per-call construction for live environment fidelity
-- `session-manager.ts` implements `MultiplexerSessionManager`, with `TmuxSessionManager` as alias for compatibility.
-- `index.ts` re-exports manager/factory contracts and concrete `TmuxMultiplexer` / `ZellijMultiplexer` implementations.
-
-### `session-manager.ts`
-
-- Listens to OpenCode events through `src/index.ts` wiring:
-  - `session.created`: validate server availability and call `spawnPane`.
-  - `session.status`: close child pane when status becomes `idle`.
-  - `session.deleted`: close child pane proactively.
-- Maintains an in-memory tracked-session map with stale-status timeout fallback.
-- Runs optional polling (`POLL_INTERVAL_BACKGROUND_MS`) as a resilience path when status streaming is incomplete.
+- `types.ts`
+  - Defines shared abstractions:
+    - `Multiplexer` (`spawnPane`, `closePane`, `applyLayout`, `isAvailable`,
+      `isInsideSession`),
+    - `PaneResult`,
+    - `isServerRunning(serverUrl, timeoutMs?, maxAttempts?)` for readiness checks.
+
+- `factory.ts`
+  - Creates fresh multiplexer instance per call (no cache) so env-specific
+    state (`TMUX`, `ZELLIJ`) is captured accurately.
+  - `auto` mode resolves strictly by env vars and can become no-op `none`.
+  - Exposes `getAutoMultiplexerType` and `startAvailabilityCheck` for diagnostics.
+
+- `tmux/index.ts` (`TmuxMultiplexer`)
+  - Detects binary lazily via `which/where` + `tmux -V`.
+  - `spawnPane` executes `opencode attach` in a split pane,
+    sets pane title, and applies layout.
+  - `closePane` sends `C-c`, waits briefly, then `kill-pane`.
+  - `applyLayout` handles main layout sizing and rebalance.
+
+- `zellij/index.ts` (`ZellijMultiplexer`)
+  - Detects and reuses/creates `opencode-agents` tab.
+  - First child uses default pane in that tab; additional children create panes.
+  - Falls back to first available pane ID heuristics and restores original tab
+    context around cross-tab operations.
+  - Layout configuration is accepted but effectively no-op (tool semantics differ
+    from tmux).
+
+- `session-manager.ts` (`MultiplexerSessionManager`)
+  - Initialized once from plugin context and config.
+  - Subscribes to lifecycle events:
+    - `session.created`: spawn pane if enabled and not already tracked,
+    - `session.status`: close on `idle`, respawn on `busy` when known,
+    - `session.deleted`: close pane and clear tracking.
+  - Tracks:
+    - active panes (`sessions` map),
+    - known sessions (`knownSessions`),
+    - in-flight spawns (`spawningSessions`).
+  - `respawnIfKnown` handles busy sessions that reappear after being closed.
+  - Polling fallback (`pollSessions`) is enabled when event coverage is incomplete.
+    It handles:
+    - idle detection,
+    - missing status grace period,
+    - max session lifetime timeout.
+
+- `index.ts`
+  - Re-exports factory, manager, and implementations for external import.
 
 ## Flow
 
-- `src/index.ts` reads multiplexer config, instantiates `MultiplexerSessionManager`, and starts optional startup availability checks.
-- Runtime handlers call `onSessionCreated`, `onSessionStatus`, and `onSessionDeleted` on delegated-session events.
-- Backend adapters execute pane operations while preserving session mapping and graceful shutdown semantics.
+- `src/index.ts` reads multiplexer config and creates
+  `MultiplexerSessionManager(ctx, config)`.
+- On startup `getMultiplexer(config)` determines backend and whether manager is
+  enabled (`type != none`, multiplexer present, running inside session).
+- On `session.created`:
+  - checks backend health via `isServerRunning(serverUrl)`,
+  - spawns a new pane,
+  - starts background polling.
+- On `session.status`:
+  - `idle` → `closeSession` (close pane + remove mapping),
+  - `busy` → `respawnIfKnown` if session was previously known.
+- On `session.deleted`:
+  - close and remove pane, clear known-session mapping.
+- `cleanup()` closes all panes and clears tracking maps.
 
 ## Integration
 
-- Used by `src/index.ts` for delegated session visualization and cleanup.
-- Implementations live in `src/multiplexer/tmux` and `src/multiplexer/zellij`; callers pass `(sessionId, description, serverUrl, directory)` to spawn panes.
-- Unit tests in `src/multiplexer/factory.test.ts` and `src/multiplexer/session-manager.test.ts` validate mode selection and lifecycle behavior.
+- Integrates with OpenCode session events and server URL from plugin input.
+- Uses helper endpoints defined by `src/config` multiplexer settings:
+  `type`, `layout`, `main_pane_size`.
+- Implementations in `src/multiplexer/tmux` and `src/multiplexer/zellij` are used
+  through the shared abstraction.
+- Validation coverage:
+  - `src/multiplexer/factory.test.ts`
+  - `src/multiplexer/session-manager.test.ts`

+ 87 - 54
src/tools/codemap.md

@@ -2,57 +2,90 @@
 
 ## Responsibility
 
-- Expose plugin tool definitions for code intelligence and workflow tooling from
-  `src/tools/index.ts`.
-- Publish three operational domains:
-  - AST pattern search/replace via `ast-grep/`.
-  - URL fetch/transform via `smartfetch/` with optional secondary-model pass.
-  - Council orchestration via `createCouncilTool` (`council.ts`).
-
-## Design
-
-- `src/tools/index.ts` is the export surface and re-exports:
-  - `ast_grep_search`, `ast_grep_replace`.
-  - `createWebfetchTool`.
-  - `createCouncilTool`.
-- Shared schema contract: tool definitions are typed with `@opencode-ai/plugin`/`@opencode-ai/plugin/tool` and return `ToolDefinition` objects.
-
-### AST-grep stack (`ast-grep/`)
-
-- `cli.ts` owns execution path (`runSg`, `getAstGrepPath`, background init).
-- `constants.ts` centralizes binary resolution, execution limits, and formatting helpers.
-- `downloader.ts` handles release metadata lookup, download, and extraction for missing CLI.
-- `utils.ts` formats matches/replacements for user-facing output.
-
-### Smartfetch stack (`smartfetch/`)
-
-- `tool.ts` owns permission prompts, cache check, fetch orchestration, binary/content branching.
-- `network.ts` enforces redirect policy, response size caps, and binary/content detection.
-- `cache.ts` memoizes by normalized URL + behavior-affecting options (`CACHE`).
-- `utils.ts` performs extraction/normalization of text/markdown/html payloads.
-- `binary.ts` stores binary payloads and returns deterministic metadata.
-- `secondary-model.ts` drives optional post-fetch summarization with fallback.
-
-## Flow
-
-- **AST-grep path**
-  - Tool call resolves schema input and invokes `runSg`.
-  - `runSg` resolves CLI binary, executes with timeout, parses JSON results,
-    then renders search/replace output.
-
-- **Smartfetch path**
-  - Permission + timeout + cache checks in `createWebfetchTool`.
-  - Respect preferred `llms.txt` probing and redirect constraints.
-  - Apply content-type branching and optional secondary-model summarization.
-  - Emit text markdown/html, metadata message, or binary metadata handle.
-
-- **Council tool path**
-  - `createCouncilTool` checks caller context (`orchestrator`/`council`) and
-    invokes `CouncilManager.runCouncil` with parent session context.
-
-## Integration
-
-- `src/index.ts` registers these tools into the plugin tool surface.
-- `src/council/council-manager.ts` consumes `createCouncilTool` output for
-  explicit consensus runs.
-- Tests and agents import from `src/tools/*` for type-safe contracts and fixture-driven execution.
+`src/tools/` exposes plugin tooling and runtime command hooks used by OpenCode.
+
+- AST-aware search/replace via `ast-grep` stack.
+- Remote fetch/transform utility via `smartfetch` (`webfetch` tool).
+- Council orchestration via `createCouncilTool` (`council.ts`).
+- Runtime preset switching via `/preset` hook via `createPresetManager` (`preset-manager.ts`).
+
+It is the bridge between plugin runtime integration (`src/index.ts`) and the lower-level
+implementations in feature folders.
+
+## Export surface (`src/tools/index.ts`)
+
+- `ast_grep_search`, `ast_grep_replace` from `./ast-grep`
+- `createWebfetchTool`, `WEBFETCH_DESCRIPTION`, and related types from `./smartfetch`
+- `createCouncilTool`
+- `createPresetManager` and `PresetManager` type
+
+## Design patterns
+
+- **Factory-based registration:** each feature exposes a factory that returns an
+  executable/tool or handler object bound to plugin context.
+- **Clear boundaries:** all plugin lifecycle hooks are emitted from factory methods
+  (`handleCommandExecuteBefore`, `handleEvent`, `registerCommand`) rather than in tool
+  modules.
+- **Metadata-first output:** tool calls return text plus internal metadata writes when
+  possible (for richer UI surfaces).
+
+## Subsystems and data flow
+
+### Council tool path
+
+- `createCouncilTool` defines `council_session`.
+- `execute` performs guarded invocation:
+  - validates `toolContext` and `sessionID`,
+  - only allows direct use by `agent: 'council'` (or missing agent for backward compatibility),
+  - calls `CouncilManager.runCouncil(prompt, preset, parentSessionId)`.
+- On success, appends a councillor response summary and normalized model list to output.
+- On failure, returns a concise error string.
+- Shows config deprecation warnings when `CouncilManager` exposes deprecated field metadata.
+
+### Preset-manager command path
+
+- `createPresetManager(ctx, config)` returns:
+  - `registerCommand(opencodeConfig)`: injects `/preset` command definition if absent,
+  - `handleCommandExecuteBefore(input, output)`: intercepts `/preset` command handling.
+- Command behavior:
+  - no args → clear output and list available presets (`active` marker supported),
+  - single token arg → switch preset through `client.config.update(...)` with mapped agent overrides,
+  - multi-word arg → suggestion + no update.
+- Mapping logic converts plugin preset override format (`AgentOverrideConfig`) into runtime
+  SDK `agent` config (`model`, `temperature`, `variant`, `options`) and skips fields not
+  supported in runtime updates (`prompt`, `orchestratorPrompt`, `skills`, `mcps`,
+  `displayName`).
+- In-memory `activePreset` supports immediate status display and updates after successful switches.
+
+### Smartfetch path
+
+- `createWebfetchTool` owns fetch orchestration, permission prompts, cache checks,
+  llms.txt probing, binary/text branching, and optional secondary-model post-processing.
+- `smartfetch` modules split work into:
+  - transport/policy (`network.ts`),
+  - cache + TTL semantics (`cache.ts`),
+  - output shaping (`utils.ts`),
+  - file-backed binaries (`binary.ts`),
+  - secondary-model summarization (`secondary-model.ts`),
+  - constants and types.
+- `webfetch` is always registered from `src/index.ts` as a public tool.
+
+### AST-grep path
+
+- `ast-grep` is split into CLI/CLI-discovery and tool-definition concerns.
+- `ast_grep_search`/`ast_grep_replace` execution calls into `runSg`, which handles
+  argument normalization, binary availability, timeout/error handling, and output truncation.
+- `src/tools/ast-grep/index.ts` re-exports tool definitions and utility helpers for
+  discoverability (`ensureCliAvailable`, `getAstGrepPath`, downloader/runtime checks).
+
+## Integration points in `src/index.ts`
+
+- Tool registration:
+  - `council` tools (only when `config.council` exists),
+  - `webfetch`,
+  - AST tools.
+- `presetManager` is initialized in plugin init and:
+  - calls `registerCommand` during config hook,
+  - handles command interception in `command.execute.before`.
+- `/preset` handling is explicitly user-facing (command hook), while webfetch and
+  council are tool-facing.

+ 25 - 0
src/utils/codemap.md

@@ -8,9 +8,12 @@ Cross-cutting runtime utilities used by orchestration, hooks, and plugin I/O.
 - **subagent-depth.ts**: Tracks delegated session depth and enforces max nested delegation depth.
 - **agent-variant.ts**: Normalizes agent names and applies optional variant labels without overriding existing body configuration.
 - **env.ts**: Unified environment lookup across Bun/Node with empty-string filtering.
+- **session-manager.ts**: Tracks resumable `task` tool sessions by parent session + agent type, normalizes user labels, assigns stable short aliases, and exposes prompt rendering/eviction behavior.
 - **session.ts**: Session extraction helpers for multi-turn synthesis and prompt/result post-processing.
 - **polling.ts**: Shared polling with stability thresholds and abort-signal support.
 - **zip-extractor.ts**: Cross-platform zip/tar extraction with Windows fallback tooling.
+- **task.ts**: Parses `task` tool CLI output to recover `task_id` for resumption.
+- **system-collapse.ts**: Collapses multiple system prompt fragments into one array element while mutating the original array reference.
 - **logger.ts**: Structured JSON logging to temporary files.
 - **internal-initiator.ts**: Marker utilities for internal orchestrator text-part tagging.
 - **compat.ts**: Backward compatibility helpers.
@@ -19,9 +22,11 @@ Cross-cutting runtime utilities used by orchestration, hooks, and plugin I/O.
 ## Design
 
 - **Deterministic lifecycle tracking**: `SubagentDepthTracker` maps session IDs → depth and is cleaned on session deletion.
+- **Parent-scoped resumable session store**: `SessionManager` groups tasks by `{parentSessionId, agentType}` and maintains LRU-ish ordering by last-used counter so active resumable sessions stay in memory.
 - **Provider-safe env access**: `getEnv` falls back from `Bun.env` to `process.env` and normalizes blank values.
 - **Graceful shutdown protocol**: Multiplexer pane close path sends Ctrl+C before kill, then rebalances layout state.
 - **Session extraction model**: `extractSessionResult`/`parseModelReference` style helpers are centralized under `session.ts`.
+- **In-place system normalization**: `collapseSystemInPlace` purposely mutates `system` array to preserve references held by OpenCode internals.
 - **Resilient polling**: `pollUntilStable` requires consecutive confirmations before success.
 
 ## Flow
@@ -32,6 +37,17 @@ Cross-cutting runtime utilities used by orchestration, hooks, and plugin I/O.
 - Blocks registration when depth exceeds `DEFAULT_MAX_SUBAGENT_DEPTH`.
 - `cleanup(sessionId)` and `cleanupAll()` remove depth state for terminated sessions.
 
+### `session-manager.ts`
+
+- `deriveTaskSessionLabel` computes a deterministic prompt hint:
+  - uses `description` if provided,
+  - falls back to first non-empty normalized line of `prompt`,
+  - else returns `recent {agentType} task`.
+- `remember` creates/reuses entries keyed by `{parentSessionId, agentType}` and enforces a per-agent max via `trimGroup`.
+- Alias generation is monotonic within each parent+agent (`exp-1`, `lib-2`, etc.).
+- `markUsed`, `resolve`, `drop`, `dropTask`, `clearParent` keep the store consistent on reuse and teardown.
+- `formatForPrompt` returns grouped and ranked prompt text (`### Resumable Sessions ...`) for use in system transforms.
+
 ### `tmux.ts`
 
 - `spawnPane` flow: validate enabled state → check multiplexer availability → resolve binary → execute attach command with layout handling.
@@ -48,12 +64,21 @@ Cross-cutting runtime utilities used by orchestration, hooks, and plugin I/O.
 - Composes prompt parts and extracts normalized session output for text/call/result flows.
 - Hosts shared parsing/formatting utilities used by council and tool execution layers.
 
+### `task.ts`
+
+- Scans task output line-by-line and extracts `task_id` from `task_id: <id>` format.
+
+### `system-collapse.ts`
+
+- `collapseSystemInPlace(system: string[])` joins all system entries using `\n\n`, clears and repopulates the same array reference, and preserves empty-array behavior.
+
 ## Integration
 
 - **Consumers**
   - `src/multiplexer/*`: `SubagentDepthTracker` and `tmux.ts` integration.
   - `src/council/council-manager.ts`: depth control and session extraction helpers.
   - `src/hooks/*`: marker detection, polling, and session-aware state helpers.
+  - `src/hooks/task-session-manager`: `SessionManager`, `parseTaskIdFromTaskOutput`, and `deriveTaskSessionLabel` provide resumable-session workflow; the plugin’s system-transform passes the hook output through `collapseSystemInPlace` after this manager injects prompts.
 
 - **Dependencies**
   - Pulls constants from `../config` (`DEFAULT_MAX_SUBAGENT_DEPTH`, polling intervals/timeouts).