@rse/ase 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/dst/ase-agent-definition-api.d.ts +184 -0
  2. package/dst/ase-agent-definition-api.js +6 -0
  3. package/dst/ase-agent-definition-builtin/condenser.js +42 -0
  4. package/dst/ase-agent-definition-builtin/editor.js +45 -0
  5. package/dst/ase-agent-definition-builtin/estimator.js +98 -0
  6. package/dst/ase-agent-definition-builtin/implementer.js +121 -0
  7. package/dst/ase-agent-definition-builtin/integrator.js +56 -0
  8. package/dst/ase-agent-definition-builtin/qualifier.js +61 -0
  9. package/dst/ase-agent-definition-builtin/rebooter.js +41 -0
  10. package/dst/ase-agent-definition-builtin/researcher.js +77 -0
  11. package/dst/ase-agent-definition-core.js +827 -0
  12. package/dst/ase-agent-fleet.js +772 -0
  13. package/dst/ase-agent-process.js +232 -0
  14. package/dst/ase-agent-relay-client.js +509 -0
  15. package/dst/ase-agent-relay-core.js +213 -0
  16. package/dst/ase-agent-relay-server-bind.js +242 -0
  17. package/dst/ase-agent-relay-server-cli.js +50 -0
  18. package/dst/ase-agent-runtime-claim.js +189 -0
  19. package/dst/ase-agent-runtime-engine.js +1100 -0
  20. package/dst/ase-agent-runtime-exec.js +275 -0
  21. package/dst/ase-agent-runtime-phase.js +581 -0
  22. package/dst/ase-agent-runtime-request.js +272 -0
  23. package/dst/ase-agent-runtime-tool.js +207 -0
  24. package/dst/ase-agent-runtime.js +1316 -0
  25. package/dst/ase-agent.js +65 -0
  26. package/dst/ase-artifact.js +6 -5
  27. package/dst/ase-config-core.js +465 -0
  28. package/dst/ase-config-schema.js +351 -0
  29. package/dst/ase-config-scope.js +172 -0
  30. package/dst/ase-config.js +25 -585
  31. package/dst/ase-hook.js +230 -116
  32. package/dst/ase-lib-daemon-cli.js +130 -0
  33. package/dst/ase-lib-hash.js +20 -0
  34. package/dst/{ase-log.js → ase-lib-log.js} +40 -7
  35. package/dst/ase-lib-server-bind.js +115 -0
  36. package/dst/ase-lib-server-cli.js +474 -0
  37. package/dst/{ase-table.js → ase-lib-table.js} +1 -1
  38. package/dst/{ase-version.js → ase-lib-version.js} +3 -0
  39. package/dst/ase-man.js +96 -0
  40. package/dst/ase-mcp.js +166 -13
  41. package/dst/{ase-getopt.js → ase-service-getopt.js} +82 -80
  42. package/dst/{ase-markdown.js → ase-service-markdown.js} +18 -11
  43. package/dst/ase-service-otel.js +1246 -0
  44. package/dst/{ase-skills.js → ase-service-skills.js} +29 -64
  45. package/dst/ase-service-state.js +101 -0
  46. package/dst/ase-service.js +251 -76
  47. package/dst/ase-setup-common.js +141 -0
  48. package/dst/ase-setup-mcp.js +359 -0
  49. package/dst/ase-setup-settings.js +837 -0
  50. package/dst/ase-setup.js +113 -869
  51. package/dst/ase-spec.js +31 -19
  52. package/dst/ase-statusline.js +108 -43
  53. package/dst/ase-task-board-core.js +739 -0
  54. package/dst/ase-task-board-filter.js +127 -0
  55. package/dst/ase-task-board-flow.js +237 -0
  56. package/dst/ase-task-board-graph.js +497 -0
  57. package/dst/ase-task-board-stats.js +263 -0
  58. package/dst/ase-task-board-tui-control.js +775 -0
  59. package/dst/ase-task-board-tui-model.js +1008 -0
  60. package/dst/ase-task-board-tui-popup.js +626 -0
  61. package/dst/ase-task-board-tui-style.js +106 -0
  62. package/dst/ase-task-board-tui-view.js +847 -0
  63. package/dst/ase-task-board-tui.js +189 -0
  64. package/dst/ase-task-board-web-client.css +1 -0
  65. package/dst/ase-task-board-web-client.html +20 -0
  66. package/dst/ase-task-board-web-client.js +81 -0
  67. package/dst/ase-task-board-web-server.js +823 -0
  68. package/dst/ase-task-board.js +134 -0
  69. package/dst/ase-task-format.js +757 -0
  70. package/dst/ase-task-request.js +208 -0
  71. package/dst/ase-task-store-client.js +495 -0
  72. package/dst/ase-task-store-core.js +804 -0
  73. package/dst/ase-task-store-issues.js +237 -0
  74. package/dst/ase-task-store-plugin-api.js +6 -0
  75. package/dst/ase-task-store-plugin-ase.js +484 -0
  76. package/dst/ase-task-store-plugin-delegate.js +137 -0
  77. package/dst/ase-task-store-plugin-gitea.js +666 -0
  78. package/dst/ase-task-store-plugin-github.js +696 -0
  79. package/dst/ase-task-store-plugin-gitlab.js +668 -0
  80. package/dst/ase-task-store-server-bind.js +538 -0
  81. package/dst/ase-task-store-server-cli.js +154 -0
  82. package/dst/ase-task.js +1335 -357
  83. package/dst/{ase-compat.js → ase-util-compat.js} +2 -2
  84. package/dst/{ase-diagram.js → ase-util-diagram.js} +107 -32
  85. package/dst/{ase-meta.js → ase-util-meta.js} +2 -2
  86. package/dst/{ase-metric.js → ase-util-metric.js} +2 -2
  87. package/dst/{ase-mint.js → ase-util-mint.js} +19 -12
  88. package/dst/{ase-worktree.js → ase-util-worktree.js} +30 -19
  89. package/dst/ase-util.js +20 -0
  90. package/dst/ase.js +108 -32
  91. package/dst/man/ase-agent-adhoc.1 +515 -0
  92. package/dst/man/ase-agent-condenser.1 +193 -0
  93. package/dst/man/ase-agent-editor.1 +212 -0
  94. package/dst/man/ase-agent-estimator.1 +214 -0
  95. package/dst/man/ase-agent-fleet.1 +185 -0
  96. package/dst/man/ase-agent-implementer.1 +233 -0
  97. package/dst/man/ase-agent-integrator.1 +213 -0
  98. package/dst/man/ase-agent-qualifier.1 +214 -0
  99. package/dst/man/ase-agent-rebooter.1 +193 -0
  100. package/dst/man/ase-agent-relay.1 +128 -0
  101. package/dst/man/ase-agent-researcher.1 +217 -0
  102. package/dst/man/ase-agent.1 +264 -0
  103. package/dst/man/ase-artifact-list.1 +38 -0
  104. package/dst/man/ase-artifact-name.1 +39 -0
  105. package/dst/man/ase-artifact.1 +56 -0
  106. package/dst/man/ase-config-delete.1 +45 -0
  107. package/dst/man/ase-config-edit.1 +48 -0
  108. package/dst/man/ase-config-get.1 +46 -0
  109. package/dst/man/ase-config-init.1 +60 -0
  110. package/dst/man/ase-config-list.1 +42 -0
  111. package/dst/man/ase-config-set.1 +52 -0
  112. package/dst/man/ase-config.1 +225 -0
  113. package/dst/man/ase-hook-permission-request.1 +36 -0
  114. package/dst/man/ase-hook-pre-tool-use.1 +59 -0
  115. package/dst/man/ase-hook-session-end.1 +47 -0
  116. package/dst/man/ase-hook-session-persona.1 +37 -0
  117. package/dst/man/ase-hook-session-start.1 +81 -0
  118. package/dst/man/ase-hook-stop.1 +34 -0
  119. package/dst/man/ase-hook-user-prompt-submit.1 +34 -0
  120. package/dst/man/ase-hook.1 +51 -0
  121. package/dst/man/ase-man.1 +67 -0
  122. package/dst/man/ase-mcp.1 +61 -0
  123. package/dst/man/ase-service-log.1 +43 -0
  124. package/dst/man/ase-service-send.1 +47 -0
  125. package/dst/man/ase-service-start.1 +54 -0
  126. package/dst/man/ase-service-status.1 +46 -0
  127. package/dst/man/ase-service-stop.1 +37 -0
  128. package/dst/man/ase-service.1 +85 -0
  129. package/dst/man/ase-setup-disable.1 +44 -0
  130. package/dst/man/ase-setup-enable.1 +45 -0
  131. package/dst/man/ase-setup-install.1 +73 -0
  132. package/dst/man/ase-setup-mcp.1 +124 -0
  133. package/dst/man/ase-setup-status.1 +60 -0
  134. package/dst/man/ase-setup-statusline.1 +92 -0
  135. package/dst/man/ase-setup-telemetry.1 +92 -0
  136. package/dst/man/ase-setup-uninstall.1 +59 -0
  137. package/dst/man/ase-setup-update.1 +64 -0
  138. package/dst/man/ase-setup.1 +93 -0
  139. package/dst/man/ase-spec-export.1 +62 -0
  140. package/dst/man/ase-spec-lint.1 +40 -0
  141. package/dst/man/ase-spec-preview.1 +40 -0
  142. package/dst/man/ase-spec.1 +46 -0
  143. package/dst/man/ase-statusline.1 +189 -0
  144. package/dst/man/ase-task-assign.1 +71 -0
  145. package/dst/man/ase-task-board.1 +384 -0
  146. package/dst/man/ase-task-delete.1 +35 -0
  147. package/dst/man/ase-task-edit.1 +46 -0
  148. package/dst/man/ase-task-idscheme.1 +65 -0
  149. package/dst/man/ase-task-lifecycle.1 +57 -0
  150. package/dst/man/ase-task-list.1 +47 -0
  151. package/dst/man/ase-task-load.1 +36 -0
  152. package/dst/man/ase-task-newid.1 +61 -0
  153. package/dst/man/ase-task-purge.1 +37 -0
  154. package/dst/man/ase-task-rename.1 +44 -0
  155. package/dst/man/ase-task-request.1 +61 -0
  156. package/dst/man/ase-task-save.1 +48 -0
  157. package/dst/man/ase-task-status.1 +55 -0
  158. package/dst/man/ase-task-store.1 +194 -0
  159. package/dst/man/ase-task-view.1 +40 -0
  160. package/dst/man/ase-task.1 +160 -0
  161. package/dst/man/ase-util-compat.1 +25 -0
  162. package/dst/man/ase-util-diagram.1 +76 -0
  163. package/dst/man/ase-util-meta.1 +45 -0
  164. package/dst/man/ase-util-metric.1 +54 -0
  165. package/dst/man/ase-util-mint.1 +59 -0
  166. package/dst/man/ase-util-worktree.1 +72 -0
  167. package/dst/man/ase-util.1 +50 -0
  168. package/dst/man/ase.1 +124 -0
  169. package/package.json +79 -21
  170. package/plugin/.claude-plugin/plugin.json +1 -1
  171. package/plugin/.codex-plugin/plugin.json +1 -1
  172. package/plugin/.github/plugin/plugin.json +1 -1
  173. package/plugin/agents/ase-meta-diagram.md +12 -8
  174. package/plugin/agents/ase-repo-review.md +322 -0
  175. package/plugin/hooks/hooks-codex.json +5 -0
  176. package/plugin/hooks/hooks-copilot.json +5 -0
  177. package/plugin/hooks/hooks.json +8 -0
  178. package/plugin/meta/ase-common-approach.md +117 -0
  179. package/plugin/meta/ase-common-changeset.md +256 -0
  180. package/plugin/meta/ase-common-code.md +10 -173
  181. package/plugin/meta/ase-common-grill.md +317 -0
  182. package/plugin/meta/ase-common-resolve.md +305 -0
  183. package/plugin/meta/ase-common-task.md +83 -4
  184. package/plugin/meta/ase-constitution.md +0 -2
  185. package/plugin/meta/ase-format-specbook.md +208 -25
  186. package/plugin/meta/ase-format-specbook.yaml +242 -851
  187. package/plugin/meta/ase-format-task.md +669 -125
  188. package/plugin/meta/ase-persona.md +3 -4
  189. package/plugin/meta/ase-skill.md +9 -0
  190. package/plugin/mods/ase-mods.ts +409 -0
  191. package/plugin/mods/claude-code.d.ts +13417 -0
  192. package/plugin/skills/ase-arch-analyze/SKILL.md +1 -1
  193. package/plugin/skills/ase-arch-analyze/help.md +2 -2
  194. package/plugin/skills/ase-code-analyze/SKILL.md +59 -8
  195. package/plugin/skills/ase-code-analyze/help.md +29 -4
  196. package/plugin/skills/ase-code-edit/SKILL.md +107 -181
  197. package/plugin/skills/ase-code-edit/help.md +118 -31
  198. package/plugin/skills/ase-code-lint/SKILL.md +64 -13
  199. package/plugin/skills/ase-code-lint/help.md +32 -2
  200. package/plugin/skills/ase-docs-proofread/SKILL.md +4 -4
  201. package/plugin/skills/ase-docs-proofread/help.md +1 -1
  202. package/plugin/skills/ase-docs-refine/SKILL.md +4 -4
  203. package/plugin/skills/ase-docs-shorten/SKILL.md +4 -4
  204. package/plugin/skills/ase-help-intent/data.md +2164 -1087
  205. package/plugin/skills/ase-help-intent/help.md +1 -1
  206. package/plugin/skills/ase-help-skill/catalog.md +12 -9
  207. package/plugin/skills/ase-meta-brainstorm/SKILL.md +1 -1
  208. package/plugin/skills/ase-meta-config/SKILL.md +3 -4
  209. package/plugin/skills/ase-meta-config/help.md +31 -10
  210. package/plugin/skills/ase-meta-mint/SKILL.md +5 -5
  211. package/plugin/skills/ase-meta-mint/help.md +10 -5
  212. package/plugin/skills/ase-meta-why/help.md +1 -1
  213. package/plugin/skills/ase-meta-workflow/SKILL.md +7 -7
  214. package/plugin/skills/ase-meta-workflow/help.md +4 -4
  215. package/plugin/skills/ase-meta-workflow/sample.md +3 -3
  216. package/plugin/skills/ase-meta-workflow/workflow.txt +22 -18
  217. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/SKILL.md +4 -3
  218. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/help.md +5 -5
  219. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/SKILL.md +6 -6
  220. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/help.md +5 -5
  221. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/SKILL.md +6 -6
  222. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/help.md +8 -8
  223. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/SKILL.md +19 -19
  224. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/help.md +10 -12
  225. package/plugin/skills/ase-repo-merge/SKILL.md +346 -0
  226. package/plugin/skills/ase-repo-merge/help.md +107 -0
  227. package/plugin/skills/ase-repo-resolve/SKILL.md +158 -0
  228. package/plugin/skills/ase-repo-resolve/help.md +102 -0
  229. package/plugin/skills/ase-repo-review/SKILL.md +406 -0
  230. package/plugin/skills/ase-repo-review/help.md +181 -0
  231. package/plugin/skills/ase-spec-edit/SKILL.md +117 -183
  232. package/plugin/skills/ase-spec-edit/help.md +107 -26
  233. package/plugin/skills/ase-sync-reconcile/help.md +1 -1
  234. package/plugin/skills/ase-task-assign/SKILL.md +111 -0
  235. package/plugin/skills/ase-task-assign/help.md +119 -0
  236. package/plugin/skills/ase-task-condense/SKILL.md +21 -21
  237. package/plugin/skills/ase-task-condense/help.md +12 -10
  238. package/plugin/skills/ase-task-delete/SKILL.md +1 -1
  239. package/plugin/skills/ase-task-dissect/SKILL.md +71 -48
  240. package/plugin/skills/ase-task-dissect/help.md +10 -9
  241. package/plugin/skills/ase-task-edit/SKILL.md +379 -94
  242. package/plugin/skills/ase-task-edit/help.md +95 -22
  243. package/plugin/skills/ase-task-estimate/SKILL.md +492 -0
  244. package/plugin/skills/ase-task-estimate/help.md +158 -0
  245. package/plugin/skills/ase-task-grill/SKILL.md +246 -138
  246. package/plugin/skills/ase-task-grill/help.md +129 -26
  247. package/plugin/skills/ase-task-id/SKILL.md +8 -1
  248. package/plugin/skills/ase-task-id/help.md +6 -3
  249. package/plugin/skills/ase-task-implement/SKILL.md +535 -145
  250. package/plugin/skills/ase-task-implement/help.md +138 -47
  251. package/plugin/skills/ase-task-integrate/SKILL.md +549 -0
  252. package/plugin/skills/ase-task-integrate/help.md +187 -0
  253. package/plugin/skills/ase-task-list/SKILL.md +55 -23
  254. package/plugin/skills/ase-task-list/help.md +45 -21
  255. package/plugin/skills/ase-task-reboot/SKILL.md +84 -43
  256. package/plugin/skills/ase-task-reboot/help.md +28 -8
  257. package/plugin/skills/ase-task-rename/SKILL.md +10 -2
  258. package/plugin/skills/ase-task-research/SKILL.md +386 -0
  259. package/plugin/skills/ase-task-research/help.md +102 -0
  260. package/plugin/skills/ase-task-status/SKILL.md +137 -0
  261. package/plugin/skills/ase-task-status/help.md +80 -0
  262. package/plugin/skills/ase-task-view/SKILL.md +49 -24
  263. package/plugin/skills/ase-task-view/help.md +19 -9
  264. package/plugin/agents/ase-meta-review.md +0 -187
  265. package/plugin/skills/ase-code-craft/SKILL.md +0 -264
  266. package/plugin/skills/ase-code-craft/help.md +0 -122
  267. package/plugin/skills/ase-code-refactor/SKILL.md +0 -232
  268. package/plugin/skills/ase-code-refactor/help.md +0 -109
  269. package/plugin/skills/ase-code-resolve/SKILL.md +0 -289
  270. package/plugin/skills/ase-code-resolve/help.md +0 -116
  271. package/plugin/skills/ase-meta-review/SKILL.md +0 -210
  272. package/plugin/skills/ase-meta-review/help.md +0 -96
  273. package/plugin/skills/ase-task-preflight/SKILL.md +0 -166
  274. package/plugin/skills/ase-task-preflight/help.md +0 -82
  275. /package/dst/{ase-ignore.js → ase-lib-ignore.js} +0 -0
  276. /package/dst/{ase-stdio.js → ase-lib-stdio.js} +0 -0
  277. /package/dst/{ase-kv.js → ase-service-kv.js} +0 -0
  278. /package/dst/{ase-sleep.js → ase-service-sleep.js} +0 -0
  279. /package/dst/{ase-timestamp.js → ase-service-timestamp.js} +0 -0
@@ -46,10 +46,12 @@ export class Skills {
46
46
  repository = r.url;
47
47
  deps = Object.keys(verEntry.dependencies ?? {}).length;
48
48
  }
49
- return { version, time, repository, deps };
49
+ const created = time.created ?? "";
50
+ const updated = version !== "" ? (time[version] ?? "") : "";
51
+ return { version, created, updated, repository, deps };
50
52
  }
51
53
  catch {
52
- return { version: "", time: {}, repository: "", deps: "N.A." };
54
+ return { version: "", created: "", updated: "", repository: "", deps: "N.A." };
53
55
  }
54
56
  }
55
57
  /* fetch GitHub stars given a repository URL (or empty string) */
@@ -199,73 +201,36 @@ export class Skills {
199
201
  - "Java"/"Kotlin": Maven Central + GitHub stars + mvnrepository.com "Used By"
200
202
  - "Unknown": not supported -- return empty result */
201
203
  static async info(stack, components, staleMonths = 18, smallScope = false) {
202
- if (stack === "JavaScript" || stack === "TypeScript") {
203
- /* per package: kick off packument and downloads in parallel,
204
- then stars as soon as the packument resolves; across packages
205
- everything runs concurrently via Promise.all */
206
- const results = await Promise.all(components.map(async (name) => {
207
- const packumentPromise = Skills.fetchPackument(name);
208
- const downloadsPromise = Skills.fetchDownloads(name);
209
- const starsPromise = packumentPromise.then((p) => Skills.fetchStars(p.repository));
210
- const [p, downloads, stars] = await Promise.all([
211
- packumentPromise, downloadsPromise, starsPromise
212
- ]);
213
- const created = p.time.created ?? "";
214
- const updated = p.version !== "" ? (p.time[p.version] ?? "") : "";
215
- const rank = Skills.computeRank(downloads, stars, created, updated, p.deps, staleMonths, smallScope);
216
- return {
217
- name,
218
- version: p.version,
219
- created,
220
- updated,
221
- repository: p.repository,
222
- stars,
223
- downloads,
224
- deps: p.deps,
225
- rank
226
- };
227
- }));
228
- /* sort by rank in descending order (best first) */
229
- results.sort((a, b) => b.rank - a.rank);
230
- return results;
231
- }
232
- else if (stack === "Java" || stack === "Kotlin") {
233
- /* per coordinate: kick off Maven Central info and mvnrepository
234
- downloads in parallel, then stars as soon as the POM-derived
235
- repository is known; across coordinates everything runs
236
- concurrently via Promise.all */
237
- const results = await Promise.all(components.map(async (name) => {
238
- const infoPromise = Skills.fetchMavenInfo(name);
239
- const downloadsPromise = Skills.fetchMavenDownloads(name);
240
- const starsPromise = infoPromise.then((i) => Skills.fetchStars(i.repository));
241
- const [i, downloads, stars] = await Promise.all([
242
- infoPromise, downloadsPromise, starsPromise
243
- ]);
244
- const rank = Skills.computeRank(downloads, stars, i.created, i.updated, i.deps, staleMonths, smallScope);
245
- return {
246
- name,
247
- version: i.version,
248
- created: i.created,
249
- updated: i.updated,
250
- repository: i.repository,
251
- stars,
252
- downloads,
253
- deps: i.deps,
254
- rank
255
- };
256
- }));
257
- /* sort by rank in descending order (best first) */
258
- results.sort((a, b) => b.rank - a.rank);
259
- return results;
260
- }
261
- else
204
+ /* select the per-stack metadata and downloads fetchers */
205
+ const fetchers = stack === "JavaScript" || stack === "TypeScript" ?
206
+ { meta: Skills.fetchPackument, downloads: Skills.fetchDownloads } :
207
+ stack === "Java" || stack === "Kotlin" ?
208
+ { meta: Skills.fetchMavenInfo, downloads: Skills.fetchMavenDownloads } :
209
+ null;
210
+ if (fetchers === null)
262
211
  return [];
212
+ /* per component: kick off metadata and downloads in parallel,
213
+ then stars as soon as the repository is known; across components
214
+ everything runs concurrently via Promise.all */
215
+ const results = await Promise.all(components.map(async (name) => {
216
+ const metaPromise = fetchers.meta(name);
217
+ const downloadsPromise = fetchers.downloads(name);
218
+ const starsPromise = metaPromise.then((m) => Skills.fetchStars(m.repository));
219
+ const [m, downloads, stars] = await Promise.all([
220
+ metaPromise, downloadsPromise, starsPromise
221
+ ]);
222
+ const rank = Skills.computeRank(downloads, stars, m.created, m.updated, m.deps, staleMonths, smallScope);
223
+ return { name, ...m, stars, downloads, rank };
224
+ }));
225
+ /* sort by rank in descending order (best first) */
226
+ results.sort((a, b) => b.rank - a.rank);
227
+ return results;
263
228
  }
264
229
  /* compute composite rank score from weighted metrics:
265
230
  (downloads + 1) x
266
231
  (stars + 1) x
267
232
  ([lifespan =] (updated - created)) x
268
- ([recentness =] exp(-(now - updated) / halfLife))
233
+ ([recentness =] 0.5 ^ ((now - updated) / halfLife))
269
234
  Numeric count metrics are shifted by `+1` so that a genuine `0`
270
235
  (e.g. a real package with zero downloads or stars) contributes a
271
236
  neutral `1` instead of collapsing the entire product to zero, while
@@ -296,7 +261,7 @@ export class Skills {
296
261
  one half-life (`0.5`), a conservative midpoint that keeps the
297
262
  entry rankable without rewarding the missing date. */
298
263
  const lifespan = (!Number.isNaN(cMs) && !Number.isNaN(uMs)) ? Math.max(1, uMs - cMs) : 1;
299
- const recentness = !Number.isNaN(uMs) ? Math.exp(-Math.max(0, (now - uMs) / msPerDay) / halfLife) : 0.5;
264
+ const recentness = !Number.isNaN(uMs) ? 0.5 ** (Math.max(0, (now - uMs) / msPerDay) / halfLife) : 0.5;
300
265
  let rank = d * s * lifespan * recentness;
301
266
  /* hard, caller-tunable staleness penalty on top of the soft
302
267
  `recentness` decay: unlike the smooth exp-decay above, this is a
@@ -0,0 +1,101 @@
1
+ /*
2
+ ** Agentic Software Engineering (ASE)
3
+ ** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
5
+ */
6
+ import { z } from "zod";
7
+ import { sessionState } from "./ase-config-core.js";
8
+ /* the keys of the internal session state */
9
+ const stateKeys = ["basedir", "task", "skill"];
10
+ /* render a caught error as an MCP tool error result */
11
+ const mcpToolError = (err) => ({
12
+ isError: true,
13
+ content: [{ type: "text", text: `ERROR: ${err instanceof Error ? err.message : String(err)}` }]
14
+ });
15
+ /* MCP registration entry point for the internal session state access */
16
+ export class StateMCP {
17
+ log;
18
+ constructor(log) {
19
+ this.log = log;
20
+ }
21
+ /* register the MCP tools */
22
+ register(mcp) {
23
+ /* state get */
24
+ mcp.registerTool("ase_state_get", {
25
+ title: "ASE state get",
26
+ description: "Read the value of a `key` from the internal state of a `session`: " +
27
+ "`basedir` (the project directory, recorded for GitHub Copilot CLI only), " +
28
+ "`task` (the id of the active task), or `skill` (the id of the active " +
29
+ "edit-capable skill). Returns the value as `text`; returns an empty string " +
30
+ "if no value is set.",
31
+ inputSchema: {
32
+ key: z.enum(stateKeys)
33
+ .describe("state key (\"basedir\", \"task\", or \"skill\")"),
34
+ session: z.string()
35
+ .describe("session identifier (allowed characters: A-Z, a-z, 0-9, '.', '_', '-')")
36
+ }
37
+ }, async (args) => {
38
+ try {
39
+ const state = sessionState(this.log, args.session);
40
+ state.read();
41
+ const val = state.get(args.key);
42
+ return { content: [{ type: "text", text: typeof val === "string" ? val : "" }] };
43
+ }
44
+ catch (err) {
45
+ return mcpToolError(err);
46
+ }
47
+ });
48
+ /* state set */
49
+ mcp.registerTool("ase_state_set", {
50
+ title: "ASE state set",
51
+ description: "Write the non-empty `val` to a `key` of the internal state of a `session`. " +
52
+ "The value is validated against the state schema before being persisted.",
53
+ inputSchema: {
54
+ key: z.enum(stateKeys)
55
+ .describe("state key (\"basedir\", \"task\", or \"skill\")"),
56
+ val: z.string().min(1)
57
+ .describe("value to store under `key`"),
58
+ session: z.string()
59
+ .describe("session identifier (allowed characters: A-Z, a-z, 0-9, '.', '_', '-')")
60
+ }
61
+ }, async (args) => {
62
+ try {
63
+ const state = sessionState(this.log, args.session);
64
+ state.lock(() => {
65
+ state.read();
66
+ state.set(args.key, args.val);
67
+ state.write();
68
+ });
69
+ return { content: [{ type: "text", text: `OK: stored "${args.key}" for session "${args.session}"` }] };
70
+ }
71
+ catch (err) {
72
+ return mcpToolError(err);
73
+ }
74
+ });
75
+ /* state delete */
76
+ mcp.registerTool("ase_state_delete", {
77
+ title: "ASE state delete",
78
+ description: "Delete the value of a `key` from the internal state of a `session`. " +
79
+ "No-op if the key is not present.",
80
+ inputSchema: {
81
+ key: z.enum(stateKeys)
82
+ .describe("state key (\"basedir\", \"task\", or \"skill\")"),
83
+ session: z.string()
84
+ .describe("session identifier (allowed characters: A-Z, a-z, 0-9, '.', '_', '-')")
85
+ }
86
+ }, async (args) => {
87
+ try {
88
+ const state = sessionState(this.log, args.session);
89
+ state.lock(() => {
90
+ state.read();
91
+ state.delete(args.key);
92
+ state.write();
93
+ });
94
+ return { content: [{ type: "text", text: `OK: removed "${args.key}" for session "${args.session}"` }] };
95
+ }
96
+ catch (err) {
97
+ return mcpToolError(err);
98
+ }
99
+ });
100
+ }
101
+ }