@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.
- package/LICENSE +201 -0
- package/README.md +81 -0
- package/dist/build-info.json +9 -0
- package/dist/bundles/ask-core.js +396 -0
- package/dist/bundles/mcp.js +16592 -0
- package/dist/bundles/trace-core.js +263 -0
- package/dist/cli.js +828 -0
- package/dist/commands/activate.js +781 -0
- package/dist/commands/adoption.js +130 -0
- package/dist/commands/ask.js +290 -0
- package/dist/commands/context.js +114 -0
- package/dist/commands/debug.js +313 -0
- package/dist/commands/doctor.js +1021 -0
- package/dist/commands/enrich.js +427 -0
- package/dist/commands/evidence.js +229 -0
- package/dist/commands/flush.js +184 -0
- package/dist/commands/graph.js +104 -0
- package/dist/commands/init.js +272 -0
- package/dist/commands/internal-active-review.js +322 -0
- package/dist/commands/internal-auto-index.js +188 -0
- package/dist/commands/internal-capture-decisions.js +320 -0
- package/dist/commands/internal-evidence-correlate.js +239 -0
- package/dist/commands/internal-evidence-hooks.js +240 -0
- package/dist/commands/internal-evidence-inject.js +231 -0
- package/dist/commands/internal-finalize.js +221 -0
- package/dist/commands/internal-pretool-observe.js +225 -0
- package/dist/commands/internal-refresh.js +136 -0
- package/dist/commands/internal-session-nudge.js +120 -0
- package/dist/commands/internal-steer-sync.js +117 -0
- package/dist/commands/internal-turn-recap.js +140 -0
- package/dist/commands/kb.js +375 -0
- package/dist/commands/kb_add.js +681 -0
- package/dist/commands/kb_forget.js +283 -0
- package/dist/commands/kb_move.js +45 -0
- package/dist/commands/kb_pending.js +410 -0
- package/dist/commands/kb_personal.js +149 -0
- package/dist/commands/kb_promote.js +188 -0
- package/dist/commands/kb_purge.js +168 -0
- package/dist/commands/kb_reingest.js +335 -0
- package/dist/commands/kb_retime.js +170 -0
- package/dist/commands/kb_review.js +391 -0
- package/dist/commands/kb_revision.js +179 -0
- package/dist/commands/kb_show.js +385 -0
- package/dist/commands/label.js +226 -0
- package/dist/commands/login.js +295 -0
- package/dist/commands/logout.js +108 -0
- package/dist/commands/mcp-supervisor.js +93 -0
- package/dist/commands/mcp.js +227 -0
- package/dist/commands/queue-prune.js +98 -0
- package/dist/commands/review.js +358 -0
- package/dist/commands/rewire.js +124 -0
- package/dist/commands/rules.js +728 -0
- package/dist/commands/scan-context.js +67 -0
- package/dist/commands/session.js +347 -0
- package/dist/commands/stats.js +479 -0
- package/dist/commands/status.js +61 -0
- package/dist/commands/summary.js +250 -0
- package/dist/commands/turn.js +114 -0
- package/dist/commands/uninstall.js +222 -0
- package/dist/commands/whoami.js +102 -0
- package/dist/commands/workspace.js +130 -0
- package/dist/hooks-template/ce0-post-tool-use.sh +34 -0
- package/dist/hooks-template/ce0-session-start.sh +49 -0
- package/dist/hooks-template/ce0-stop.sh +29 -0
- package/dist/hooks-template/ce0-user-prompt-submit.sh +38 -0
- package/dist/hooks-template/common.sh +934 -0
- package/dist/hooks-template/event-batch-filter.jq +67 -0
- package/dist/hooks-template/flush.sh +503 -0
- package/dist/hooks-template/post-tool-use.sh +423 -0
- package/dist/hooks-template/pre-tool-use.sh +69 -0
- package/dist/hooks-template/session-start.sh +140 -0
- package/dist/hooks-template/stop.sh +308 -0
- package/dist/hooks-template/user-prompt-submit.sh +1162 -0
- package/dist/lib/activation.js +79 -0
- package/dist/lib/active-conflict-cache.js +141 -0
- package/dist/lib/active-memory.js +59 -0
- package/dist/lib/active-review-runner.js +26 -0
- package/dist/lib/agent-decision/index.js +25 -0
- package/dist/lib/agent-decision/keys.js +49 -0
- package/dist/lib/agent-decision/normalize-claude.js +183 -0
- package/dist/lib/agent-decision/types.js +21 -0
- package/dist/lib/agent-decision/validate.js +216 -0
- package/dist/lib/analytics/capture.js +96 -0
- package/dist/lib/analytics/command-event.js +267 -0
- package/dist/lib/analytics/consent.js +58 -0
- package/dist/lib/analytics/coverage-gap.js +96 -0
- package/dist/lib/analytics/envelope.js +236 -0
- package/dist/lib/analytics/event-id.js +86 -0
- package/dist/lib/analytics/evidence.js +150 -0
- package/dist/lib/analytics/followthrough.js +194 -0
- package/dist/lib/analytics/forwarder.js +109 -0
- package/dist/lib/analytics/logs.js +78 -0
- package/dist/lib/analytics/metrics.js +78 -0
- package/dist/lib/analytics/recorder.js +92 -0
- package/dist/lib/analytics/review-analytics.js +75 -0
- package/dist/lib/analytics/sequence.js +77 -0
- package/dist/lib/analytics/store.js +131 -0
- package/dist/lib/analytics/turn-recap.js +279 -0
- package/dist/lib/artifact_id.js +108 -0
- package/dist/lib/auth-breaker.js +161 -0
- package/dist/lib/auto-index.js +112 -0
- package/dist/lib/classifier.js +88 -0
- package/dist/lib/config.js +298 -0
- package/dist/lib/conflict-advisory.js +64 -0
- package/dist/lib/debug-bundle.js +520 -0
- package/dist/lib/enrichment/ingest.js +301 -0
- package/dist/lib/enrichment/plan.js +253 -0
- package/dist/lib/enrichment/protocol.js +359 -0
- package/dist/lib/enrichment/scout-brief.js +176 -0
- package/dist/lib/failure-telemetry.js +444 -0
- package/dist/lib/git.js +200 -0
- package/dist/lib/governance-cache.js +77 -0
- package/dist/lib/governed-path-cache.js +76 -0
- package/dist/lib/http.js +677 -0
- package/dist/lib/identity-envelope.js +23 -0
- package/dist/lib/kb-candidate.js +65 -0
- package/dist/lib/kb_acl.js +98 -0
- package/dist/lib/login.js +353 -0
- package/dist/lib/mcp-fetchers.js +130 -0
- package/dist/lib/mcp-restart.js +47 -0
- package/dist/lib/observability.js +805 -0
- package/dist/lib/open-url.js +33 -0
- package/dist/lib/orphan-guard.js +70 -0
- package/dist/lib/packaged.js +21 -0
- package/dist/lib/reconcile-sessions.js +171 -0
- package/dist/lib/redactor.js +89 -0
- package/dist/lib/relationship-candidate-query.js +27 -0
- package/dist/lib/render.js +611 -0
- package/dist/lib/rules/applicability.js +64 -0
- package/dist/lib/rules/attest-code-rule-version.js +47 -0
- package/dist/lib/rules/attest-notes-location.js +217 -0
- package/dist/lib/rules/attest-rule-version.js +69 -0
- package/dist/lib/rules/canonical-json.js +97 -0
- package/dist/lib/rules/ce0-emit.js +64 -0
- package/dist/lib/rules/ce0-evidence.js +281 -0
- package/dist/lib/rules/ce0-recall-sample.js +82 -0
- package/dist/lib/rules/ce0-rule.js +55 -0
- package/dist/lib/rules/ce0-sampling-bucket.js +15 -0
- package/dist/lib/rules/ce0-store.js +683 -0
- package/dist/lib/rules/ce0-telemetry-project.js +93 -0
- package/dist/lib/rules/ce0-telemetry.js +158 -0
- package/dist/lib/rules/code-rule-registry.js +17 -0
- package/dist/lib/rules/command-match.js +185 -0
- package/dist/lib/rules/consult-evidence-binding.js +27 -0
- package/dist/lib/rules/consultation-capture-adapter.js +193 -0
- package/dist/lib/rules/content-match.js +56 -0
- package/dist/lib/rules/deny-admission.js +99 -0
- package/dist/lib/rules/durable-observation.js +190 -0
- package/dist/lib/rules/enforce-notes-version.js +421 -0
- package/dist/lib/rules/evaluation-input-hash.js +126 -0
- package/dist/lib/rules/evaluator.js +108 -0
- package/dist/lib/rules/inert-rule-families.js +51 -0
- package/dist/lib/rules/input-authority-resolver.js +241 -0
- package/dist/lib/rules/interception-schema.js +170 -0
- package/dist/lib/rules/interception-store.js +267 -0
- package/dist/lib/rules/live-input-authority.js +66 -0
- package/dist/lib/rules/local-matcher.js +108 -0
- package/dist/lib/rules/local-observe.js +79 -0
- package/dist/lib/rules/local-rule-version-repo.js +214 -0
- package/dist/lib/rules/memory-requirement.js +109 -0
- package/dist/lib/rules/notes-observe.js +39 -0
- package/dist/lib/rules/notes-path.js +261 -0
- package/dist/lib/rules/notes-rule.js +75 -0
- package/dist/lib/rules/observe-adapter.js +114 -0
- package/dist/lib/rules/observed-rule-hash.js +119 -0
- package/dist/lib/rules/prompt-submit-adapter.js +132 -0
- package/dist/lib/rules/requirement-subject.js +240 -0
- package/dist/lib/rules/rule-activity.js +67 -0
- package/dist/lib/rules/rule-version-hash.js +151 -0
- package/dist/lib/rules/runtime-scope.js +55 -0
- package/dist/lib/rules/stop-adapter.js +116 -0
- package/dist/lib/rules/stop-response-snapshot.js +174 -0
- package/dist/lib/rules/types.js +10 -0
- package/dist/lib/rules/ulid.js +46 -0
- package/dist/lib/rules/version-evaluation.js +156 -0
- package/dist/lib/scanner/agent-memory.js +99 -0
- package/dist/lib/scanner/bootstrap-summary.js +87 -0
- package/dist/lib/scanner/cache.js +59 -0
- package/dist/lib/scanner/frontmatter.js +42 -0
- package/dist/lib/scanner/parse-directives.js +69 -0
- package/dist/lib/scanner/parse-structured.js +72 -0
- package/dist/lib/scanner/render.js +73 -0
- package/dist/lib/scanner/scan.js +132 -0
- package/dist/lib/scanner/score.js +38 -0
- package/dist/lib/scanner/scout-mission.js +126 -0
- package/dist/lib/scanner/types.js +7 -0
- package/dist/lib/session-scope.js +195 -0
- package/dist/lib/spool.js +355 -0
- package/dist/lib/staleness.js +100 -0
- package/dist/lib/steer-cache.js +87 -0
- package/dist/lib/tagged-reference.js +20 -0
- package/dist/lib/temporal.js +109 -0
- package/dist/lib/turn-recap-emit.js +67 -0
- package/dist/lib/unwire.js +253 -0
- package/dist/lib/update-check.js +469 -0
- package/dist/lib/update-notifier.js +217 -0
- package/dist/lib/upgrade-apply.js +643 -0
- package/dist/lib/wire.js +1087 -0
- package/dist/lib/workspace.js +96 -0
- package/dist/lib/zip.js +154 -0
- package/dist/pretool-entry.js +37 -0
- 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
|
+
}
|
package/dist/lib/zip.js
ADDED
|
@@ -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
|
+
}
|