@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,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseArgs = parseArgs;
|
|
4
|
+
exports.runFlush = runFlush;
|
|
5
|
+
const spool_1 = require("../lib/spool");
|
|
6
|
+
const config_1 = require("../lib/config");
|
|
7
|
+
// Strict argv parsing for `mla flush` (Wedge v6 Epoch 48).
|
|
8
|
+
//
|
|
9
|
+
// The old parser had a genuinely dangerous silent-drop trap and a dead
|
|
10
|
+
// flag:
|
|
11
|
+
//
|
|
12
|
+
// 1. `--session` / `-s` with no following value silently bound
|
|
13
|
+
// `out.session = undefined`. Downstream, `flags.session ? [...] :
|
|
14
|
+
// listActiveSessions()` then treated undefined as falsy and
|
|
15
|
+
// drained EVERY pending session in the queue. The operator's
|
|
16
|
+
// intent ("drain just this one") flipped to "drain everything"
|
|
17
|
+
// with no diagnostic. On a busy machine that is dozens to
|
|
18
|
+
// hundreds of sessions and minutes of un-bounded fan-out.
|
|
19
|
+
//
|
|
20
|
+
// 2. `--all` was a dead flag. The ternary collapsed to
|
|
21
|
+
// `flags.all ? listActiveSessions() : listActiveSessions()`,
|
|
22
|
+
// so `--all` and the default both did the same thing. Operators
|
|
23
|
+
// reading the help text reasonably inferred the default behaved
|
|
24
|
+
// differently.
|
|
25
|
+
//
|
|
26
|
+
// Strict rules below:
|
|
27
|
+
// - Unknown `--`-prefixed token throws with the supported set.
|
|
28
|
+
// - `--session`/`-s` MUST be followed by a non-`--` value; a missing
|
|
29
|
+
// or flag-shape value throws rather than silently widening to
|
|
30
|
+
// "drain everything".
|
|
31
|
+
// - Positional argument is still allowed as a shortcut for
|
|
32
|
+
// `--session <sid>`, but a second positional throws.
|
|
33
|
+
// - `--all` and `--session` are mutually exclusive (passing both
|
|
34
|
+
// throws, rather than silently letting `--session` win).
|
|
35
|
+
// - `--all` is preserved as an explicit synonym for the default
|
|
36
|
+
// (drain every active session) but it is no longer a no-op
|
|
37
|
+
// branch; the runFlush body uses the single resolved
|
|
38
|
+
// `listActiveSessions()` call.
|
|
39
|
+
// - `--gc` additionally runs the age-gated stale-session reaper
|
|
40
|
+
// (reapQueue) AFTER the drain, removing dead-session litter
|
|
41
|
+
// (`.lock`/`.turn`/`.repoPath`/`.gitBaseline` and 0-byte spools
|
|
42
|
+
// idle longer than MEETLESS_QUEUE_GC_MAX_AGE_SEC, default 24h). It
|
|
43
|
+
// NEVER touches a session with undelivered work, so it is safe to
|
|
44
|
+
// pair with the default drain. `--gc` is whole-queue, so it is
|
|
45
|
+
// mutually exclusive with `--session` (draining one session while
|
|
46
|
+
// reaping all is contradictory intent).
|
|
47
|
+
// - `--reap-only` runs the SAME reaper but SKIPS the drain loop
|
|
48
|
+
// entirely. This is the Stop-hook path: the session that just
|
|
49
|
+
// ended already self-flushes via spawn_flush, so the hook only
|
|
50
|
+
// needs the cheap age-gated litter sweep. Tail-calling `--gc`
|
|
51
|
+
// there would re-drain EVERY active session on every Stop -- an
|
|
52
|
+
// O(sessions) fan-out per Stop, the exact pile-up that left 99
|
|
53
|
+
// stranded `.lock` files. `--reap-only` is whole-queue and pure
|
|
54
|
+
// reap, so it is mutually exclusive with `--gc` (redundant),
|
|
55
|
+
// `--all`, `--session`, and a positional id (all drain selectors).
|
|
56
|
+
const KNOWN_FLAGS = new Set(["--all", "--session", "-s", "--quiet", "-q", "--gc", "--reap-only"]);
|
|
57
|
+
// `--reap-only` reaps without draining; combining it with any drain
|
|
58
|
+
// selector is contradictory intent. Centralized so every branch raises
|
|
59
|
+
// the same message.
|
|
60
|
+
const REAP_ONLY_CONFLICT = "--reap-only reaps without draining; it cannot be combined with --gc/--all/--session";
|
|
61
|
+
function parseArgs(argv) {
|
|
62
|
+
const out = {};
|
|
63
|
+
for (let i = 0; i < argv.length; i++) {
|
|
64
|
+
const a = argv[i];
|
|
65
|
+
if (a === "--reap-only") {
|
|
66
|
+
if (out.all || out.gc || out.session !== undefined) {
|
|
67
|
+
throw new Error(REAP_ONLY_CONFLICT);
|
|
68
|
+
}
|
|
69
|
+
out.reapOnly = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (a === "--all") {
|
|
73
|
+
if (out.session !== undefined) {
|
|
74
|
+
throw new Error("--all and --session are mutually exclusive");
|
|
75
|
+
}
|
|
76
|
+
if (out.reapOnly) {
|
|
77
|
+
throw new Error(REAP_ONLY_CONFLICT);
|
|
78
|
+
}
|
|
79
|
+
out.all = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (a === "--gc") {
|
|
83
|
+
if (out.session !== undefined) {
|
|
84
|
+
throw new Error("--gc and --session are mutually exclusive (--gc reaps the whole queue)");
|
|
85
|
+
}
|
|
86
|
+
if (out.reapOnly) {
|
|
87
|
+
throw new Error(REAP_ONLY_CONFLICT);
|
|
88
|
+
}
|
|
89
|
+
out.gc = true;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (a === "--session" || a === "-s") {
|
|
93
|
+
if (out.all) {
|
|
94
|
+
throw new Error("--all and --session are mutually exclusive");
|
|
95
|
+
}
|
|
96
|
+
if (out.gc) {
|
|
97
|
+
throw new Error("--gc and --session are mutually exclusive (--gc reaps the whole queue)");
|
|
98
|
+
}
|
|
99
|
+
if (out.reapOnly) {
|
|
100
|
+
throw new Error(REAP_ONLY_CONFLICT);
|
|
101
|
+
}
|
|
102
|
+
const v = argv[i + 1];
|
|
103
|
+
if (v === undefined) {
|
|
104
|
+
throw new Error(`Missing value for ${a}`);
|
|
105
|
+
}
|
|
106
|
+
if (v.startsWith("--") || v.startsWith("-")) {
|
|
107
|
+
throw new Error(`Missing value for ${a} (got the next flag ${v} instead)`);
|
|
108
|
+
}
|
|
109
|
+
out.session = v;
|
|
110
|
+
i += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (a === "--quiet" || a === "-q") {
|
|
114
|
+
out.quiet = true;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (a.startsWith("--") || a.startsWith("-")) {
|
|
118
|
+
if (!KNOWN_FLAGS.has(a)) {
|
|
119
|
+
throw new Error(`Unknown flag: ${a}. Supported flags: --all, --session/-s, --quiet/-q, --gc, --reap-only`);
|
|
120
|
+
}
|
|
121
|
+
// Should be unreachable; KNOWN_FLAGS aligns with the branches above.
|
|
122
|
+
throw new Error(`Unhandled known flag: ${a}`);
|
|
123
|
+
}
|
|
124
|
+
if (out.reapOnly) {
|
|
125
|
+
throw new Error(REAP_ONLY_CONFLICT);
|
|
126
|
+
}
|
|
127
|
+
if (out.all) {
|
|
128
|
+
throw new Error(`Unexpected positional argument: ${a}. --all already drains every session.`);
|
|
129
|
+
}
|
|
130
|
+
if (out.gc) {
|
|
131
|
+
throw new Error(`--gc and a per-session id are mutually exclusive (--gc reaps the whole queue).`);
|
|
132
|
+
}
|
|
133
|
+
if (out.session !== undefined) {
|
|
134
|
+
throw new Error(`Unexpected extra positional argument: ${a}. \`mla flush\` accepts at most one session id.`);
|
|
135
|
+
}
|
|
136
|
+
out.session = a;
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
async function runFlush(argv, opts = {}) {
|
|
141
|
+
const flags = parseArgs(argv);
|
|
142
|
+
const hookDir = opts.hookDir ?? config_1.HOOKS_DIR;
|
|
143
|
+
const quiet = opts.quiet ?? flags.quiet;
|
|
144
|
+
let bad = 0;
|
|
145
|
+
// --reap-only skips the drain loop entirely (Stop-hook path). Everything
|
|
146
|
+
// else (`--all`, `--session`, the bare default) drains. `--all` and the bare
|
|
147
|
+
// default both mean "drain every active session"; the distinction is
|
|
148
|
+
// documentation-only. Collapse to a single resolved call so the dead-branch
|
|
149
|
+
// pattern that hid the missing-value trap cannot return.
|
|
150
|
+
if (!flags.reapOnly) {
|
|
151
|
+
const sessions = flags.session ? [flags.session] : (0, spool_1.listActiveSessions)();
|
|
152
|
+
if (sessions.length === 0) {
|
|
153
|
+
if (!quiet)
|
|
154
|
+
console.log("No sessions to flush.");
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
for (const sid of sessions) {
|
|
158
|
+
const r = (0, spool_1.runFlushScript)(sid, hookDir);
|
|
159
|
+
if (!r.ok) {
|
|
160
|
+
bad += 1;
|
|
161
|
+
if (!quiet)
|
|
162
|
+
console.error(`[flush] ${sid} FAILED: ${r.stderr.slice(0, 200)}`);
|
|
163
|
+
}
|
|
164
|
+
else if (!quiet) {
|
|
165
|
+
console.log(`[flush] ${sid} ok`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// --gc reaps dead-session litter AFTER the drain; --reap-only reaps WITHOUT
|
|
171
|
+
// draining. Drain-first (for --gc) is the conservative ordering -- a session
|
|
172
|
+
// that is still deliverable gets delivered (and self-cleaned by flush.sh's
|
|
173
|
+
// RC1 path) before the reaper looks at it, and reapQueue never touches a
|
|
174
|
+
// session with undelivered work regardless. Runs even when there was nothing
|
|
175
|
+
// to drain.
|
|
176
|
+
if (flags.gc || flags.reapOnly) {
|
|
177
|
+
const gc = (0, spool_1.reapQueue)();
|
|
178
|
+
if (!quiet) {
|
|
179
|
+
console.log(`[gc] reaped ${gc.reaped.length} stale session(s), removed ${gc.removedFiles} file(s)` +
|
|
180
|
+
` (${gc.skippedPending} with pending work and ${gc.skippedFresh} still-fresh kept)`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return bad > 0 ? 1 : 0;
|
|
184
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GRAPH_USAGE = void 0;
|
|
4
|
+
exports.runGraph = runGraph;
|
|
5
|
+
const kb_1 = require("./kb");
|
|
6
|
+
const kb_pending_1 = require("./kb_pending");
|
|
7
|
+
const kb_review_1 = require("./kb_review");
|
|
8
|
+
// `mla graph`: the coordination-graph (relationship) surface.
|
|
9
|
+
//
|
|
10
|
+
// notes/20260608-mla-ml-generalization-review.md, Q1. `mla kb` had grown to span
|
|
11
|
+
// two orthogonal axes:
|
|
12
|
+
// (a) document / posture: ingestion + grounding, LIVE vs SHADOW.
|
|
13
|
+
// (b) relationship / graph: typed edges between docs, decided via verdicts.
|
|
14
|
+
// Calling axis (b) "kb" buries the coordination graph (the product's substrate)
|
|
15
|
+
// under a storage noun. `mla graph` gives axis (b) its own home WITHOUT moving
|
|
16
|
+
// axis (a): `review`/`pending` route to the EXACT same handlers as
|
|
17
|
+
// `mla kb review`/`mla kb pending` (one implementation, two entry points), and the
|
|
18
|
+
// overload boundary + pending-alias semantics are imported from `./kb` so the two
|
|
19
|
+
// surfaces can never drift. `kb review`/`kb pending` stay as working back-compat.
|
|
20
|
+
//
|
|
21
|
+
// Deliberately NOT here: any document ingestion verb. The review's explicit trap
|
|
22
|
+
// is `graph add <file>` reading as "ingest"; that would re-blur the two axes the
|
|
23
|
+
// codebase fought to separate. Document/posture verbs typed under `graph` are
|
|
24
|
+
// redirected to `mla kb`, not silently rejected.
|
|
25
|
+
// The document/posture verbs that live under `mla kb`. Typing one of these under
|
|
26
|
+
// `graph` is an axis mismatch, not a typo, so each gets a pointed redirect rather
|
|
27
|
+
// than the generic unknown-subcommand catalog. `share` is the deprecated alias for
|
|
28
|
+
// `promote`; include it so the redirect fires for muscle-memory too.
|
|
29
|
+
const KB_DOC_POSTURE_VERBS = new Set([
|
|
30
|
+
"add",
|
|
31
|
+
"show",
|
|
32
|
+
"reingest",
|
|
33
|
+
"forget",
|
|
34
|
+
"purge",
|
|
35
|
+
"move",
|
|
36
|
+
"retime",
|
|
37
|
+
"promote",
|
|
38
|
+
"share",
|
|
39
|
+
"personal",
|
|
40
|
+
"summary",
|
|
41
|
+
"dump",
|
|
42
|
+
]);
|
|
43
|
+
// The user-facing `mla graph` catalog. It teaches the one fact that keeps the two
|
|
44
|
+
// axes apart: reviewing an edge records how docs RELATE; it never changes whether a
|
|
45
|
+
// doc is grounded (that is posture, under `mla kb`). The graph + control-projection
|
|
46
|
+
// layers expose per-item reads as counts only today (their per-item read endpoints
|
|
47
|
+
// remain deferred), so the catalog points at `mla kb summary` for graph counts
|
|
48
|
+
// rather than pretending a per-edge inspector exists. Keep "Usage" present: the
|
|
49
|
+
// unknown-subcommand path re-emits this block and a test locks that contract.
|
|
50
|
+
exports.GRAPH_USAGE = `mla graph: the coordination graph — relationship review (typed edges between docs).
|
|
51
|
+
|
|
52
|
+
The graph axis decides how docs RELATE: SUPERSEDES / CONTRADICTS / REFINES /
|
|
53
|
+
REFERENCES. It is independent of the document/posture axis (ingestion + grounding,
|
|
54
|
+
LIVE vs SHADOW), which lives under \`mla kb\`. Reviewing an edge records how two docs
|
|
55
|
+
relate; it NEVER changes whether a doc is grounded.
|
|
56
|
+
|
|
57
|
+
Usage:
|
|
58
|
+
mla graph review list the queue (defaults to your current session)
|
|
59
|
+
mla graph review --all list the full workspace queue
|
|
60
|
+
mla graph review --session <sid|current|latest> list a specific session's candidates
|
|
61
|
+
mla graph review [scope] --json structured output (agent policy + scope)
|
|
62
|
+
mla graph review <candidate-id> --accept | --reject [--note <text>] [--agent]
|
|
63
|
+
record a verdict (--accept is human-only)
|
|
64
|
+
mla graph pending [scope] deprecated alias for \`graph review\` (list mode)
|
|
65
|
+
|
|
66
|
+
Related (the OTHER axis — document/posture, not relationships):
|
|
67
|
+
mla kb ... ingest, ground (posture LIVE/SHADOW), and curate documents
|
|
68
|
+
mla kb summary substrate counts (includes graph entities + knowledge_relations)`;
|
|
69
|
+
// Router for the relationship/graph axis. Mirrors `runKb`'s help + dispatch
|
|
70
|
+
// shape; `review`/`pending` delegate to the shared handlers, document/posture
|
|
71
|
+
// verbs are redirected, everything else re-emits the catalog with exit 2.
|
|
72
|
+
async function runGraph(argv) {
|
|
73
|
+
const sub = argv[0];
|
|
74
|
+
const rest = argv.slice(1);
|
|
75
|
+
// Help is workspace-free: full catalog to stdout, exit 0. Reached by
|
|
76
|
+
// `mla graph`, `mla graph help`, and `mla graph --help/-h`.
|
|
77
|
+
if (sub === undefined || sub === "help" || sub === "--help" || sub === "-h") {
|
|
78
|
+
console.log(exports.GRAPH_USAGE);
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
switch (sub) {
|
|
82
|
+
case "review":
|
|
83
|
+
// Same overload boundary as `mla kb review`: a leading candidate id records
|
|
84
|
+
// a verdict; anything else (no args / leading flag) lists the queue.
|
|
85
|
+
return (0, kb_1.isReviewListInvocation)(rest) ? (0, kb_pending_1.runKbReviewList)(rest) : (0, kb_review_1.runKbReview)(rest);
|
|
86
|
+
case "pending":
|
|
87
|
+
// Deprecated alias for `review` (list mode); injects --all when no explicit
|
|
88
|
+
// scope so the historical workspace-wide default holds.
|
|
89
|
+
return (0, kb_pending_1.runKbReviewList)((0, kb_1.pendingAliasArgs)(rest));
|
|
90
|
+
}
|
|
91
|
+
// Axis mismatch: a document/posture verb typed under `graph`. Redirect to the
|
|
92
|
+
// surface that owns it instead of a generic "unknown subcommand" — this is the
|
|
93
|
+
// anti-conflation guardrail made executable.
|
|
94
|
+
if (KB_DOC_POSTURE_VERBS.has(sub)) {
|
|
95
|
+
console.error(`\`${sub}\` is a document/posture command (ingestion + grounding), not a ` +
|
|
96
|
+
`relationship (graph) command.\n` +
|
|
97
|
+
`Documents are ingested and grounded under \`mla kb\`. Run: mla kb ${sub} ...\n\n` +
|
|
98
|
+
`\`mla graph\` only reviews how docs RELATE. See \`mla graph help\`.`);
|
|
99
|
+
return 2;
|
|
100
|
+
}
|
|
101
|
+
console.error(`unknown \`mla graph\` subcommand: ${sub}\n`);
|
|
102
|
+
console.error(exports.GRAPH_USAGE);
|
|
103
|
+
return 2;
|
|
104
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseInitArgs = parseInitArgs;
|
|
37
|
+
exports.buildInitConfig = buildInitConfig;
|
|
38
|
+
exports.runInit = runInit;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const config_1 = require("../lib/config");
|
|
41
|
+
const wire_1 = require("../lib/wire");
|
|
42
|
+
// Strict argv parsing for `mla init` (Wedge v6 Epoch 54).
|
|
43
|
+
//
|
|
44
|
+
// The old parser used `const next = () => argv[++i]` and switched on
|
|
45
|
+
// the flag name. That shape had three real silent-drop classes, the
|
|
46
|
+
// first one is genuinely dangerous because it writes a corrupt
|
|
47
|
+
// 0o600-mode config that breaks every subsequent CLI call:
|
|
48
|
+
//
|
|
49
|
+
// 1. `mla init --control-token --intel-url http://x` bound
|
|
50
|
+
// controlToken = "--intel-url" (next() ate the next flag) and
|
|
51
|
+
// then "http://x" fell through the switch's `default` branch
|
|
52
|
+
// (positional, no `--` prefix) and was silently dropped. The
|
|
53
|
+
// operator's intent ("set token AND intel url") flipped to "set
|
|
54
|
+
// token to the string '--intel-url'", and the config was written
|
|
55
|
+
// at 0o600 perms with a wrong token. Every downstream `mla` call
|
|
56
|
+
// then 401'd with no obvious cause. (The trap applies to any value
|
|
57
|
+
// flag; `--workspace-id` was the original example before T3.1
|
|
58
|
+
// removed that flag.)
|
|
59
|
+
//
|
|
60
|
+
// 2. `mla init -x` (any short flag) hit the `default` branch's
|
|
61
|
+
// `if (a.startsWith("--"))` guard which is `--` only -- so `-x`
|
|
62
|
+
// was silently dropped with no diagnostic.
|
|
63
|
+
//
|
|
64
|
+
// 3. `mla init some_positional --control-token T` silently dropped
|
|
65
|
+
// the positional. No `mla init` flow takes positionals.
|
|
66
|
+
//
|
|
67
|
+
// Strict rules below:
|
|
68
|
+
// - Unknown `--`-prefixed or `-`-prefixed token throws with the
|
|
69
|
+
// supported set.
|
|
70
|
+
// - Value flags MUST be followed by a non-`--`/`-` value; missing
|
|
71
|
+
// or flag-shape value throws.
|
|
72
|
+
// - Positional arguments throw; `mla init` takes none.
|
|
73
|
+
const VALUE_FLAGS = new Set([
|
|
74
|
+
"--control-url",
|
|
75
|
+
"--control-token",
|
|
76
|
+
"--intel-url",
|
|
77
|
+
"--actor",
|
|
78
|
+
]);
|
|
79
|
+
const BOOLEAN_FLAGS = new Set([
|
|
80
|
+
"--no-post-tool-use",
|
|
81
|
+
"--unsafe-capture-non-bash",
|
|
82
|
+
"--skill-only",
|
|
83
|
+
"--no-install-flock",
|
|
84
|
+
"--no-project-rules",
|
|
85
|
+
"--no-mcp",
|
|
86
|
+
]);
|
|
87
|
+
function parseInitArgs(argv) {
|
|
88
|
+
const out = {};
|
|
89
|
+
for (let i = 0; i < argv.length; i++) {
|
|
90
|
+
const a = argv[i];
|
|
91
|
+
if (VALUE_FLAGS.has(a)) {
|
|
92
|
+
const v = argv[i + 1];
|
|
93
|
+
if (v === undefined) {
|
|
94
|
+
throw new Error(`Missing value for ${a}`);
|
|
95
|
+
}
|
|
96
|
+
if (v.startsWith("--") || v.startsWith("-")) {
|
|
97
|
+
throw new Error(`Missing value for ${a} (got the next flag ${v} instead)`);
|
|
98
|
+
}
|
|
99
|
+
if (a === "--control-url")
|
|
100
|
+
out.controlUrl = v;
|
|
101
|
+
else if (a === "--control-token")
|
|
102
|
+
out.controlToken = v;
|
|
103
|
+
else if (a === "--intel-url")
|
|
104
|
+
out.intelUrl = v;
|
|
105
|
+
else if (a === "--actor")
|
|
106
|
+
out.actorUserId = v;
|
|
107
|
+
i += 1;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (BOOLEAN_FLAGS.has(a)) {
|
|
111
|
+
if (a === "--no-post-tool-use")
|
|
112
|
+
out.noPostToolUse = true;
|
|
113
|
+
else if (a === "--unsafe-capture-non-bash")
|
|
114
|
+
out.unsafeCaptureNonBash = true;
|
|
115
|
+
else if (a === "--skill-only")
|
|
116
|
+
out.skillOnly = true;
|
|
117
|
+
else if (a === "--no-install-flock")
|
|
118
|
+
out.noInstallFlock = true;
|
|
119
|
+
else if (a === "--no-project-rules")
|
|
120
|
+
out.noProjectRules = true;
|
|
121
|
+
else if (a === "--no-mcp")
|
|
122
|
+
out.noMcp = true;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (a.startsWith("--") || a.startsWith("-")) {
|
|
126
|
+
throw new Error(`Unknown flag: ${a}. Supported flags: ${[...VALUE_FLAGS, ...BOOLEAN_FLAGS].sort().join(", ")}`);
|
|
127
|
+
}
|
|
128
|
+
throw new Error(`Unexpected positional argument: ${a}. \`mla init\` takes no positional arguments.`);
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
// Assemble the cli-config that `mla init` writes, inheriting unset fields from a
|
|
133
|
+
// prior config (idempotent re-run / token rotation). Pure (no I/O beyond
|
|
134
|
+
// resolveMlaPath reading argv) so the folder = workspace contract is unit-pinned
|
|
135
|
+
// in init-config-shape.spec.ts.
|
|
136
|
+
//
|
|
137
|
+
// Folder = workspace (T3.1): the assembled config carries NO `workspaceId`. The
|
|
138
|
+
// field is omitted from the literal entirely, so even a stale workspaceId on a
|
|
139
|
+
// pre-cutover `prior` is dropped rather than carried forward. The workspace
|
|
140
|
+
// binding lives only in the per-folder `.meetless.json` marker.
|
|
141
|
+
function buildInitConfig(flags, prior) {
|
|
142
|
+
// `mla init` is the SHARED-KEY bootstrap (scripted / CI / `--control-token`),
|
|
143
|
+
// never the browser-login path. So it only ever assembles a shared-key or a
|
|
144
|
+
// 'none' auth. The one exception is idempotence: a re-run while a browser
|
|
145
|
+
// session is live (prior.auth.mode === 'user-token') must PRESERVE that login
|
|
146
|
+
// rather than silently downgrade it to a shared key (which would also freeze a
|
|
147
|
+
// short-lived access token as if it were permanent). `mla login`/`mla logout`
|
|
148
|
+
// own the user-token lifecycle (§6.6).
|
|
149
|
+
let auth;
|
|
150
|
+
if (flags.controlToken) {
|
|
151
|
+
auth = { mode: "shared-key", accessToken: flags.controlToken };
|
|
152
|
+
}
|
|
153
|
+
else if (prior?.auth) {
|
|
154
|
+
// Preserve whatever was canonically on disk (none / shared-key / user-token).
|
|
155
|
+
auth = prior.auth;
|
|
156
|
+
}
|
|
157
|
+
else if (prior?.controlToken) {
|
|
158
|
+
// Legacy prior (pre-nested-auth) with only a top-level token: shared-key.
|
|
159
|
+
auth = { mode: "shared-key", accessToken: prior.controlToken };
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Fresh init with no token: logged out until `mla login` or a later
|
|
163
|
+
// `mla init --control-token`.
|
|
164
|
+
auth = { mode: "none" };
|
|
165
|
+
}
|
|
166
|
+
// P3: under a preserved user session the actor is pinned to the authenticated
|
|
167
|
+
// user; otherwise it is the explicit flag or the inherited value.
|
|
168
|
+
const actorUserId = auth.mode === "user-token"
|
|
169
|
+
? auth.user.id
|
|
170
|
+
: (flags.actorUserId ?? prior?.actorUserId);
|
|
171
|
+
return {
|
|
172
|
+
controlUrl: flags.controlUrl ?? prior?.controlUrl ?? config_1.DEFAULT_CONTROL_URL,
|
|
173
|
+
// Derived projection of auth (= accessToken, "" for none). Never persisted.
|
|
174
|
+
controlToken: auth.mode === "none" ? "" : auth.accessToken,
|
|
175
|
+
intelUrl: flags.intelUrl ?? prior?.intelUrl ?? config_1.DEFAULT_INTEL_URL,
|
|
176
|
+
mlaPath: (0, wire_1.resolveMlaPath)(),
|
|
177
|
+
intelRoot: prior?.intelRoot,
|
|
178
|
+
consoleUrl: prior?.consoleUrl,
|
|
179
|
+
actorUserId,
|
|
180
|
+
auth,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Human-readable one-liner for the auth state a fresh/updated init just wrote,
|
|
184
|
+
// shown in the init summary. `none` is the DEFAULT (no --control-token): the
|
|
185
|
+
// machine is wired but logged out, so `mla login` is the next step. shared-key
|
|
186
|
+
// is the opt-in headless path; user-token only appears on an idempotent re-run
|
|
187
|
+
// over a live browser session (init preserves it, never downgrades).
|
|
188
|
+
function describeInitAuthMode(mode) {
|
|
189
|
+
if (mode === "user-token")
|
|
190
|
+
return "user-token (browser login preserved)";
|
|
191
|
+
if (mode === "shared-key")
|
|
192
|
+
return "shared-key (headless)";
|
|
193
|
+
return "none (logged out; run `mla login` to sign in)";
|
|
194
|
+
}
|
|
195
|
+
async function runInit(argv) {
|
|
196
|
+
let flags;
|
|
197
|
+
try {
|
|
198
|
+
flags = parseInitArgs(argv);
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
console.error(e.message);
|
|
202
|
+
return 2;
|
|
203
|
+
}
|
|
204
|
+
if (flags.unsafeCaptureNonBash) {
|
|
205
|
+
console.error("--unsafe-capture-non-bash is v0.1; rejected in v0.");
|
|
206
|
+
return 2;
|
|
207
|
+
}
|
|
208
|
+
if (flags.skillOnly) {
|
|
209
|
+
const res = (0, wire_1.runWire)({ skillOnly: true });
|
|
210
|
+
(0, wire_1.printWireResult)(res, { skillOnly: true });
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
// Idempotent re-run: when cli-config.json exists, inherit each field
|
|
214
|
+
// the operator did not explicitly override. This lets `mla init` double
|
|
215
|
+
// as "rotate token" (`mla init --control-token NEW`) or "change backend"
|
|
216
|
+
// (`mla init --control-url ...`) without forcing the operator to retype
|
|
217
|
+
// every previously-set value. On a first run with nothing to inherit, the
|
|
218
|
+
// auth defaults to 'none' (see below) rather than demanding a token.
|
|
219
|
+
let prior = null;
|
|
220
|
+
if ((0, config_1.configExists)()) {
|
|
221
|
+
try {
|
|
222
|
+
prior = (0, config_1.readConfig)();
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
prior = null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// §6.4: `mla init` DEFAULTS to auth.mode 'none' (machine wired, logged out)
|
|
229
|
+
// when no --control-token is given. The shared-key bootstrap is now opt-in via
|
|
230
|
+
// --control-token (headless / CI); the interactive path is `mla init` then
|
|
231
|
+
// `mla login`. buildInitConfig already assembles the 'none' auth, and a
|
|
232
|
+
// tokenless re-run over a live user-token PRESERVES it (no downgrade), so there
|
|
233
|
+
// is no token guard here: a tokenless first run is a supported, audited-by-login
|
|
234
|
+
// setup, not an error.
|
|
235
|
+
const cfg = buildInitConfig(flags, prior);
|
|
236
|
+
fs.mkdirSync(config_1.QUEUE_DIR, { recursive: true });
|
|
237
|
+
(0, config_1.writeConfig)(cfg);
|
|
238
|
+
const wire = (0, wire_1.runWire)({
|
|
239
|
+
noPostToolUse: !!flags.noPostToolUse,
|
|
240
|
+
noInstallFlock: !!flags.noInstallFlock,
|
|
241
|
+
noProjectRules: !!flags.noProjectRules,
|
|
242
|
+
noMcp: !!flags.noMcp,
|
|
243
|
+
});
|
|
244
|
+
const authMode = cfg.auth.mode;
|
|
245
|
+
console.log(`Wrote ${config_1.CFG_PATH}${prior ? " (updated)" : ""}`);
|
|
246
|
+
console.log(` controlUrl: ${cfg.controlUrl}`);
|
|
247
|
+
console.log(` intelUrl: ${cfg.intelUrl}`);
|
|
248
|
+
console.log(` mlaPath: ${cfg.mlaPath}`);
|
|
249
|
+
console.log(` auth: ${describeInitAuthMode(authMode)}`);
|
|
250
|
+
if (cfg.actorUserId) {
|
|
251
|
+
console.log(` actorUserId: ${cfg.actorUserId}`);
|
|
252
|
+
}
|
|
253
|
+
else if (authMode !== "none") {
|
|
254
|
+
// Under 'none' the actor is stamped by `mla login` (pinned to auth.user.id),
|
|
255
|
+
// so only the headless shared-key path needs the explicit --actor nag.
|
|
256
|
+
console.log(" actorUserId: (unset; required for `mla kb` curation commands. " +
|
|
257
|
+
"Re-run `mla init --actor <id>` to set it.)");
|
|
258
|
+
}
|
|
259
|
+
(0, wire_1.printWireResult)(wire);
|
|
260
|
+
// 4.4 first-run telemetry disclosure. Stated once, at setup, rather than on
|
|
261
|
+
// every invocation (a per-run notice would pollute scriptable output). Crash
|
|
262
|
+
// reporting is OFF unless a Sentry DSN is configured; run traces, when a
|
|
263
|
+
// backend enables them, go ONLY to the control URL above (your own server),
|
|
264
|
+
// never to Meetless. Hard-disable everything with MEETLESS_TELEMETRY=off.
|
|
265
|
+
console.log("Telemetry: crash reporting OFF (no Sentry DSN); run traces go only to " +
|
|
266
|
+
"your configured control, never to Meetless. Disable all with " +
|
|
267
|
+
"MEETLESS_TELEMETRY=off. See TELEMETRY.md.");
|
|
268
|
+
// A logged-out machine's next step is the browser login; a headless shared-key
|
|
269
|
+
// install goes straight to doctor.
|
|
270
|
+
console.log(`Next: ${authMode === "none" ? "mla login" : "mla doctor"}`);
|
|
271
|
+
return wire.flock?.ok ? 0 : 1;
|
|
272
|
+
}
|