@jentrix/cli 0.5.22 → 0.5.23
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/dist/main.js +80 -24
- package/package.json +1 -1
- package/surface.json +2 -2
package/dist/main.js
CHANGED
|
@@ -20966,7 +20966,7 @@ function refreshAccessToken(input) {
|
|
|
20966
20966
|
|
|
20967
20967
|
// src/client.ts
|
|
20968
20968
|
var CLI_NAME = "stacks-cli";
|
|
20969
|
-
var CLI_VERSION = "0.5.
|
|
20969
|
+
var CLI_VERSION = "0.5.23";
|
|
20970
20970
|
var DEAD_TOKEN_MESSAGE = "authentication failed (HTTP 401): the token is dead or expired \u2014 mint a new PAT at /account/tokens on your Jentrix server and update STACKS_TOKEN (or --token / the config file).";
|
|
20971
20971
|
var RELOGIN_MESSAGE = "OAuth session expired and could not be refreshed \u2014 run `jentrix login` to sign in again.";
|
|
20972
20972
|
function originOf2(url2) {
|
|
@@ -21386,10 +21386,10 @@ function buildAlignDisclosures(catalog) {
|
|
|
21386
21386
|
catalog.liveHostPid !== null ? `keep the live session host (pid ${catalog.liveHostPid}) running` : "start a detached session host (heartbeats + provider usage receipts)"
|
|
21387
21387
|
);
|
|
21388
21388
|
disclosures.push(
|
|
21389
|
-
catalog.captureMode === "on" ? "TRACE capture: ON \u2014 the full transcript will be recorded" : "TRACE capture: OFF
|
|
21389
|
+
catalog.captureMode === "on" ? "TRACE capture: ON \u2014 the full transcript will be recorded" : catalog.captureMode === "off" ? "TRACE capture: OFF \u2014 typed artifacts only, no transcript" : "TRACE capture: your account default (Account \u2192 Capture; the built-in is OFF \u2014 typed artifacts only). The confirmed value is printed after the align; --capture/--no-capture decides it here instead"
|
|
21390
21390
|
);
|
|
21391
21391
|
disclosures.push(
|
|
21392
|
-
catalog.skeletonMode === "on" ? "activity skeleton: ON
|
|
21392
|
+
catalog.skeletonMode === "on" ? "activity skeleton: ON \u2014 content-free counts/timing (turns, tool names, files-touched), independent of capture; --no-skeleton opts out" : catalog.skeletonMode === "off" ? "activity skeleton: OFF \u2014 no counts, no timing, no files-touched; the session's Session activity section will read as not observed" : "activity skeleton: your account default (Account \u2192 Capture; the built-in is ON \u2014 content-free counts/timing). The confirmed value is printed after the align; --skeleton/--no-skeleton decides it here instead"
|
|
21393
21393
|
);
|
|
21394
21394
|
disclosures.push("write the local alignment marker for this checkout");
|
|
21395
21395
|
const mcp = catalog.mcpConfig;
|
|
@@ -22007,6 +22007,10 @@ function upsertAlignmentMarker(file, providerSessionId, marker) {
|
|
|
22007
22007
|
sessions[providerSessionId] = marker;
|
|
22008
22008
|
return { version: 2, sessions, latest: providerSessionId };
|
|
22009
22009
|
}
|
|
22010
|
+
function findAlignmentMarkerForSession(file, sessionId) {
|
|
22011
|
+
if (!file) return null;
|
|
22012
|
+
return Object.values(file.sessions).find((m) => m.sessionId === sessionId) ?? null;
|
|
22013
|
+
}
|
|
22010
22014
|
function removeAlignmentMarkerEntry(file, sessionId) {
|
|
22011
22015
|
if (!file) return null;
|
|
22012
22016
|
const sessions = Object.fromEntries(
|
|
@@ -23035,6 +23039,13 @@ async function runSessionStatus(sessionId, flags, deps2) {
|
|
|
23035
23039
|
const deadLocal = open && boundHere && !hasLocalCaptureFootprint(deps2, sessionId);
|
|
23036
23040
|
const captureOff = session.alignment?.capture === "off";
|
|
23037
23041
|
const capture = captureOff ? "off (MVP alignment \u2014 typed artifacts only)" : session.captureComplete ? "complete" : deadLocal ? "bound server-side; local capture NOT RUNNING" : open ? "recording (finalizes when the session ends)" : `INCOMPLETE${session.captureError ? ` \u2014 ${String(session.captureError)}` : ""}`;
|
|
23042
|
+
const inspection = await inspectRepository(deps2.cwd(), deps2.git);
|
|
23043
|
+
const alignMarker = inspection ? findAlignmentMarkerForSession(
|
|
23044
|
+
readAlignmentMarkerFile(deps2.configPath, inspection.root),
|
|
23045
|
+
sessionId
|
|
23046
|
+
) : null;
|
|
23047
|
+
const captureProvenance = alignMarker?.captureSource ? ` \xB7 resolved from ${alignMarker.captureSource}` : "";
|
|
23048
|
+
const skeletonProvenance = alignMarker?.skeletonSource ? ` \xB7 resolved from ${alignMarker.skeletonSource}` : "";
|
|
23038
23049
|
const local = deadLocal ? [
|
|
23039
23050
|
"Local capture: NOT RUNNING \u2014 this machine bound the session but no capture host ever started here (no host marker, no spool parts).",
|
|
23040
23051
|
` Fix: \`jentrix session end ${sessionId}\` closes it honestly (the capture gap is recorded), or reattach with a transcript path to start capture.`
|
|
@@ -23050,9 +23061,9 @@ async function runSessionStatus(sessionId, flags, deps2) {
|
|
|
23050
23061
|
`Session ${String(session.id)} \xB7 ${String(session.provider)} \xB7 ${String(session.status)}`,
|
|
23051
23062
|
`Project: ${String(session.projectName)} (${String(session.projectId)})`,
|
|
23052
23063
|
`Repository: ${String(session.repoOwnerName)}`,
|
|
23053
|
-
`Capture: ${capture}`,
|
|
23064
|
+
`Capture: ${capture}${captureProvenance}`,
|
|
23054
23065
|
// Evidence floor (D3): the skeleton mode the alignment declared.
|
|
23055
|
-
`Skeleton: ${session.alignment?.skeleton === "off" ? "off (
|
|
23066
|
+
`Skeleton: ${session.alignment?.skeleton === "off" ? "off (no activity counts, no timing, no files-touched)" : "on (content-free activity counts/timing)"}${skeletonProvenance}`,
|
|
23056
23067
|
...local,
|
|
23057
23068
|
telemetry.line,
|
|
23058
23069
|
`Summary artifact: ${session.summaryArtifactId ? String(session.summaryArtifactId) : "\u2014"}`
|
|
@@ -24221,10 +24232,11 @@ async function buildCatalog(caller, flags, detection) {
|
|
|
24221
24232
|
// Host/capture disclosure inputs are filled by runAlign (they need the
|
|
24222
24233
|
// checkout root); defaults here are the no-live-host reading.
|
|
24223
24234
|
liveHostPid: null,
|
|
24224
|
-
captureMode:
|
|
24225
|
-
// JEN-169
|
|
24226
|
-
//
|
|
24227
|
-
|
|
24235
|
+
captureMode: captureSubmission(flags.capture, false, false) ?? "default",
|
|
24236
|
+
// JEN-169 + capture settings §5: the disclosure states the same tri-state
|
|
24237
|
+
// the submission carries, so "your account default" is never quietly
|
|
24238
|
+
// disclosed as a posture the wizard guessed.
|
|
24239
|
+
skeletonMode: skeletonSubmission(flags.skeleton) ?? "default",
|
|
24228
24240
|
producer: producerFromFlags(flags),
|
|
24229
24241
|
tokenBudget: budgetFromFlags(flags),
|
|
24230
24242
|
preconditionNotices: [],
|
|
@@ -24338,6 +24350,18 @@ function decideCaptureMode(requested, liveCapturing) {
|
|
|
24338
24350
|
if (requested === false) return "off";
|
|
24339
24351
|
return liveCapturing ? "on" : "off";
|
|
24340
24352
|
}
|
|
24353
|
+
function captureSubmission(requested, liveHost, liveCapturing) {
|
|
24354
|
+
if (requested === void 0 && !liveHost) return void 0;
|
|
24355
|
+
return decideCaptureMode(requested, liveCapturing);
|
|
24356
|
+
}
|
|
24357
|
+
function skeletonSubmission(requested) {
|
|
24358
|
+
if (requested === void 0) return void 0;
|
|
24359
|
+
return requested ? "on" : "off";
|
|
24360
|
+
}
|
|
24361
|
+
function captureSourceLabel(requested, liveHost, serverLabel) {
|
|
24362
|
+
if (requested === void 0 && liveHost) return "(live host)";
|
|
24363
|
+
return serverLabel;
|
|
24364
|
+
}
|
|
24341
24365
|
function keepCurrentAlignment(currentAlignment, projectId, workItem, ownerUserId) {
|
|
24342
24366
|
if (workItem !== null || !projectId) return null;
|
|
24343
24367
|
const current = currentAlignment;
|
|
@@ -24402,7 +24426,9 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24402
24426
|
sessionId,
|
|
24403
24427
|
alignment: session.alignment,
|
|
24404
24428
|
realigned: false,
|
|
24405
|
-
captureMode: (session.alignment.capture ?? "off") === "on" ? "on" : "off"
|
|
24429
|
+
captureMode: (session.alignment.capture ?? "off") === "on" ? "on" : "off",
|
|
24430
|
+
// No align ran, so nothing resolved anything — claim no provenance.
|
|
24431
|
+
captureSources: null
|
|
24406
24432
|
};
|
|
24407
24433
|
}
|
|
24408
24434
|
}
|
|
@@ -24453,7 +24479,12 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24453
24479
|
`cannot turn TRACE capture off: the live session host (pid ${liveHost.pid}) is actively capturing \u2014 end the session (\`jentrix session end\`) to stop it`
|
|
24454
24480
|
);
|
|
24455
24481
|
}
|
|
24456
|
-
const
|
|
24482
|
+
const captureSubmitted = captureSubmission(
|
|
24483
|
+
flags.capture,
|
|
24484
|
+
liveHost !== null,
|
|
24485
|
+
liveCapturing
|
|
24486
|
+
);
|
|
24487
|
+
const skeletonSubmitted = skeletonSubmission(flags.skeleton);
|
|
24457
24488
|
if (liveHost && session.taskId && session.taskId !== (taskId ?? null)) {
|
|
24458
24489
|
const acked = await requestUsageFlush(deps2, sessionId);
|
|
24459
24490
|
deps2.writeOut(
|
|
@@ -24471,14 +24502,22 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24471
24502
|
...producer.emoji ? { agentEmoji: producer.emoji } : {}
|
|
24472
24503
|
} : {},
|
|
24473
24504
|
...budget !== null ? { tokenBudget: budget } : {},
|
|
24474
|
-
capture:
|
|
24475
|
-
|
|
24476
|
-
// lets the server keep the stored mode (default "on").
|
|
24477
|
-
...flags.skeleton === false ? { skeleton: "off" } : {},
|
|
24505
|
+
...captureSubmitted !== void 0 ? { capture: captureSubmitted } : {},
|
|
24506
|
+
...skeletonSubmitted !== void 0 ? { skeleton: skeletonSubmitted } : {},
|
|
24478
24507
|
expectedUpdatedAt: session.updatedAt
|
|
24479
24508
|
});
|
|
24480
24509
|
const alignment = aligned.alignment;
|
|
24481
24510
|
const skeletonMode = alignment.skeleton === "off" ? "off" : "on";
|
|
24511
|
+
const captureMode = alignment.capture === "on" ? "on" : "off";
|
|
24512
|
+
const serverSources = aligned.captureSources ?? null;
|
|
24513
|
+
const captureSources = serverSources ? {
|
|
24514
|
+
capture: captureSourceLabel(
|
|
24515
|
+
flags.capture,
|
|
24516
|
+
liveHost !== null,
|
|
24517
|
+
serverSources.capture
|
|
24518
|
+
),
|
|
24519
|
+
skeleton: serverSources.skeleton
|
|
24520
|
+
} : null;
|
|
24482
24521
|
writeAlignmentMarker(
|
|
24483
24522
|
deps2.configPath,
|
|
24484
24523
|
inspection.root,
|
|
@@ -24488,6 +24527,12 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24488
24527
|
projectId: choices.projectId,
|
|
24489
24528
|
taskId,
|
|
24490
24529
|
capture: captureMode,
|
|
24530
|
+
// Capture settings D6/S4: `session status` reads the provenance back
|
|
24531
|
+
// from here — the snapshot deliberately stores values only, so the
|
|
24532
|
+
// align that resolved them is the only place the source exists.
|
|
24533
|
+
...captureSources?.capture ? { captureSource: captureSources.capture } : {},
|
|
24534
|
+
...captureSources?.skeleton ? { skeletonSource: captureSources.skeleton } : {},
|
|
24535
|
+
skeleton: skeletonMode,
|
|
24491
24536
|
alignedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
24492
24537
|
},
|
|
24493
24538
|
detected.providerSessionId
|
|
@@ -24514,7 +24559,8 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24514
24559
|
sessionId,
|
|
24515
24560
|
alignment,
|
|
24516
24561
|
realigned: Boolean(aligned.realigned),
|
|
24517
|
-
captureMode
|
|
24562
|
+
captureMode,
|
|
24563
|
+
captureSources
|
|
24518
24564
|
};
|
|
24519
24565
|
}
|
|
24520
24566
|
if (!liveHost && (detected.provider === "claude" && detected.transcriptPath || detected.provider === "codex" && detected.hookDir)) {
|
|
@@ -24558,7 +24604,8 @@ ${JSON.stringify(session.alignment, null, 2)}`
|
|
|
24558
24604
|
sessionId,
|
|
24559
24605
|
alignment,
|
|
24560
24606
|
realigned: Boolean(aligned.realigned),
|
|
24561
|
-
captureMode
|
|
24607
|
+
captureMode,
|
|
24608
|
+
captureSources
|
|
24562
24609
|
};
|
|
24563
24610
|
}
|
|
24564
24611
|
async function requestUsageFlush(deps2, sessionId, timeoutMs = 6e3) {
|
|
@@ -24609,10 +24656,11 @@ async function runAlign(flags, deps2) {
|
|
|
24609
24656
|
);
|
|
24610
24657
|
const markerHost = marker ? readLiveHostMarker(deps2, marker.sessionId) : null;
|
|
24611
24658
|
catalog.liveHostPid = markerHost?.pid ?? null;
|
|
24612
|
-
catalog.captureMode =
|
|
24659
|
+
catalog.captureMode = captureSubmission(
|
|
24613
24660
|
flags.capture,
|
|
24661
|
+
markerHost !== null,
|
|
24614
24662
|
marker !== null && markerHost !== null && isHostCapturing(deps2, marker.sessionId, markerHost)
|
|
24615
|
-
);
|
|
24663
|
+
) ?? "default";
|
|
24616
24664
|
const newest = newestAlignmentMarker(deps2.configPath, inspection.root);
|
|
24617
24665
|
catalog.lastAlignedWorkspaceId = newest?.workspaceId ?? null;
|
|
24618
24666
|
catalog.binding = {
|
|
@@ -25001,6 +25049,7 @@ async function runAlign(flags, deps2) {
|
|
|
25001
25049
|
deps2.writeOut(JSON.stringify(result));
|
|
25002
25050
|
} else {
|
|
25003
25051
|
const a = result.alignment;
|
|
25052
|
+
const sources = result.captureSources;
|
|
25004
25053
|
deps2.writeOut(
|
|
25005
25054
|
[
|
|
25006
25055
|
`${result.realigned ? "Re-aligned" : "Aligned"} session ${result.sessionId}:`,
|
|
@@ -25010,8 +25059,12 @@ async function runAlign(flags, deps2) {
|
|
|
25010
25059
|
` Owner: ${a.owner?.name ?? a.owner?.email ?? "\u2014"}`,
|
|
25011
25060
|
` Agent: ${a.agent?.provider ?? "\u2014"}`,
|
|
25012
25061
|
` Repo: ${a.repo?.ownerName ?? "\u2014"}@${a.repo?.branch ?? "detached"}`,
|
|
25013
|
-
|
|
25014
|
-
|
|
25062
|
+
// Capture settings D6: each resolved knob names WHERE it came
|
|
25063
|
+
// from, in the server's own words — "(flag)", "(this session)",
|
|
25064
|
+
// "(your default)", "(built-in)". A server older than this round
|
|
25065
|
+
// sends none, and then nothing is claimed.
|
|
25066
|
+
` Capture: ${a.capture ?? "off"}${sources?.capture ? ` ${sources.capture}` : ""}`,
|
|
25067
|
+
` Skeleton: ${a.skeleton ?? "on"}${sources?.skeleton ? ` ${sources.skeleton}` : ""} \u2014 content-free activity counts/timing; --skeleton/--no-skeleton decides one session, Account \u2192 Capture sets your default`,
|
|
25015
25068
|
`Alignment snapshot (server-confirmed): ${JSON.stringify(result.alignment)}`
|
|
25016
25069
|
].join("\n")
|
|
25017
25070
|
);
|
|
@@ -25072,13 +25125,16 @@ function registerAlignCommand(program3, deps2, onExit2) {
|
|
|
25072
25125
|
"token budget for this session \u2014 a breach is recorded and badged, never enforced"
|
|
25073
25126
|
).option(
|
|
25074
25127
|
"--capture",
|
|
25075
|
-
"turn TRACE capture ON for this session (
|
|
25128
|
+
"turn TRACE capture ON for this session (overrides your account default; applies from a fresh attach)"
|
|
25076
25129
|
).option(
|
|
25077
25130
|
"--no-capture",
|
|
25078
|
-
"keep TRACE capture OFF explicitly \u2014
|
|
25131
|
+
"keep TRACE capture OFF explicitly \u2014 overrides your account default, and corrects a wrongly-on record on re-align"
|
|
25132
|
+
).option(
|
|
25133
|
+
"--skeleton",
|
|
25134
|
+
"record the content-free activity skeleton for this session explicitly (overrides your account default)"
|
|
25079
25135
|
).option(
|
|
25080
25136
|
"--no-skeleton",
|
|
25081
|
-
"opt out of the content-free activity skeleton (event/tool counts, files-touched, timing buckets) for this session \u2014
|
|
25137
|
+
"opt out of the content-free activity skeleton (event/tool counts, files-touched, timing buckets) for this session \u2014 independent of capture"
|
|
25082
25138
|
).addOption(
|
|
25083
25139
|
new Option(
|
|
25084
25140
|
"--provider <provider>",
|
package/package.json
CHANGED
package/surface.json
CHANGED
|
@@ -441,7 +441,7 @@
|
|
|
441
441
|
"description": "Optional producer label for this session (\"triage-bot\"). Null = the operator themself; absent leaves it unchanged."
|
|
442
442
|
},
|
|
443
443
|
"capture": {
|
|
444
|
-
"description": "TRACE capture mode the
|
|
444
|
+
"description": "TRACE capture mode for this session. OMIT to let the server resolve it: this session's previous value, then the operator's account default (Account → Capture), then the built-in off.",
|
|
445
445
|
"enum": [
|
|
446
446
|
"off",
|
|
447
447
|
"on"
|
|
@@ -464,7 +464,7 @@
|
|
|
464
464
|
"type": "string"
|
|
465
465
|
},
|
|
466
466
|
"skeleton": {
|
|
467
|
-
"description": "Activity-skeleton mode the
|
|
467
|
+
"description": "Activity-skeleton mode for this session, independent of capture. OMIT to let the server resolve it: this session's previous value, then the operator's account default, then the built-in on.",
|
|
468
468
|
"enum": [
|
|
469
469
|
"on",
|
|
470
470
|
"off"
|