@meetless/mla 0.1.4

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 (202) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +81 -0
  3. package/dist/build-info.json +9 -0
  4. package/dist/bundles/ask-core.js +396 -0
  5. package/dist/bundles/mcp.js +16592 -0
  6. package/dist/bundles/trace-core.js +263 -0
  7. package/dist/cli.js +828 -0
  8. package/dist/commands/activate.js +781 -0
  9. package/dist/commands/adoption.js +130 -0
  10. package/dist/commands/ask.js +290 -0
  11. package/dist/commands/context.js +114 -0
  12. package/dist/commands/debug.js +313 -0
  13. package/dist/commands/doctor.js +1021 -0
  14. package/dist/commands/enrich.js +427 -0
  15. package/dist/commands/evidence.js +229 -0
  16. package/dist/commands/flush.js +184 -0
  17. package/dist/commands/graph.js +104 -0
  18. package/dist/commands/init.js +272 -0
  19. package/dist/commands/internal-active-review.js +322 -0
  20. package/dist/commands/internal-auto-index.js +188 -0
  21. package/dist/commands/internal-capture-decisions.js +320 -0
  22. package/dist/commands/internal-evidence-correlate.js +239 -0
  23. package/dist/commands/internal-evidence-hooks.js +240 -0
  24. package/dist/commands/internal-evidence-inject.js +231 -0
  25. package/dist/commands/internal-finalize.js +221 -0
  26. package/dist/commands/internal-pretool-observe.js +225 -0
  27. package/dist/commands/internal-refresh.js +136 -0
  28. package/dist/commands/internal-session-nudge.js +120 -0
  29. package/dist/commands/internal-steer-sync.js +117 -0
  30. package/dist/commands/internal-turn-recap.js +140 -0
  31. package/dist/commands/kb.js +375 -0
  32. package/dist/commands/kb_add.js +681 -0
  33. package/dist/commands/kb_forget.js +283 -0
  34. package/dist/commands/kb_move.js +45 -0
  35. package/dist/commands/kb_pending.js +410 -0
  36. package/dist/commands/kb_personal.js +149 -0
  37. package/dist/commands/kb_promote.js +188 -0
  38. package/dist/commands/kb_purge.js +168 -0
  39. package/dist/commands/kb_reingest.js +335 -0
  40. package/dist/commands/kb_retime.js +170 -0
  41. package/dist/commands/kb_review.js +391 -0
  42. package/dist/commands/kb_revision.js +179 -0
  43. package/dist/commands/kb_show.js +385 -0
  44. package/dist/commands/label.js +226 -0
  45. package/dist/commands/login.js +295 -0
  46. package/dist/commands/logout.js +108 -0
  47. package/dist/commands/mcp-supervisor.js +93 -0
  48. package/dist/commands/mcp.js +227 -0
  49. package/dist/commands/queue-prune.js +98 -0
  50. package/dist/commands/review.js +358 -0
  51. package/dist/commands/rewire.js +124 -0
  52. package/dist/commands/rules.js +728 -0
  53. package/dist/commands/scan-context.js +67 -0
  54. package/dist/commands/session.js +347 -0
  55. package/dist/commands/stats.js +479 -0
  56. package/dist/commands/status.js +61 -0
  57. package/dist/commands/summary.js +250 -0
  58. package/dist/commands/turn.js +114 -0
  59. package/dist/commands/uninstall.js +222 -0
  60. package/dist/commands/whoami.js +102 -0
  61. package/dist/commands/workspace.js +130 -0
  62. package/dist/hooks-template/ce0-post-tool-use.sh +34 -0
  63. package/dist/hooks-template/ce0-session-start.sh +49 -0
  64. package/dist/hooks-template/ce0-stop.sh +29 -0
  65. package/dist/hooks-template/ce0-user-prompt-submit.sh +38 -0
  66. package/dist/hooks-template/common.sh +934 -0
  67. package/dist/hooks-template/event-batch-filter.jq +67 -0
  68. package/dist/hooks-template/flush.sh +503 -0
  69. package/dist/hooks-template/post-tool-use.sh +423 -0
  70. package/dist/hooks-template/pre-tool-use.sh +69 -0
  71. package/dist/hooks-template/session-start.sh +140 -0
  72. package/dist/hooks-template/stop.sh +308 -0
  73. package/dist/hooks-template/user-prompt-submit.sh +1162 -0
  74. package/dist/lib/activation.js +79 -0
  75. package/dist/lib/active-conflict-cache.js +141 -0
  76. package/dist/lib/active-memory.js +59 -0
  77. package/dist/lib/active-review-runner.js +26 -0
  78. package/dist/lib/agent-decision/index.js +25 -0
  79. package/dist/lib/agent-decision/keys.js +49 -0
  80. package/dist/lib/agent-decision/normalize-claude.js +183 -0
  81. package/dist/lib/agent-decision/types.js +21 -0
  82. package/dist/lib/agent-decision/validate.js +216 -0
  83. package/dist/lib/analytics/capture.js +96 -0
  84. package/dist/lib/analytics/command-event.js +267 -0
  85. package/dist/lib/analytics/consent.js +58 -0
  86. package/dist/lib/analytics/coverage-gap.js +96 -0
  87. package/dist/lib/analytics/envelope.js +236 -0
  88. package/dist/lib/analytics/event-id.js +86 -0
  89. package/dist/lib/analytics/evidence.js +150 -0
  90. package/dist/lib/analytics/followthrough.js +194 -0
  91. package/dist/lib/analytics/forwarder.js +109 -0
  92. package/dist/lib/analytics/logs.js +78 -0
  93. package/dist/lib/analytics/metrics.js +78 -0
  94. package/dist/lib/analytics/recorder.js +92 -0
  95. package/dist/lib/analytics/review-analytics.js +75 -0
  96. package/dist/lib/analytics/sequence.js +77 -0
  97. package/dist/lib/analytics/store.js +131 -0
  98. package/dist/lib/analytics/turn-recap.js +279 -0
  99. package/dist/lib/artifact_id.js +108 -0
  100. package/dist/lib/auth-breaker.js +161 -0
  101. package/dist/lib/auto-index.js +112 -0
  102. package/dist/lib/classifier.js +88 -0
  103. package/dist/lib/config.js +298 -0
  104. package/dist/lib/conflict-advisory.js +64 -0
  105. package/dist/lib/debug-bundle.js +520 -0
  106. package/dist/lib/enrichment/ingest.js +301 -0
  107. package/dist/lib/enrichment/plan.js +253 -0
  108. package/dist/lib/enrichment/protocol.js +359 -0
  109. package/dist/lib/enrichment/scout-brief.js +176 -0
  110. package/dist/lib/failure-telemetry.js +444 -0
  111. package/dist/lib/git.js +200 -0
  112. package/dist/lib/governance-cache.js +77 -0
  113. package/dist/lib/governed-path-cache.js +76 -0
  114. package/dist/lib/http.js +677 -0
  115. package/dist/lib/identity-envelope.js +23 -0
  116. package/dist/lib/kb-candidate.js +65 -0
  117. package/dist/lib/kb_acl.js +98 -0
  118. package/dist/lib/login.js +353 -0
  119. package/dist/lib/mcp-fetchers.js +130 -0
  120. package/dist/lib/mcp-restart.js +47 -0
  121. package/dist/lib/observability.js +805 -0
  122. package/dist/lib/open-url.js +33 -0
  123. package/dist/lib/orphan-guard.js +70 -0
  124. package/dist/lib/packaged.js +21 -0
  125. package/dist/lib/reconcile-sessions.js +171 -0
  126. package/dist/lib/redactor.js +89 -0
  127. package/dist/lib/relationship-candidate-query.js +27 -0
  128. package/dist/lib/render.js +611 -0
  129. package/dist/lib/rules/applicability.js +64 -0
  130. package/dist/lib/rules/attest-code-rule-version.js +47 -0
  131. package/dist/lib/rules/attest-notes-location.js +217 -0
  132. package/dist/lib/rules/attest-rule-version.js +69 -0
  133. package/dist/lib/rules/canonical-json.js +97 -0
  134. package/dist/lib/rules/ce0-emit.js +64 -0
  135. package/dist/lib/rules/ce0-evidence.js +281 -0
  136. package/dist/lib/rules/ce0-recall-sample.js +82 -0
  137. package/dist/lib/rules/ce0-rule.js +55 -0
  138. package/dist/lib/rules/ce0-sampling-bucket.js +15 -0
  139. package/dist/lib/rules/ce0-store.js +683 -0
  140. package/dist/lib/rules/ce0-telemetry-project.js +93 -0
  141. package/dist/lib/rules/ce0-telemetry.js +158 -0
  142. package/dist/lib/rules/code-rule-registry.js +17 -0
  143. package/dist/lib/rules/command-match.js +185 -0
  144. package/dist/lib/rules/consult-evidence-binding.js +27 -0
  145. package/dist/lib/rules/consultation-capture-adapter.js +193 -0
  146. package/dist/lib/rules/content-match.js +56 -0
  147. package/dist/lib/rules/deny-admission.js +99 -0
  148. package/dist/lib/rules/durable-observation.js +190 -0
  149. package/dist/lib/rules/enforce-notes-version.js +421 -0
  150. package/dist/lib/rules/evaluation-input-hash.js +126 -0
  151. package/dist/lib/rules/evaluator.js +108 -0
  152. package/dist/lib/rules/inert-rule-families.js +51 -0
  153. package/dist/lib/rules/input-authority-resolver.js +241 -0
  154. package/dist/lib/rules/interception-schema.js +170 -0
  155. package/dist/lib/rules/interception-store.js +267 -0
  156. package/dist/lib/rules/live-input-authority.js +66 -0
  157. package/dist/lib/rules/local-matcher.js +108 -0
  158. package/dist/lib/rules/local-observe.js +79 -0
  159. package/dist/lib/rules/local-rule-version-repo.js +214 -0
  160. package/dist/lib/rules/memory-requirement.js +109 -0
  161. package/dist/lib/rules/notes-observe.js +39 -0
  162. package/dist/lib/rules/notes-path.js +261 -0
  163. package/dist/lib/rules/notes-rule.js +75 -0
  164. package/dist/lib/rules/observe-adapter.js +114 -0
  165. package/dist/lib/rules/observed-rule-hash.js +119 -0
  166. package/dist/lib/rules/prompt-submit-adapter.js +132 -0
  167. package/dist/lib/rules/requirement-subject.js +240 -0
  168. package/dist/lib/rules/rule-activity.js +67 -0
  169. package/dist/lib/rules/rule-version-hash.js +151 -0
  170. package/dist/lib/rules/runtime-scope.js +55 -0
  171. package/dist/lib/rules/stop-adapter.js +116 -0
  172. package/dist/lib/rules/stop-response-snapshot.js +174 -0
  173. package/dist/lib/rules/types.js +10 -0
  174. package/dist/lib/rules/ulid.js +46 -0
  175. package/dist/lib/rules/version-evaluation.js +156 -0
  176. package/dist/lib/scanner/agent-memory.js +99 -0
  177. package/dist/lib/scanner/bootstrap-summary.js +87 -0
  178. package/dist/lib/scanner/cache.js +59 -0
  179. package/dist/lib/scanner/frontmatter.js +42 -0
  180. package/dist/lib/scanner/parse-directives.js +69 -0
  181. package/dist/lib/scanner/parse-structured.js +72 -0
  182. package/dist/lib/scanner/render.js +73 -0
  183. package/dist/lib/scanner/scan.js +132 -0
  184. package/dist/lib/scanner/score.js +38 -0
  185. package/dist/lib/scanner/scout-mission.js +126 -0
  186. package/dist/lib/scanner/types.js +7 -0
  187. package/dist/lib/session-scope.js +195 -0
  188. package/dist/lib/spool.js +355 -0
  189. package/dist/lib/staleness.js +100 -0
  190. package/dist/lib/steer-cache.js +87 -0
  191. package/dist/lib/tagged-reference.js +20 -0
  192. package/dist/lib/temporal.js +109 -0
  193. package/dist/lib/turn-recap-emit.js +67 -0
  194. package/dist/lib/unwire.js +253 -0
  195. package/dist/lib/update-check.js +469 -0
  196. package/dist/lib/update-notifier.js +217 -0
  197. package/dist/lib/upgrade-apply.js +643 -0
  198. package/dist/lib/wire.js +1087 -0
  199. package/dist/lib/workspace.js +96 -0
  200. package/dist/lib/zip.js +154 -0
  201. package/dist/pretool-entry.js +37 -0
  202. package/package.json +75 -0
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarkerMissingWorkspaceIdError = exports.NotActivatedError = void 0;
4
+ exports.findWorkspaceContext = findWorkspaceContext;
5
+ exports.resolveWorkspaceContext = resolveWorkspaceContext;
6
+ exports.resolveWorkspaceId = resolveWorkspaceId;
7
+ exports.tryResolveWorkspaceId = tryResolveWorkspaceId;
8
+ exports.resolveWorkspaceIdWithEnv = resolveWorkspaceIdWithEnv;
9
+ const activation_1 = require("./activation");
10
+ // Folder = workspace (notes/20260604-folder-equals-workspace-binding-design.md,
11
+ // T1.1). The single shared resolver for "which workspace is this directory bound
12
+ // to?". It walks UP from a start dir to the nearest `.meetless.json` marker
13
+ // (nearest-wins, mirroring how Claude Code resolves CLAUDE.md and how the bash
14
+ // gate `meetless_activated` behaves) and returns the marker's workspaceId.
15
+ //
16
+ // The marker is the ONLY source of the workspaceId. There is no cli-config
17
+ // fallback: cli-config carries machine creds (controlUrl, controlToken, actor),
18
+ // never the per-folder workspace binding. A directory with no usable marker is
19
+ // "not activated" and workspace-scoped commands refuse with a clear pointer to
20
+ // `mla activate`.
21
+ class NotActivatedError extends Error {
22
+ startDir;
23
+ constructor(startDir) {
24
+ super(`No Meetless workspace is activated for this directory ` +
25
+ `(${startDir}). Run 'mla activate' here to bind this repository to a ` +
26
+ `workspace. Meetless resolves the workspace from the nearest ` +
27
+ `.meetless.json, walking up from the current directory.`);
28
+ this.startDir = startDir;
29
+ this.name = "NotActivatedError";
30
+ }
31
+ }
32
+ exports.NotActivatedError = NotActivatedError;
33
+ class MarkerMissingWorkspaceIdError extends Error {
34
+ markerPath;
35
+ constructor(markerPath) {
36
+ super(`The Meetless marker at ${markerPath} has no usable workspaceId ` +
37
+ `(missing or malformed). Re-run 'mla activate' to repair the binding.`);
38
+ this.markerPath = markerPath;
39
+ this.name = "MarkerMissingWorkspaceIdError";
40
+ }
41
+ }
42
+ exports.MarkerMissingWorkspaceIdError = MarkerMissingWorkspaceIdError;
43
+ // Non-throwing lookup: returns the resolved context, or null when no usable
44
+ // marker exists up the tree (no marker at all, or a marker with no workspaceId).
45
+ // Use this on best-effort paths (CLI bootstrap trace flush, prefetch) that must
46
+ // degrade silently rather than fail a non-workspace command.
47
+ function findWorkspaceContext(startDir = process.cwd()) {
48
+ const found = (0, activation_1.findActivation)(startDir);
49
+ if (!found || !found.workspaceId)
50
+ return null;
51
+ return {
52
+ workspaceId: found.workspaceId,
53
+ workspaceName: found.workspaceName,
54
+ markerPath: found.path,
55
+ markerDir: found.dir,
56
+ };
57
+ }
58
+ // Throwing lookup for command bodies that REQUIRE an activated workspace.
59
+ // Distinguishes "no marker" (NotActivatedError) from "marker present but no
60
+ // usable workspaceId" (MarkerMissingWorkspaceIdError) so callers and `mla
61
+ // doctor` / `mla workspace show` can report a stale binding precisely.
62
+ function resolveWorkspaceContext(startDir = process.cwd()) {
63
+ const found = (0, activation_1.findActivation)(startDir);
64
+ if (!found)
65
+ throw new NotActivatedError(startDir);
66
+ if (!found.workspaceId)
67
+ throw new MarkerMissingWorkspaceIdError(found.path);
68
+ return {
69
+ workspaceId: found.workspaceId,
70
+ workspaceName: found.workspaceName,
71
+ markerPath: found.path,
72
+ markerDir: found.dir,
73
+ };
74
+ }
75
+ function resolveWorkspaceId(startDir = process.cwd()) {
76
+ return resolveWorkspaceContext(startDir).workspaceId;
77
+ }
78
+ function tryResolveWorkspaceId(startDir = process.cwd()) {
79
+ const ctx = findWorkspaceContext(startDir);
80
+ return ctx ? ctx.workspaceId : null;
81
+ }
82
+ // Shared resolver for commands that require a workspace: checks the
83
+ // MEETLESS_WORKSPACE_ID env var first (operator override), then walks up from
84
+ // process.cwd() via tryResolveWorkspaceId to the nearest .meetless.json marker.
85
+ // Returns undefined when neither source yields an id. Never throws.
86
+ function resolveWorkspaceIdWithEnv() {
87
+ const envWs = (process.env.MEETLESS_WORKSPACE_ID ?? "").trim();
88
+ if (envWs)
89
+ return envWs;
90
+ try {
91
+ return tryResolveWorkspaceId() ?? undefined;
92
+ }
93
+ catch {
94
+ return undefined;
95
+ }
96
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ // Zero-dependency, store-only (uncompressed) ZIP writer + reader.
3
+ //
4
+ // The mla CLI deliberately keeps a tiny dependency surface (Phase 4.5 OSS
5
+ // hardening: only @sentry/node + the workspace trace-core). The Phase 5 debug
6
+ // bundle (gap 6.7) needs to emit a single .zip; pulling in archiver/adm-zip just
7
+ // for that would undo that hardening. A store-only ZIP is a small, well-specified
8
+ // container (PKWARE APPNOTE: local file header + central directory + end-of-
9
+ // central-directory), so we hand-roll it here with only Node built-ins.
10
+ //
11
+ // "Store" means no compression: the file bytes appear verbatim. That is fine for
12
+ // a debug bundle (text + small JSON) and removes the only part of the spec that
13
+ // would need zlib stream plumbing. CRC-32 is still required by the format and is
14
+ // implemented below; readStoredZip verifies it on read so a corrupt bundle is
15
+ // caught rather than silently opened.
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.crc32 = crc32;
18
+ exports.createZip = createZip;
19
+ exports.readStoredZip = readStoredZip;
20
+ const LOCAL_FILE_HEADER_SIG = 0x04034b50;
21
+ const CENTRAL_DIR_SIG = 0x02014b50;
22
+ const END_OF_CENTRAL_DIR_SIG = 0x06054b50;
23
+ // Fixed DOS timestamp (1980-01-01 00:00:00, the ZIP epoch). Deterministic by
24
+ // design: the bundle's real created-at lives in manifest.json, and a fixed entry
25
+ // time keeps two bundles of the same inputs byte-identical (easier to test and
26
+ // to diff). Avoids any reliance on a wall clock in the archive layer.
27
+ const DOS_DATE = 0x0021; // year=1980, month=1, day=1
28
+ const DOS_TIME = 0x0000;
29
+ const CRC_TABLE = (() => {
30
+ const table = new Array(256);
31
+ for (let n = 0; n < 256; n++) {
32
+ let c = n;
33
+ for (let k = 0; k < 8; k++) {
34
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
35
+ }
36
+ table[n] = c >>> 0;
37
+ }
38
+ return table;
39
+ })();
40
+ function crc32(buf) {
41
+ let crc = 0xffffffff;
42
+ for (let i = 0; i < buf.length; i++) {
43
+ crc = CRC_TABLE[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
44
+ }
45
+ return (crc ^ 0xffffffff) >>> 0;
46
+ }
47
+ // Build a store-only ZIP archive from the given entries. Names use forward
48
+ // slashes (the ZIP convention) and are encoded UTF-8.
49
+ function createZip(entries) {
50
+ const localChunks = [];
51
+ const centralChunks = [];
52
+ let offset = 0;
53
+ for (const entry of entries) {
54
+ const nameBuf = Buffer.from(entry.name.replace(/\\/g, "/"), "utf8");
55
+ const data = entry.data;
56
+ const crc = crc32(data);
57
+ const local = Buffer.alloc(30);
58
+ local.writeUInt32LE(LOCAL_FILE_HEADER_SIG, 0);
59
+ local.writeUInt16LE(20, 4); // version needed (2.0)
60
+ local.writeUInt16LE(0x0800, 6); // flags: bit 11 = UTF-8 names
61
+ local.writeUInt16LE(0, 8); // method: 0 = store
62
+ local.writeUInt16LE(DOS_TIME, 10);
63
+ local.writeUInt16LE(DOS_DATE, 12);
64
+ local.writeUInt32LE(crc, 14);
65
+ local.writeUInt32LE(data.length, 18); // compressed size == size (store)
66
+ local.writeUInt32LE(data.length, 22); // uncompressed size
67
+ local.writeUInt16LE(nameBuf.length, 26);
68
+ local.writeUInt16LE(0, 28); // extra field length
69
+ localChunks.push(local, nameBuf, data);
70
+ const central = Buffer.alloc(46);
71
+ central.writeUInt32LE(CENTRAL_DIR_SIG, 0);
72
+ central.writeUInt16LE(20, 4); // version made by
73
+ central.writeUInt16LE(20, 6); // version needed
74
+ central.writeUInt16LE(0x0800, 8); // flags: UTF-8
75
+ central.writeUInt16LE(0, 10); // method: store
76
+ central.writeUInt16LE(DOS_TIME, 12);
77
+ central.writeUInt16LE(DOS_DATE, 14);
78
+ central.writeUInt32LE(crc, 16);
79
+ central.writeUInt32LE(data.length, 20);
80
+ central.writeUInt32LE(data.length, 24);
81
+ central.writeUInt16LE(nameBuf.length, 28);
82
+ central.writeUInt16LE(0, 30); // extra length
83
+ central.writeUInt16LE(0, 32); // comment length
84
+ central.writeUInt16LE(0, 34); // disk number start
85
+ central.writeUInt16LE(0, 36); // internal attrs
86
+ central.writeUInt32LE(0, 38); // external attrs
87
+ central.writeUInt32LE(offset, 42); // local header offset
88
+ centralChunks.push(central, nameBuf);
89
+ offset += local.length + nameBuf.length + data.length;
90
+ }
91
+ const centralDir = Buffer.concat(centralChunks);
92
+ const localData = Buffer.concat(localChunks);
93
+ const eocd = Buffer.alloc(22);
94
+ eocd.writeUInt32LE(END_OF_CENTRAL_DIR_SIG, 0);
95
+ eocd.writeUInt16LE(0, 4); // disk number
96
+ eocd.writeUInt16LE(0, 6); // disk with central dir
97
+ eocd.writeUInt16LE(entries.length, 8); // entries on this disk
98
+ eocd.writeUInt16LE(entries.length, 10); // total entries
99
+ eocd.writeUInt32LE(centralDir.length, 12); // central dir size
100
+ eocd.writeUInt32LE(localData.length, 16); // central dir offset
101
+ eocd.writeUInt16LE(0, 20); // comment length
102
+ return Buffer.concat([localData, centralDir, eocd]);
103
+ }
104
+ // Parse a store-only ZIP produced by createZip back into its entries, verifying
105
+ // each entry's CRC-32. Throws on a malformed archive or a CRC mismatch. Used by
106
+ // the debug-bundle tests for a real round-trip and available for self-verify.
107
+ function readStoredZip(buf) {
108
+ // Locate the end-of-central-directory record (no trailing comment, so it is
109
+ // the last 22 bytes for archives we produce).
110
+ let eocdOffset = -1;
111
+ for (let i = buf.length - 22; i >= 0; i--) {
112
+ if (buf.readUInt32LE(i) === END_OF_CENTRAL_DIR_SIG) {
113
+ eocdOffset = i;
114
+ break;
115
+ }
116
+ }
117
+ if (eocdOffset < 0) {
118
+ throw new Error("readStoredZip: end-of-central-directory record not found");
119
+ }
120
+ const total = buf.readUInt16LE(eocdOffset + 10);
121
+ let p = buf.readUInt32LE(eocdOffset + 16); // central dir offset
122
+ const entries = [];
123
+ for (let n = 0; n < total; n++) {
124
+ if (buf.readUInt32LE(p) !== CENTRAL_DIR_SIG) {
125
+ throw new Error("readStoredZip: bad central directory signature");
126
+ }
127
+ const method = buf.readUInt16LE(p + 10);
128
+ if (method !== 0) {
129
+ throw new Error(`readStoredZip: unsupported method ${method} (store only)`);
130
+ }
131
+ const crc = buf.readUInt32LE(p + 16);
132
+ const size = buf.readUInt32LE(p + 24);
133
+ const nameLen = buf.readUInt16LE(p + 28);
134
+ const extraLen = buf.readUInt16LE(p + 30);
135
+ const commentLen = buf.readUInt16LE(p + 32);
136
+ const localOffset = buf.readUInt32LE(p + 42);
137
+ const name = buf.toString("utf8", p + 46, p + 46 + nameLen);
138
+ // Walk into the local header to find the data start (its name/extra lengths
139
+ // can differ from the central record's, so read them locally).
140
+ if (buf.readUInt32LE(localOffset) !== LOCAL_FILE_HEADER_SIG) {
141
+ throw new Error("readStoredZip: bad local file header signature");
142
+ }
143
+ const localNameLen = buf.readUInt16LE(localOffset + 26);
144
+ const localExtraLen = buf.readUInt16LE(localOffset + 28);
145
+ const dataStart = localOffset + 30 + localNameLen + localExtraLen;
146
+ const data = buf.subarray(dataStart, dataStart + size);
147
+ if (crc32(data) !== crc) {
148
+ throw new Error(`readStoredZip: CRC mismatch for ${name}`);
149
+ }
150
+ entries.push({ name, data: Buffer.from(data) });
151
+ p += 46 + nameLen + extraLen + commentLen;
152
+ }
153
+ return entries;
154
+ }
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runPretoolEntry = runPretoolEntry;
5
+ // The minimal PreToolUse entrypoint (latency lever A,
6
+ // notes/20260615-rules-as-node-and-action-interception-consolidated-proposal.md).
7
+ //
8
+ // The managed pre-tool-use.sh hook runs THIS file (`node dist/pretool-entry.js`)
9
+ // directly instead of `mla _internal pretool-observe`. Both call the very same
10
+ // runInternalPretoolObserve core, so the deny decision is byte-identical; the only
11
+ // difference is the require graph. cli.js eagerly pulls all 30+ command modules
12
+ // (~150ms cold). This entry's transitive closure is only the ce0 store + the
13
+ // rules/scanner deny path (~12ms cold), a ~10x cold-start cut on the Write/Edit hot
14
+ // path. When this file is absent (a pkg binary, an older install), the hook falls
15
+ // back to `mla _internal pretool-observe`, so the slow path stays correct.
16
+ //
17
+ // It is a thin IO shell: read the decision via stdin (the core does it), forward the
18
+ // core's exit code, and fail OPEN (exit 0) on any unexpected rejection so an
19
+ // entrypoint fault can never escalate into a blocking hook decision.
20
+ const internal_pretool_observe_1 = require("./commands/internal-pretool-observe");
21
+ /**
22
+ * Run the observe core with no argv (the PreToolUse payload arrives on stdin, not in
23
+ * args) and forward its exit code. The core already fails open internally to exit 0;
24
+ * the catch here is the belt-and-suspenders guard for an unexpected throw before the
25
+ * promise settles, preserving the "never block a tool" invariant at the process edge.
26
+ */
27
+ async function runPretoolEntry(observe = internal_pretool_observe_1.runInternalPretoolObserve, exit = (code) => process.exit(code)) {
28
+ try {
29
+ exit(await observe([]));
30
+ }
31
+ catch {
32
+ exit(0);
33
+ }
34
+ }
35
+ if (require.main === module) {
36
+ void runPretoolEntry();
37
+ }
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@meetless/mla",
3
+ "version": "0.1.4",
4
+ "license": "Apache-2.0",
5
+ "private": false,
6
+ "description": "Meetless CLI (mla): governed change-control and knowledge for AI coding agents.",
7
+ "keywords": [
8
+ "meetless",
9
+ "mla",
10
+ "cli",
11
+ "ai",
12
+ "coding-agent",
13
+ "claude-code",
14
+ "mcp",
15
+ "governance",
16
+ "knowledge-base"
17
+ ],
18
+ "homepage": "https://meetless.ai",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/Meetless/mla.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/Meetless/mla/issues"
25
+ },
26
+ "author": "Meetless",
27
+ "type": "commonjs",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "bin": {
32
+ "mla": "dist/cli.js"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md"
37
+ ],
38
+ "engines": {
39
+ "node": ">=18.18.0"
40
+ },
41
+ "pkg": {
42
+ "assets": [
43
+ "dist/hooks-template/**/*",
44
+ "dist/build-info.json"
45
+ ],
46
+ "scripts": [
47
+ "dist/**/*.js"
48
+ ]
49
+ },
50
+ "dependencies": {
51
+ "@sentry/node": "^10.39.0",
52
+ "better-sqlite3": "^11.8.0"
53
+ },
54
+ "devDependencies": {
55
+ "@types/better-sqlite3": "^7.6.11",
56
+ "@types/jest": "^29.5.12",
57
+ "@types/node": "^20.11.30",
58
+ "@yao-pkg/pkg": "^6.3.0",
59
+ "esbuild": "^0.28.0",
60
+ "jest": "^29.7.0",
61
+ "ts-jest": "^29.1.2",
62
+ "ts-node": "^10.9.2",
63
+ "typescript": "^5.4.5",
64
+ "@meetless/mcp": "0.1.0",
65
+ "@meetless/trace-core": "0.1.0",
66
+ "@meetless/ask-core": "0.1.0"
67
+ },
68
+ "scripts": {
69
+ "build": "tsc -p tsconfig.json && node scripts/copy-assets.js && node scripts/gen-build-info.js && node scripts/bundle-esm.js && chmod +x dist/cli.js dist/pretool-entry.js",
70
+ "dev": "ts-node src/cli.ts",
71
+ "start": "node dist/cli.js",
72
+ "test": "jest --config jest.config.js",
73
+ "typecheck": "tsc --noEmit -p tsconfig.json"
74
+ }
75
+ }