@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,120 @@
|
|
|
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.runInternalSessionNudge = runInternalSessionNudge;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const child_process_1 = require("child_process");
|
|
39
|
+
const config_1 = require("../lib/config");
|
|
40
|
+
const workspace_1 = require("../lib/workspace");
|
|
41
|
+
function defaultIsGitRepo(dir) {
|
|
42
|
+
const r = (0, child_process_1.spawnSync)("git", ["-C", dir, "rev-parse", "--is-inside-work-tree"], { encoding: "utf8" });
|
|
43
|
+
return r.status === 0 && r.stdout.trim() === "true";
|
|
44
|
+
}
|
|
45
|
+
function parseCwd(argv, fallback) {
|
|
46
|
+
const i = argv.indexOf("--cwd");
|
|
47
|
+
if (i >= 0 && argv[i + 1])
|
|
48
|
+
return path.resolve(argv[i + 1]);
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
// Claude Code reads a SessionStart hook's stdout and, when it is this shape,
|
|
52
|
+
// injects `additionalContext` into the session.
|
|
53
|
+
function additionalContext(message) {
|
|
54
|
+
return JSON.stringify({
|
|
55
|
+
hookSpecificOutput: {
|
|
56
|
+
hookEventName: "SessionStart",
|
|
57
|
+
additionalContext: message,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const NOT_ACTIVATED_MSG = "Meetless is installed but inactive in this repository. No Meetless context is being injected. " +
|
|
62
|
+
"Run `mla activate` to enable it, or `mla doctor` for details.";
|
|
63
|
+
const INVALID_MARKER_MSG = "Meetless activation is incomplete in this repository. No Meetless context is being injected. " +
|
|
64
|
+
"Run `mla doctor`, then rerun `mla activate` to repair it.";
|
|
65
|
+
const LOGGED_OUT_MSG = "Meetless is activated in this repository but you are signed out, so no Meetless context is being injected. " +
|
|
66
|
+
"Run `mla login` to resume, or `mla doctor` for details.";
|
|
67
|
+
function runInternalSessionNudge(argv, deps = {}) {
|
|
68
|
+
const readCfg = deps.readConfig ?? config_1.readConfig;
|
|
69
|
+
const resolveWs = deps.resolveWorkspaceContext ?? workspace_1.resolveWorkspaceContext;
|
|
70
|
+
const isGitRepo = deps.isGitRepo ?? defaultIsGitRepo;
|
|
71
|
+
const log = deps.log ?? ((m) => process.stdout.write(m + "\n"));
|
|
72
|
+
const env = deps.env ?? process.env;
|
|
73
|
+
const cwd = parseCwd(argv, env.MEETLESS_PROJECT_DIR ?? env.CLAUDE_PROJECT_DIR ?? process.cwd());
|
|
74
|
+
// Read auth, but do NOT use it to short-circuit: an activated repo that the user
|
|
75
|
+
// has since logged out of still deserves a visible login nudge. Auth only gates
|
|
76
|
+
// the no-marker case below. Any config-read failure -> silent (never break a hook).
|
|
77
|
+
let loggedIn = false;
|
|
78
|
+
try {
|
|
79
|
+
loggedIn = readCfg().auth.mode !== "none";
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
// Git repositories only: suppress scratch dirs and $HOME, regardless of auth.
|
|
85
|
+
if (!isGitRepo(cwd))
|
|
86
|
+
return 0;
|
|
87
|
+
// Resolve the marker FIRST, then branch on (marker-state x auth). Reusing the
|
|
88
|
+
// MCP's resolver keeps "activated?" meaning EXACTLY the same thing in both
|
|
89
|
+
// surfaces. The key distinction this enables: "logged out in a repo the user
|
|
90
|
+
// activated" (nudge login) vs "logged out in an unrelated repo" (stay silent).
|
|
91
|
+
try {
|
|
92
|
+
resolveWs(cwd);
|
|
93
|
+
// Valid marker: this repo is activated. Logged in -> the active hook path
|
|
94
|
+
// injects context, so we stay silent. Logged out -> governance is dark in a
|
|
95
|
+
// repo the user chose, so surface the login path.
|
|
96
|
+
if (!loggedIn) {
|
|
97
|
+
log(additionalContext(LOGGED_OUT_MSG));
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e instanceof workspace_1.NotActivatedError) {
|
|
103
|
+
// No marker: only nudge a logged-in user. A logged-out user in an unrelated
|
|
104
|
+
// repo has never expressed intent here; silence is correct.
|
|
105
|
+
if (loggedIn) {
|
|
106
|
+
log(additionalContext(NOT_ACTIVATED_MSG));
|
|
107
|
+
}
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
if (e instanceof workspace_1.MarkerMissingWorkspaceIdError) {
|
|
111
|
+
// A present-but-broken marker is durable evidence of intent to use Meetless
|
|
112
|
+
// here, so surface the repair path regardless of auth.
|
|
113
|
+
log(additionalContext(INVALID_MARKER_MSG));
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
// Unanticipated resolver failure: stay silent rather than emit a confusing
|
|
117
|
+
// message into a fresh session.
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseArgs = parseArgs;
|
|
4
|
+
exports.runInternalSteerSync = runInternalSteerSync;
|
|
5
|
+
const config_1 = require("../lib/config");
|
|
6
|
+
const http_1 = require("../lib/http");
|
|
7
|
+
const active_conflict_cache_1 = require("../lib/active-conflict-cache");
|
|
8
|
+
const steer_cache_1 = require("../lib/steer-cache");
|
|
9
|
+
function realTransport(cfg) {
|
|
10
|
+
return {
|
|
11
|
+
pull: async (sessionId) => {
|
|
12
|
+
const res = await (0, http_1.post)(cfg, `/internal/v1/session-steers/by-session/${encodeURIComponent(sessionId)}/pull`, { workspaceId: cfg.workspaceId }, 8000);
|
|
13
|
+
return res.steers ?? [];
|
|
14
|
+
},
|
|
15
|
+
markInjected: async (id) => {
|
|
16
|
+
await (0, http_1.post)(cfg, `/internal/v1/session-steers/${encodeURIComponent(id)}/injected`, { workspaceId: cfg.workspaceId }, 8000);
|
|
17
|
+
},
|
|
18
|
+
fetchActiveConflicts: async (sessionId) => {
|
|
19
|
+
const res = await (0, http_1.get)(cfg, `/internal/v1/session-conflicts/by-session/${encodeURIComponent(sessionId)}/active` +
|
|
20
|
+
`?workspaceId=${encodeURIComponent(cfg.workspaceId)}`, 8000);
|
|
21
|
+
return res.conflicts ?? [];
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function stubTransport(stubJson) {
|
|
26
|
+
return {
|
|
27
|
+
pull: async () => {
|
|
28
|
+
const parsed = JSON.parse(stubJson);
|
|
29
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
30
|
+
},
|
|
31
|
+
markInjected: async () => {
|
|
32
|
+
/* stub: no network */
|
|
33
|
+
},
|
|
34
|
+
fetchActiveConflicts: async () => {
|
|
35
|
+
const raw = process.env.MEETLESS_CONFLICT_SYNC_STUB;
|
|
36
|
+
if (!raw || raw.length === 0)
|
|
37
|
+
return [];
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function parseArgs(argv) {
|
|
44
|
+
let sessionId = null;
|
|
45
|
+
for (let i = 0; i < argv.length; i++) {
|
|
46
|
+
const a = argv[i];
|
|
47
|
+
if (a === "--session") {
|
|
48
|
+
sessionId = argv[i + 1] ?? null;
|
|
49
|
+
i++;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (a.startsWith("-")) {
|
|
53
|
+
throw new Error(`Unknown flag: ${a}. \`mla _internal steer-sync\` takes only --session <sid>.`);
|
|
54
|
+
}
|
|
55
|
+
throw new Error(`Unexpected positional argument: ${a}. \`mla _internal steer-sync\` takes only --session <sid>.`);
|
|
56
|
+
}
|
|
57
|
+
if (!sessionId) {
|
|
58
|
+
throw new Error("`mla _internal steer-sync` requires --session <sid>.");
|
|
59
|
+
}
|
|
60
|
+
return { sessionId };
|
|
61
|
+
}
|
|
62
|
+
async function runInternalSteerSync(argv) {
|
|
63
|
+
let sessionId;
|
|
64
|
+
try {
|
|
65
|
+
({ sessionId } = parseArgs(argv));
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
console.error(e.message);
|
|
69
|
+
return 2;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const stub = process.env.MEETLESS_STEER_SYNC_STUB_PULL;
|
|
73
|
+
const transport = stub && stub.length > 0 ? stubTransport(stub) : realTransport((0, config_1.loadWorkspaceConfig)());
|
|
74
|
+
// 1) Pull and cache the authoritative deliverable set (overwrite: the server
|
|
75
|
+
// returns the full not-yet-injected set, so the cache is never a stale delta).
|
|
76
|
+
const steers = await transport.pull(sessionId);
|
|
77
|
+
(0, steer_cache_1.writeSteerCache)(sessionId, steers);
|
|
78
|
+
// 2) Mark-injected what the hook already surfaced. The hook dedups injection
|
|
79
|
+
// via its own inject-state, so a one-turn overlap (a just-injected steer
|
|
80
|
+
// still in the freshly written cache) never re-injects; the next pull drops
|
|
81
|
+
// it once it is flipped to INJECTED.
|
|
82
|
+
let injected = 0;
|
|
83
|
+
if (!stub) {
|
|
84
|
+
for (const id of (0, steer_cache_1.readInjectedIds)(sessionId)) {
|
|
85
|
+
try {
|
|
86
|
+
await transport.markInjected(id);
|
|
87
|
+
injected++;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* best-effort: a failed mark-injected retries next flush */
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// 3) Snapshot the session's open cross-session conflicts for the PreToolUse soft
|
|
95
|
+
// warning. Isolated from the steer pull: a conflict-fetch failure must not
|
|
96
|
+
// zero the pull or the flush. On a SUCCESSFUL fetch (even an empty set) we
|
|
97
|
+
// overwrite the snapshot so a resolved conflict clears the warning at once;
|
|
98
|
+
// on a FAILURE we leave the prior snapshot in place and let the hook's TTL
|
|
99
|
+
// staleness guard fail it open. -1 means "fetch did not complete this turn".
|
|
100
|
+
let conflicts = -1;
|
|
101
|
+
try {
|
|
102
|
+
const active = await transport.fetchActiveConflicts(sessionId);
|
|
103
|
+
(0, active_conflict_cache_1.writeActiveConflictCache)(sessionId, active);
|
|
104
|
+
conflicts = active.length;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* best-effort: leave the prior snapshot; TTL fails it open if the sync stays down */
|
|
108
|
+
}
|
|
109
|
+
console.log(JSON.stringify({ pulled: steers.length, injected, conflicts }));
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Best-effort: never break the flush this hop rides on.
|
|
114
|
+
console.log(JSON.stringify({ pulled: 0, injected: 0, conflicts: -1 }));
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// `mla _internal turn-recap` -- the machine-facing per-turn assist recap reader
|
|
3
|
+
// (Layer B of notes/20260609-mla-per-turn-assist-recap-plan.md). Two callers shell
|
|
4
|
+
// out to it:
|
|
5
|
+
// - user-prompt-submit.sh (Layer C-lite): `--style block-context` for the prior
|
|
6
|
+
// turn, injected into the next prompt's context. Best-effort; a slow or empty
|
|
7
|
+
// recap must produce nothing, never an error.
|
|
8
|
+
// - stop.sh (Layer D): `--emit-langfuse` detached at turn-end, to attach the
|
|
9
|
+
// mla_ran / mla_assist scores to the turn's Langfuse trace.
|
|
10
|
+
//
|
|
11
|
+
// It computes the recap (Layer A computeTurnRecap) for one (session, turn) and
|
|
12
|
+
// prints one of three render styles or the raw JSON. Like the other `_internal`
|
|
13
|
+
// subcommands it skips analytics capture and is fail-soft: a strict argv parse
|
|
14
|
+
// error exits 2; any other failure prints nothing and exits 0 so it can never
|
|
15
|
+
// disturb the hook that spawned it.
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.parseTurnRecapArgs = parseTurnRecapArgs;
|
|
18
|
+
exports.renderStyle = renderStyle;
|
|
19
|
+
exports.runInternalTurnRecap = runInternalTurnRecap;
|
|
20
|
+
const config_1 = require("../lib/config");
|
|
21
|
+
const turn_recap_emit_1 = require("../lib/turn-recap-emit");
|
|
22
|
+
const turn_recap_1 = require("../lib/analytics/turn-recap");
|
|
23
|
+
const STYLES = ["footer", "block", "block-context"];
|
|
24
|
+
function parseTurnRecapArgs(argv) {
|
|
25
|
+
const out = {
|
|
26
|
+
session: null,
|
|
27
|
+
turn: null,
|
|
28
|
+
style: "footer",
|
|
29
|
+
json: false,
|
|
30
|
+
emitLangfuse: false,
|
|
31
|
+
};
|
|
32
|
+
for (let i = 0; i < argv.length; i++) {
|
|
33
|
+
const a = argv[i];
|
|
34
|
+
switch (a) {
|
|
35
|
+
case "--session":
|
|
36
|
+
out.session = argv[++i] ?? "";
|
|
37
|
+
if (!out.session)
|
|
38
|
+
throw new Error("--session requires a value");
|
|
39
|
+
break;
|
|
40
|
+
case "--turn": {
|
|
41
|
+
const v = argv[++i];
|
|
42
|
+
if (!v || !/^[0-9]+$/.test(v) || Number(v) < 1) {
|
|
43
|
+
throw new Error(`--turn requires a positive integer: ${v ?? "(missing)"}`);
|
|
44
|
+
}
|
|
45
|
+
out.turn = Number(v);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case "--style": {
|
|
49
|
+
const v = argv[++i];
|
|
50
|
+
if (!STYLES.includes(v))
|
|
51
|
+
throw new Error(`--style must be one of ${STYLES.join("|")}: ${v ?? "(missing)"}`);
|
|
52
|
+
out.style = v;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case "--json":
|
|
56
|
+
out.json = true;
|
|
57
|
+
break;
|
|
58
|
+
case "--emit-langfuse":
|
|
59
|
+
out.emitLangfuse = true;
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Unknown flag for \`mla _internal turn-recap\`: ${a}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
function renderStyle(recap, style) {
|
|
68
|
+
switch (style) {
|
|
69
|
+
case "block":
|
|
70
|
+
return (0, turn_recap_1.renderBlock)(recap);
|
|
71
|
+
case "block-context":
|
|
72
|
+
return (0, turn_recap_1.renderBlockContext)(recap);
|
|
73
|
+
default:
|
|
74
|
+
return (0, turn_recap_1.renderFooter)(recap);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// A recap with no usable content to inject: the turn left no trace and we cannot
|
|
78
|
+
// even name why (a true "nothing happened" gap, distinct from a known muted /
|
|
79
|
+
// suppressed / NO_OFFER turn, all of which carry signal worth surfacing).
|
|
80
|
+
function isEmptyRecap(r) {
|
|
81
|
+
return !r.ran && r.not_run_reason === null;
|
|
82
|
+
}
|
|
83
|
+
async function runInternalTurnRecap(argv, deps = {}) {
|
|
84
|
+
let args;
|
|
85
|
+
try {
|
|
86
|
+
args = parseTurnRecapArgs(argv);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
console.error(e.message);
|
|
90
|
+
return 2;
|
|
91
|
+
}
|
|
92
|
+
const env = deps.env ?? process.env;
|
|
93
|
+
const log = deps.log ?? ((line) => console.log(line));
|
|
94
|
+
try {
|
|
95
|
+
const session = args.session ?? env.CLAUDE_CODE_SESSION_ID ?? "";
|
|
96
|
+
if (!session || args.turn === null) {
|
|
97
|
+
// Nothing to compute against. Silent, fail-soft (the hook ignores this).
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
const compute = deps.compute ?? ((s, t) => (0, turn_recap_1.computeTurnRecap)(s, t));
|
|
101
|
+
const recap = compute(session, args.turn);
|
|
102
|
+
if (args.json) {
|
|
103
|
+
log(JSON.stringify(recap));
|
|
104
|
+
}
|
|
105
|
+
else if (args.style === "block-context" && isEmptyRecap(recap)) {
|
|
106
|
+
// C-lite: inject nothing when there is genuinely nothing to say.
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
log(renderStyle(recap, args.style));
|
|
110
|
+
}
|
|
111
|
+
// Layer D emission: detached, best-effort, never blocks the agent.
|
|
112
|
+
// No-op when no trace id (nothing to attach a score to).
|
|
113
|
+
if (args.emitLangfuse && recap.trace_id) {
|
|
114
|
+
const readCfg = deps.readCfg ??
|
|
115
|
+
(() => {
|
|
116
|
+
try {
|
|
117
|
+
return (0, config_1.readConfig)();
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const postTurnRecap = deps.postTurnRecap ?? turn_recap_emit_1.postTurnRecapToIntel;
|
|
124
|
+
const cfg = readCfg();
|
|
125
|
+
if (cfg) {
|
|
126
|
+
try {
|
|
127
|
+
await postTurnRecap(cfg, recap);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Langfuse/intel outage must degrade to "no score this turn", nothing more.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Fail-soft: never throw into the hook that spawned us.
|
|
138
|
+
return 0;
|
|
139
|
+
}
|
|
140
|
+
}
|