@mulmoclaude/accounting-plugin 1.0.2 → 1.1.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.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @mulmoclaude/accounting-plugin
2
+
3
+ Double-entry accounting plugin for MulmoClaude and MulmoTerminal. Three surfaces: ./shared (isomorphic enums/meta, browser-safe), ./vue (chat View/Preview + canvas app), ./server (createAccountingRouter — the workspace-file-backed backend, wired via dependency injection so it pulls zero host-only infra).
4
+
5
+ A plugin for [MulmoClaude](https://github.com/receptron/mulmoclaude) and [MulmoTerminal](https://github.com/receptron/mulmoterminal) — loaded by the host, not run standalone.
6
+
7
+ ## Dev loop
8
+
9
+ ```bash
10
+ yarn workspace @mulmoclaude/accounting-plugin run build
11
+ yarn workspace @mulmoclaude/accounting-plugin run test
12
+ ```
13
+
14
+ ## Related projects
15
+
16
+ Used by both MulmoClaude and MulmoTerminal, and published from the MulmoClaude monorepo by [Receptron](https://github.com/receptron).
17
+
18
+ - **[MulmoClaude](https://github.com/receptron/mulmoclaude)** — an open-source AI assistant platform that runs on your own computer. Claude Code as the engine, a personal wiki for long-term memory, schema-driven collections for your data, and chat that summons the right GUI (markdown, charts, forms, spreadsheets, wikis) for each task.
19
+ - **[MulmoTerminal](https://github.com/receptron/mulmoterminal)** — a terminal-first cockpit for running many AI coding agents in parallel. One roster showing every session's summary and PR status, tmux-backed session persistence, git-worktree isolation, one-click PRs, and mobile push with remote reply.
20
+ - **[MulmoTerminal manual](https://receptron.github.io/mulmoterminal/)** — setup, workflows, feature reference, configuration, mobile notifications, and alternative / local model providers. Available in English and Japanese.
@@ -1,3 +1,35 @@
1
1
  import type { Request, Response, NextFunction } from "express";
2
- export declare function asyncHandler<TReq = Request, TRes = Response>(namespace: string, fallbackMessage: string, handler: (req: TReq, res: TRes) => Promise<void>): (req: TReq, res: TRes, next: NextFunction) => Promise<void>;
2
+ /** The body the catch path sends. Declared here rather than imported from the
3
+ * host's `httpError.ts` for the same reason the wrapper is copied: reaching
4
+ * into the host would be an uphill import. */
5
+ export interface ErrorBody {
6
+ error: string;
7
+ }
8
+ /** A route response that can carry either its success body or an error — use
9
+ * this, not a bare `Response<T>`, for any handler wrapped by `asyncHandler`,
10
+ * which can always emit `ErrorBody` on the failure path. */
11
+ export type ApiResponse<T> = Response<T | ErrorBody>;
12
+ /** The bounds below name exactly what the catch path dereferences.
13
+ *
14
+ * They are NOT `extends Request` / `extends Response`: Express uses its type
15
+ * parameters in mixed variance positions, so a nominal bound rejects valid
16
+ * call sites like `Request<object, unknown, MyBody>`. Naming only the members
17
+ * we touch keeps every concrete `Request<…>` / `Response<…>` assignable.
18
+ *
19
+ * Structural bounds rather than unconstrained generics plus `as` casts,
20
+ * because the casts were load-bearing in a way that hid a real contract: this
21
+ * wrapper sends `{ error }` on the failure path, so a route declaring a
22
+ * `ResBody` that cannot carry it was lying. That is now a compile error, and
23
+ * the fix at such a site is `ApiResponse<T>`. */
24
+ interface RoutePathBearing {
25
+ path: string;
26
+ }
27
+ interface ErrorSendableResponse {
28
+ headersSent: boolean;
29
+ status: (code: number) => {
30
+ json: (body: ErrorBody) => unknown;
31
+ };
32
+ }
33
+ export declare function asyncHandler<TReq extends RoutePathBearing = Request, TRes extends ErrorSendableResponse = Response>(namespace: string, fallbackMessage: string, handler: (req: TReq, res: TRes) => Promise<void>): (req: TReq, res: TRes, next: NextFunction) => Promise<void>;
34
+ export {};
3
35
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI/D,wBAAgB,YAAY,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,QAAQ,EAC1D,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAkB7D"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI/D;;+CAE+C;AAC/C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;6DAE6D;AAC7D,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;AAErD;;;;;;;;;;;kDAWkD;AAClD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,qBAAqB;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAA;KAAE,CAAC;CAClE;AAED,wBAAgB,YAAY,CAAC,IAAI,SAAS,gBAAgB,GAAG,OAAO,EAAE,IAAI,SAAS,qBAAqB,GAAG,QAAQ,EACjH,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAgB7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAyUpD;;;2BAG2B;AAC3B,wBAAgB,sBAAsB,IAAI,MAAM,CAsC/C"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AA2UpD;;;2BAG2B;AAC3B,wBAAgB,sBAAsB,IAAI,MAAM,CAsC/C"}
package/dist/server.cjs CHANGED
@@ -1858,17 +1858,15 @@ function asyncHandler(namespace, fallbackMessage, handler) {
1858
1858
  try {
1859
1859
  await handler(req, res);
1860
1860
  } catch (err) {
1861
- const expressReq = req;
1862
- const expressRes = res;
1863
1861
  log.error(namespace, "handler threw", {
1864
- route: expressReq.path,
1862
+ route: req.path,
1865
1863
  error: require_shared.errorMessage(err)
1866
1864
  });
1867
- if (expressRes.headersSent) {
1865
+ if (res.headersSent) {
1868
1866
  next(err);
1869
1867
  return;
1870
1868
  }
1871
- expressRes.status(500).json({ error: fallbackMessage });
1869
+ res.status(500).json({ error: fallbackMessage });
1872
1870
  }
1873
1871
  };
1874
1872
  }