@aiwg/cli 2026.9.24 → 2026.10.0
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/agentic/code/providers/capability-matrix.yaml +2 -1
- package/dist/src/artifacts/discovery-shadow-evaluator.js +177 -0
- package/dist/src/artifacts/discovery-shadow.js +195 -0
- package/dist/src/artifacts/index-builder.js +47 -9
- package/dist/src/artifacts/query-engine.js +94 -1
- package/dist/src/artifacts/types.js +1 -0
- package/dist/src/cli/handlers/decision.js +88 -0
- package/dist/src/cli/handlers/gates.js +154 -0
- package/dist/src/cli/handlers/index.js +5 -1
- package/dist/src/cli/handlers/sessions.js +10 -7
- package/dist/src/cli/handlers/utilities.js +20 -0
- package/dist/src/config/aiwg-config.js +15 -2
- package/dist/src/decision/acceptance.js +25 -0
- package/dist/src/decision/adapters/jev.js +24 -2
- package/dist/src/decision/calibration/registry.js +9 -0
- package/dist/src/decision/compose.js +74 -15
- package/dist/src/decision/context-live-promotion.js +344 -0
- package/dist/src/decision/context-live-qualification.js +591 -0
- package/dist/src/decision/context-pruning.js +847 -0
- package/dist/src/decision/driver.js +430 -0
- package/dist/src/decision/egress-live-qualification.js +874 -0
- package/dist/src/decision/ensemble/contract.js +64 -1
- package/dist/src/decision/ensemble/index.js +1 -0
- package/dist/src/decision/ensemble/report.js +8 -42
- package/dist/src/decision/ensemble/runtime.js +571 -0
- package/dist/src/decision/ensemble-study/artifacts.js +85 -0
- package/dist/src/decision/ensemble-study/calibration.js +443 -0
- package/dist/src/decision/ensemble-study/corpus.js +229 -0
- package/dist/src/decision/ensemble-study/multifact-artifacts.js +23 -0
- package/dist/src/decision/ensemble-study/multifact-study.js +596 -0
- package/dist/src/decision/ensemble-study/multifact.js +241 -0
- package/dist/src/decision/ensemble-study/protocol.js +77 -0
- package/dist/src/decision/ensemble-study/score.js +462 -0
- package/dist/src/decision/ensemble-study/staged.js +87 -0
- package/dist/src/decision/ensemble-study/statistics.js +84 -0
- package/dist/src/decision/evaluate.js +227 -14
- package/dist/src/decision/export.js +4 -0
- package/dist/src/decision/feature-export.js +1074 -0
- package/dist/src/decision/graph-index.js +16 -0
- package/dist/src/decision/graph-live-qualification.js +1041 -0
- package/dist/src/decision/graph-live-workload.js +245 -0
- package/dist/src/decision/graph-skill-bridge.js +21 -3
- package/dist/src/decision/heldout/calibration.js +140 -0
- package/dist/src/decision/heldout/collector.js +430 -0
- package/dist/src/decision/heldout/contract.js +309 -0
- package/dist/src/decision/heldout/d29-generator-ids.js +12 -0
- package/dist/src/decision/heldout/d29-passage-baseline-v2.js +93 -0
- package/dist/src/decision/heldout/d29-passage-baseline-v3.js +100 -0
- package/dist/src/decision/heldout/d29-passage-baseline.js +66 -0
- package/dist/src/decision/heldout/d29-pools-v8.js +575 -0
- package/dist/src/decision/heldout/d29-pools.js +288 -0
- package/dist/src/decision/heldout/d29-v6.js +169 -0
- package/dist/src/decision/heldout/d29-v7.js +202 -0
- package/dist/src/decision/heldout/d29-v8.js +586 -0
- package/dist/src/decision/heldout/generator-registry.js +67 -0
- package/dist/src/decision/heldout/generators.js +696 -0
- package/dist/src/decision/heldout/index.js +8 -0
- package/dist/src/decision/heldout/journal.js +346 -0
- package/dist/src/decision/heldout/study-generators.js +64 -0
- package/dist/src/decision/heldout/types.js +2 -0
- package/dist/src/decision/host-policy.js +61 -0
- package/dist/src/decision/index.js +11 -0
- package/dist/src/decision/interop-profile.v1.json +112 -0
- package/dist/src/decision/interop.js +653 -0
- package/dist/src/decision/issue-triage/index.js +3 -0
- package/dist/src/decision/issue-triage/runtime.js +1069 -0
- package/dist/src/decision/issue-triage/types.js +2 -0
- package/dist/src/decision/patterns/catalog.js +28 -8
- package/dist/src/decision/patterns/playground.js +28 -11
- package/dist/src/decision/patterns/specs.js +19 -10
- package/dist/src/decision/preprocessed-evidence.js +724 -0
- package/dist/src/decision/qualification/capture.js +8 -2
- package/dist/src/decision/qualification/gate-evidence.js +19 -4
- package/dist/src/decision/qualification/quality.js +57 -49
- package/dist/src/decision/qualification/release.js +76 -3
- package/dist/src/decision/qualification/runner.js +5 -2
- package/dist/src/decision/routing/contract.js +175 -0
- package/dist/src/decision/routing/index.js +5 -0
- package/dist/src/decision/routing/report.js +216 -0
- package/dist/src/decision/routing/runtime.js +685 -0
- package/dist/src/decision/routing/types.js +2 -0
- package/dist/src/decision/sdlc-screening.js +1157 -0
- package/dist/src/decision/sensitivity/comparative.js +154 -0
- package/dist/src/decision/sensitivity/contract.js +218 -0
- package/dist/src/decision/sensitivity/index.js +5 -0
- package/dist/src/decision/sensitivity/runtime.js +912 -0
- package/dist/src/decision/sensitivity/types.js +2 -0
- package/dist/src/decision/validate.js +26 -0
- package/dist/src/extensions/commands/definitions.js +38 -0
- package/dist/src/extensions/manifest.js +44 -0
- package/dist/src/gates/discovery.js +315 -0
- package/dist/src/gates/driver.js +388 -0
- package/dist/src/gates/evaluate.js +719 -0
- package/dist/src/gates/floors.js +255 -0
- package/dist/src/gates/index.js +17 -0
- package/dist/src/gates/providers/evidence.js +38 -0
- package/dist/src/gates/providers/index.js +21 -0
- package/dist/src/gates/providers/isolated-child-source.js +446 -0
- package/dist/src/gates/providers/loader.js +1069 -0
- package/dist/src/gates/providers/paired.js +52 -0
- package/dist/src/gates/providers/proportion.js +60 -0
- package/dist/src/gates/providers/registry.js +40 -0
- package/dist/src/gates/providers/scalar.js +41 -0
- package/dist/src/gates/providers/screening.js +53 -0
- package/dist/src/gates/providers/types.js +25 -0
- package/dist/src/gates/registry.js +1003 -0
- package/dist/src/gates/report.js +102 -0
- package/dist/src/gates/schema.js +56 -0
- package/dist/src/gates/stats/binomial.js +26 -0
- package/dist/src/gates/stats/bootstrap.js +62 -0
- package/dist/src/gates/stats/clopper-pearson.js +95 -0
- package/dist/src/gates/stats/digest.js +26 -0
- package/dist/src/gates/stats/error.js +5 -0
- package/dist/src/gates/stats/index.js +9 -0
- package/dist/src/gates/stats/normal.js +35 -0
- package/dist/src/gates/stats/paired.js +120 -0
- package/dist/src/gates/stats/splits.js +30 -0
- package/dist/src/gates/types.js +8 -0
- package/dist/src/governance/redaction.js +14 -4
- package/dist/src/mcp/muse-native-config.mjs +123 -0
- package/dist/src/mcp/tools/decision.mjs +188 -0
- package/dist/src/mcp/tools/subsystems.mjs +2 -0
- package/dist/src/providers/capability-matrix.yaml +2 -1
- package/dist/src/providers/provider-definitions.js +2 -1
- package/dist/src/sessions/adapters/muse.js +336 -39
- package/dist/src/sessions/batch-import.js +7 -0
- package/dist/src/sessions/workspace-discovery.js +13 -2
- package/package.json +1 -1
- package/schemas/decision/ConformalFrozenOpenData.v2.schema.json +371 -0
- package/schemas/decision/ConformalOpenDataReport.v2.schema.json +421 -0
- package/schemas/decision/ConformalPreregistration.v2.schema.json +529 -0
- package/schemas/decision/ContextPruningCandidate.v1.schema.json +47 -0
- package/schemas/decision/ContextPruningEvaluationReport.v1.schema.json +758 -0
- package/schemas/decision/ContextPruningPreregistration.v1.schema.json +175 -0
- package/schemas/decision/ContextPruningReceipt.v1.schema.json +72 -0
- package/schemas/decision/D17Multifact.v1.schema.json +1851 -0
- package/schemas/decision/D17StudyAnalysis.v1.schema.json +42 -0
- package/schemas/decision/D17StudyAnalysis.v2.schema.json +51 -0
- package/schemas/decision/D17StudyCalibration.v1.schema.json +819 -0
- package/schemas/decision/D17StudyDryRun.v1.schema.json +169 -0
- package/schemas/decision/D17StudyDryRun.v2.schema.json +239 -0
- package/schemas/decision/D17StudyGold.v1.schema.json +108 -0
- package/schemas/decision/D17StudyGuide.v1.schema.json +63 -0
- package/schemas/decision/D17StudyNativeTemplates.v1.schema.json +619 -0
- package/schemas/decision/D17StudyProtocol.v1.schema.json +241 -0
- package/schemas/decision/D17StudyReport.v1.schema.json +902 -0
- package/schemas/decision/D17StudyReport.v2.schema.json +1319 -0
- package/schemas/decision/D17StudyReview.v1.schema.json +175 -0
- package/schemas/decision/D17StudySplits.v1.schema.json +217 -0
- package/schemas/decision/D29Study.v1.schema.json +1903 -0
- package/schemas/decision/D29Study.v2.schema.json +1344 -0
- package/schemas/decision/D29Study.v3.schema.json +609 -0
- package/schemas/decision/D29Study.v4.schema.json +1133 -0
- package/schemas/decision/D29Study.v6.schema.json +1205 -0
- package/schemas/decision/D29Study.v7.schema.json +1471 -0
- package/schemas/decision/D29Study.v8.schema.json +671 -0
- package/schemas/decision/D29Study.v9.schema.json +778 -0
- package/schemas/decision/DecisionComparativeReplayAuditSample.v1.schema.json +137 -0
- package/schemas/decision/DecisionComparativeReplayCorpus.v1.schema.json +258 -0
- package/schemas/decision/DecisionComparativeReplayFreeze.v1.schema.json +74 -0
- package/schemas/decision/DecisionComparativeReplayGold.v1.schema.json +50 -0
- package/schemas/decision/DecisionComparativeReplayGoldAsset.v1.schema.json +37 -0
- package/schemas/decision/DecisionComparativeReplayIntegrity.v1.schema.json +81 -0
- package/schemas/decision/DecisionComparativeReplayMembers.v1.schema.json +52 -0
- package/schemas/decision/DecisionComparativeReplayPreregistration.v1.schema.json +113 -0
- package/schemas/decision/DecisionComparativeReplayReport.v1.schema.json +407 -0
- package/schemas/decision/DecisionComparativeReplayReviewPackets.v1.schema.json +260 -0
- package/schemas/decision/DecisionComparativeReplaySplit.v1.schema.json +84 -0
- package/schemas/decision/DecisionFeatureObservation.v1.schema.json +564 -0
- package/schemas/decision/DecisionFeatureSet.v1.schema.json +155 -0
- package/schemas/decision/DecisionInteropMapping.v1.schema.json +85 -0
- package/schemas/decision/DecisionIssueTriageEvaluationManifest.v1.schema.json +174 -0
- package/schemas/decision/DecisionIssueTriageEvaluationReport.v1.schema.json +280 -0
- package/schemas/decision/DecisionIssueTriagePilotPack.v1.schema.json +114 -0
- package/schemas/decision/DecisionRouteReceipt.v1.schema.json +155 -0
- package/schemas/decision/DecisionRoutingPolicy.v1.schema.json +132 -0
- package/schemas/decision/DecisionRoutingShadowReport.v1.schema.json +170 -0
- package/schemas/decision/DecisionRoutingTask.v1.schema.json +49 -0
- package/schemas/decision/DecisionRuleset.schema.json +8 -2
- package/schemas/decision/DecisionRuleset.v1alpha2.schema.json +8 -2
- package/schemas/decision/DecisionSensitivityPlan.v1.schema.json +191 -0
- package/schemas/decision/DecisionSensitivityReport.v1.schema.json +163 -0
- package/schemas/decision/HeldoutApproval.v1.schema.json +312 -0
- package/schemas/decision/HeldoutAttempt.v1.schema.json +211 -0
- package/schemas/decision/HeldoutBaseline.v1.schema.json +90 -0
- package/schemas/decision/HeldoutCalibrationPhase.v1.schema.json +87 -0
- package/schemas/decision/HeldoutCorpus.v1.schema.json +167 -0
- package/schemas/decision/HeldoutEvent.v1.schema.json +41 -0
- package/schemas/decision/HeldoutFrozen.v1.schema.json +142 -0
- package/schemas/decision/HeldoutPreregistration.v1.schema.json +222 -0
- package/schemas/decision/HeldoutSpendEvent.v1.schema.json +122 -0
- package/schemas/decision/HeldoutSpendHead.v1.schema.json +25 -0
- package/schemas/decision/HeldoutSpendHead.v2.schema.json +46 -0
- package/schemas/decision/HeldoutSummary.v1.schema.json +101 -0
- package/schemas/decision/OpaDecisionLogExport.v1.schema.json +65 -0
- package/schemas/decision/PreprocessedEvidence.v1.schema.json +306 -0
- package/schemas/decision/RulesetResult.v1alpha2.schema.json +175 -0
- package/schemas/decision/SdlcEvidenceScreening.v1.schema.json +499 -0
- package/schemas/decision/SdlcScreeningPreregistration.v1.schema.json +132 -0
- package/schemas/decision/SdlcScreeningPreregistration.v2.schema.json +138 -0
- package/schemas/decision/SdlcScreeningRelease.v1.schema.json +654 -0
- package/schemas/decision/SdlcScreeningRelease.v2.schema.json +654 -0
- package/tools/agents/deploy-agents.mjs +1 -1
- package/tools/agents/providers/base.mjs +26 -7
- package/tools/agents/providers/factory.mjs +10 -2
- package/tools/agents/providers/muse-hooks.mjs +1 -29
- package/tools/agents/providers/muse.mjs +6 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Muse Code session adapter —
|
|
2
|
+
* Muse Code session adapter — explicit export plus evidence-gated native logs.
|
|
3
3
|
*
|
|
4
4
|
* Muse Code journals model calls, tool runs, and approvals to an append-only
|
|
5
5
|
* session log and projects it into a self-contained JSON document via
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
* fail closed with `UNKNOWN_SCHEMA_MAJOR`, as with peer native-export
|
|
10
10
|
* adapters.
|
|
11
11
|
*
|
|
12
|
-
* Auto-discovery
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* here; a future evidence-gated `--muse-root` discover path remains the
|
|
17
|
-
* route to native discovery (#222 PR B).
|
|
12
|
+
* Auto-discovery must never scrape home directories or invent session roots.
|
|
13
|
+
* Native discovery is available only when the operator explicitly authorizes
|
|
14
|
+
* a Muse sessions root with `--muse-root`; the adapter then enumerates only
|
|
15
|
+
* `$root/YYYY/MM/DD/<session-id>/session.jsonl`.
|
|
18
16
|
*
|
|
19
17
|
* Trajectory shape follows the documented export format at
|
|
20
18
|
* https://dev.meta.ai/docs/cookbook/audit-agent-sessions: top-level
|
|
@@ -41,13 +39,17 @@
|
|
|
41
39
|
* @see docs/providers/muse-sessions.md
|
|
42
40
|
* @issue #232
|
|
43
41
|
*/
|
|
42
|
+
import { opendir } from 'node:fs/promises';
|
|
43
|
+
import { resolve } from 'node:path';
|
|
44
44
|
import { z } from 'zod';
|
|
45
45
|
import { SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
|
|
46
|
-
import { readBoundedJson } from '../readers.js';
|
|
46
|
+
import { readBoundedJson, readBoundedJsonLines, } from '../readers.js';
|
|
47
47
|
export const MUSE_ADAPTER_VERSION = '1.0.0';
|
|
48
48
|
export const MUSE_EXPORT_SCHEMA_VERSION = '1.0.0';
|
|
49
49
|
export const MUSE_EXPORT_SCHEMA_MAJOR = 1;
|
|
50
50
|
export const MUSE_LOCATOR_CLASS = 'manual-export';
|
|
51
|
+
export const MUSE_NATIVE_LOCATOR_CLASS = 'muse-native-session-log';
|
|
52
|
+
export const MUSE_NATIVE_SCHEMA_VERSION = '1.0.0';
|
|
51
53
|
const Rfc3339Schema = z.string().refine((value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value)
|
|
52
54
|
&& !Number.isNaN(Date.parse(value)), 'timestamp must be RFC 3339 with an explicit UTC offset');
|
|
53
55
|
/**
|
|
@@ -119,7 +121,10 @@ const MuseDiagnosticsSchema = z.object({
|
|
|
119
121
|
unknown_payload_kinds: z.number().int().nonnegative().optional(),
|
|
120
122
|
gaps: z.number().int().nonnegative().optional(),
|
|
121
123
|
omitted_live_only: z.number().int().nonnegative().optional(),
|
|
124
|
+
omitted_records: z.number().int().nonnegative().optional(),
|
|
122
125
|
duplicate_records: z.number().int().nonnegative().optional(),
|
|
126
|
+
retained_frames: z.number().int().nonnegative().optional(),
|
|
127
|
+
retained_frame_children: z.number().int().nonnegative().optional(),
|
|
123
128
|
}).passthrough();
|
|
124
129
|
const MuseTrajectorySchema = z.object({
|
|
125
130
|
export_schema_version: z.number().int().nonnegative(),
|
|
@@ -134,24 +139,53 @@ const MuseTrajectorySchema = z.object({
|
|
|
134
139
|
function isRecordEvent(event) {
|
|
135
140
|
return event.kind === 'record';
|
|
136
141
|
}
|
|
142
|
+
const MuseRetainedFrameSchema = z.object({
|
|
143
|
+
retained_frame: z.string().min(1),
|
|
144
|
+
frame_schema_version: z.number().int().nonnegative().optional(),
|
|
145
|
+
outer_log_ordinal: z.number().int().nonnegative().optional(),
|
|
146
|
+
transaction_id: z.string().optional(),
|
|
147
|
+
content_sha256: z.string().optional(),
|
|
148
|
+
children: z.array(z.object({
|
|
149
|
+
child_index: z.number().int().nonnegative().optional(),
|
|
150
|
+
record_json: z.string().min(1),
|
|
151
|
+
}).passthrough()),
|
|
152
|
+
}).passthrough();
|
|
137
153
|
export class MuseSessionAdapter {
|
|
138
154
|
limits;
|
|
155
|
+
maxFiles;
|
|
139
156
|
provider = 'muse';
|
|
140
157
|
adapterVersion = MUSE_ADAPTER_VERSION;
|
|
141
|
-
disposition = '
|
|
142
|
-
supportedOperations = ['inspect', 'stream'];
|
|
143
|
-
acquisitionModes = ['manual-export'];
|
|
144
|
-
constructor(limits) {
|
|
158
|
+
disposition = 'implemented';
|
|
159
|
+
supportedOperations = ['discover', 'inspect', 'stream'];
|
|
160
|
+
acquisitionModes = ['manual-export', 'jsonl'];
|
|
161
|
+
constructor(limits, maxFiles = 10_000) {
|
|
145
162
|
this.limits = limits;
|
|
163
|
+
this.maxFiles = maxFiles;
|
|
146
164
|
}
|
|
147
|
-
async *discover(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
165
|
+
async *discover(scope) {
|
|
166
|
+
if (scope.allowedRoots.length === 0) {
|
|
167
|
+
throw unsupportedNativeDiscovery();
|
|
168
|
+
}
|
|
169
|
+
let count = 0;
|
|
170
|
+
for (const root of [...scope.allowedRoots].sort()) {
|
|
171
|
+
for await (const locator of museNativeSessionLogs(resolve(root))) {
|
|
172
|
+
if (++count > this.maxFiles) {
|
|
173
|
+
throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Muse native session discovery exceeded the authorized file limit');
|
|
174
|
+
}
|
|
175
|
+
yield { provider: 'muse', locator, locatorClass: MUSE_NATIVE_LOCATOR_CLASS };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
152
178
|
}
|
|
153
179
|
async inspect(source) {
|
|
154
|
-
|
|
180
|
+
if (source.locatorClass === MUSE_NATIVE_LOCATOR_CLASS) {
|
|
181
|
+
const native = await this.readNative(source);
|
|
182
|
+
return {
|
|
183
|
+
sourceSchemaVersion: MUSE_NATIVE_SCHEMA_VERSION,
|
|
184
|
+
consistency: native.complete ? 'complete' : 'provisional',
|
|
185
|
+
operationalState: 'available',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
this.assertSupportedLocator(source);
|
|
155
189
|
const { trajectory } = await this.readTrajectory(source);
|
|
156
190
|
for (const event of trajectory.events)
|
|
157
191
|
this.parseEvent(event);
|
|
@@ -162,10 +196,38 @@ export class MuseSessionAdapter {
|
|
|
162
196
|
};
|
|
163
197
|
}
|
|
164
198
|
async *stream(source, cursor) {
|
|
165
|
-
|
|
199
|
+
if (source.locatorClass === MUSE_NATIVE_LOCATOR_CLASS) {
|
|
200
|
+
const native = await this.readNative(source);
|
|
201
|
+
const start = parseEventCursor(cursor?.value);
|
|
202
|
+
let outputIndex = 0;
|
|
203
|
+
for (const record of native.records) {
|
|
204
|
+
const position = outputIndex;
|
|
205
|
+
outputIndex += 1;
|
|
206
|
+
if (position < start)
|
|
207
|
+
continue;
|
|
208
|
+
const mapped = this.toProviderRecord(native.context, record.event.envelope, record.event, position);
|
|
209
|
+
mapped.rawReference = {
|
|
210
|
+
locatorClass: MUSE_NATIVE_LOCATOR_CLASS,
|
|
211
|
+
offset: record.line.byteOffset,
|
|
212
|
+
sequence: record.line.sequence,
|
|
213
|
+
};
|
|
214
|
+
mapped.sourceCursor = String(outputIndex);
|
|
215
|
+
mapped.extensions = {
|
|
216
|
+
...mapped.extensions,
|
|
217
|
+
'native.muse': compactObject({
|
|
218
|
+
...(mapped.extensions?.['native.muse'] ?? {}),
|
|
219
|
+
retainedFrame: record.retainedFrame,
|
|
220
|
+
retainedChildIndex: record.retainedChildIndex,
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
yield mapped;
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
this.assertSupportedLocator(source);
|
|
166
228
|
const { trajectory, bytesRead } = await this.readTrajectory(source);
|
|
167
229
|
const start = parseEventCursor(cursor?.value);
|
|
168
|
-
const
|
|
230
|
+
const context = contextFromTrajectory(trajectory, bytesRead);
|
|
169
231
|
let index = 0;
|
|
170
232
|
for (const event of trajectory.events) {
|
|
171
233
|
// Cursor positions are raw event positions so resume stays aligned
|
|
@@ -178,7 +240,7 @@ export class MuseSessionAdapter {
|
|
|
178
240
|
// fabricate a ProviderRecord for one.
|
|
179
241
|
if (!isRecordEvent(event))
|
|
180
242
|
continue;
|
|
181
|
-
yield this.toProviderRecord(
|
|
243
|
+
yield this.toProviderRecord(context, event.envelope, event, position);
|
|
182
244
|
}
|
|
183
245
|
}
|
|
184
246
|
async readTrajectory(source) {
|
|
@@ -203,12 +265,12 @@ export class MuseSessionAdapter {
|
|
|
203
265
|
parseEvent(event) {
|
|
204
266
|
eventKindOf(event);
|
|
205
267
|
}
|
|
206
|
-
toProviderRecord(
|
|
268
|
+
toProviderRecord(context, envelope, event, index) {
|
|
207
269
|
// Attribute by the event's own stream id; fall back to the document's
|
|
208
270
|
// first session summary only when the stream block is absent. Live
|
|
209
271
|
// evidence (Muse Code 1.3.0) shows merged events always carry the parent
|
|
210
272
|
// id here, so never assume sessions[0] without reading the envelope.
|
|
211
|
-
const nativeSessionId = streamSessionIdOf(envelope) ??
|
|
273
|
+
const nativeSessionId = streamSessionIdOf(envelope) ?? context.fallbackSessionId;
|
|
212
274
|
const payload = envelope.payload ?? {};
|
|
213
275
|
const payloadRecord = payload;
|
|
214
276
|
const eventKind = eventKindOf(event);
|
|
@@ -219,7 +281,7 @@ export class MuseSessionAdapter {
|
|
|
219
281
|
const approvalOutcome = stringField(payloadRecord, 'outcome');
|
|
220
282
|
const decisionSource = objectField(payloadRecord, 'decision_source');
|
|
221
283
|
const linkage = subagentLinkageOf(payloadRecord);
|
|
222
|
-
const spawnContext = spawnContextOf(spawns, envelope.payload_type, linkage.subagentId);
|
|
284
|
+
const spawnContext = spawnContextOf(context.spawns, envelope.payload_type, linkage.subagentId);
|
|
223
285
|
return {
|
|
224
286
|
nativeSessionId,
|
|
225
287
|
nativeEventId: `muse-seq-${envelope.sequence}`,
|
|
@@ -232,14 +294,15 @@ export class MuseSessionAdapter {
|
|
|
232
294
|
model: undefined,
|
|
233
295
|
entities: [],
|
|
234
296
|
occurredAt: occurredAtOf(envelope.recorded_at) ?? undefined,
|
|
235
|
-
text: describeEvent(eventKind, envelope.sequence, {
|
|
297
|
+
text: describeEvent(context.sourceLabel, eventKind, envelope.sequence, {
|
|
236
298
|
operation, policyDecision, decision, approvalOutcome, decisionSource,
|
|
237
299
|
}),
|
|
238
|
-
rawReference: { locatorClass:
|
|
300
|
+
rawReference: { locatorClass: context.locatorClass, sequence: index },
|
|
239
301
|
sourceCursor: String(index + 1),
|
|
240
|
-
sourceBytes: bytesRead,
|
|
302
|
+
sourceBytes: context.bytesRead,
|
|
241
303
|
extensions: {
|
|
242
304
|
'native.muse': compactObject({
|
|
305
|
+
acquisition: context.locatorClass,
|
|
243
306
|
eventKind,
|
|
244
307
|
recordType: event.kind,
|
|
245
308
|
payloadType: envelope.payload_type,
|
|
@@ -249,11 +312,11 @@ export class MuseSessionAdapter {
|
|
|
249
312
|
envelopeSequence: envelope.sequence,
|
|
250
313
|
envelopeId: envelope.id,
|
|
251
314
|
causationId: envelope.causation_id,
|
|
252
|
-
exportSchemaVersion:
|
|
253
|
-
redaction:
|
|
254
|
-
exporterVersion:
|
|
255
|
-
sessionBuild:
|
|
256
|
-
terminatedAbnormally:
|
|
315
|
+
exportSchemaVersion: context.exportSchemaVersion,
|
|
316
|
+
redaction: context.redaction,
|
|
317
|
+
exporterVersion: context.exporterVersion,
|
|
318
|
+
sessionBuild: context.sessionBuild,
|
|
319
|
+
terminatedAbnormally: context.terminatedAbnormally,
|
|
257
320
|
operation,
|
|
258
321
|
policyDecision,
|
|
259
322
|
decision,
|
|
@@ -261,17 +324,246 @@ export class MuseSessionAdapter {
|
|
|
261
324
|
approvalOutcome,
|
|
262
325
|
...linkage,
|
|
263
326
|
...spawnContext,
|
|
264
|
-
diagnostics:
|
|
327
|
+
diagnostics: context.diagnostics,
|
|
265
328
|
}),
|
|
266
329
|
},
|
|
267
330
|
};
|
|
268
331
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
332
|
+
async readNative(source) {
|
|
333
|
+
this.assertSupportedLocator(source);
|
|
334
|
+
let input;
|
|
335
|
+
try {
|
|
336
|
+
input = await readBoundedJsonLines({ selectedPath: source.locator, allowedRoots: source.authorizedScope.allowedRoots }, { consistency: 'complete', limits: this.limits });
|
|
273
337
|
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
if (error instanceof SessionContractError && error.code === 'SCHEMA_DRIFT') {
|
|
340
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse native session log contains malformed JSONL');
|
|
341
|
+
}
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
344
|
+
const diagnostics = {};
|
|
345
|
+
const records = [];
|
|
346
|
+
let fallbackSessionId = nativeSessionIdFromLocator(source.locator) ?? source.sourceId;
|
|
347
|
+
let complete = false;
|
|
348
|
+
for (const line of input.records) {
|
|
349
|
+
const value = line.value;
|
|
350
|
+
if (isOmissionMarker(value)) {
|
|
351
|
+
diagnostics.omitted_records = (diagnostics.omitted_records ?? 0) + 1;
|
|
352
|
+
if (asObject(value).retained_marker === 'omitted_live_only') {
|
|
353
|
+
diagnostics.omitted_live_only = (diagnostics.omitted_live_only ?? 0) + 1;
|
|
354
|
+
}
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
const retained = MuseRetainedFrameSchema.safeParse(value);
|
|
358
|
+
if (retained.success) {
|
|
359
|
+
diagnostics.retained_frames = (diagnostics.retained_frames ?? 0) + 1;
|
|
360
|
+
for (const child of retained.data.children) {
|
|
361
|
+
let decoded;
|
|
362
|
+
try {
|
|
363
|
+
decoded = JSON.parse(child.record_json);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse retained frame child record is malformed JSON');
|
|
367
|
+
}
|
|
368
|
+
const event = recordEventFromEnvelope(decoded);
|
|
369
|
+
if (!event) {
|
|
370
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse retained frame child record is malformed');
|
|
371
|
+
}
|
|
372
|
+
fallbackSessionId = streamSessionIdOf(event.envelope) ?? fallbackSessionId;
|
|
373
|
+
complete ||= event.envelope.payload_type === 'session.end';
|
|
374
|
+
diagnostics.retained_frame_children = (diagnostics.retained_frame_children ?? 0) + 1;
|
|
375
|
+
records.push({
|
|
376
|
+
event,
|
|
377
|
+
line,
|
|
378
|
+
retainedFrame: retained.data.retained_frame,
|
|
379
|
+
retainedChildIndex: child.child_index,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const event = recordEventFromEnvelope(value);
|
|
385
|
+
if (!event) {
|
|
386
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse native session log line is not a supported record shape');
|
|
387
|
+
}
|
|
388
|
+
fallbackSessionId = streamSessionIdOf(event.envelope) ?? fallbackSessionId;
|
|
389
|
+
complete ||= event.envelope.payload_type === 'session.end';
|
|
390
|
+
records.push({ event, line });
|
|
391
|
+
}
|
|
392
|
+
if (records.length === 0) {
|
|
393
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse native session log contains no record envelopes');
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
records,
|
|
397
|
+
complete,
|
|
398
|
+
context: {
|
|
399
|
+
locatorClass: MUSE_NATIVE_LOCATOR_CLASS,
|
|
400
|
+
sourceLabel: 'muse native session log',
|
|
401
|
+
bytesRead: input.bytesRead,
|
|
402
|
+
fallbackSessionId,
|
|
403
|
+
spawns: new Map(),
|
|
404
|
+
diagnostics,
|
|
405
|
+
},
|
|
406
|
+
};
|
|
274
407
|
}
|
|
408
|
+
assertSupportedLocator(source) {
|
|
409
|
+
if (source.locatorClass !== MUSE_LOCATOR_CLASS && source.locatorClass !== MUSE_NATIVE_LOCATOR_CLASS) {
|
|
410
|
+
throw new SessionContractError('UNSUPPORTED_OPERATION', `Muse Code supports locatorClass "${MUSE_LOCATOR_CLASS}" and explicitly authorized `
|
|
411
|
+
+ `"${MUSE_NATIVE_LOCATOR_CLASS}" sources (got "${source.locatorClass}").`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function unsupportedNativeDiscovery() {
|
|
416
|
+
return new SessionContractError('UNSUPPORTED_OPERATION', 'Muse Code session auto-discover is unsupported: the native log under '
|
|
417
|
+
+ '$XDG_DATA_HOME/muse/sessions uses an internal format. Run `muse export --session '
|
|
418
|
+
+ '<id-or-session.jsonl>` and select that trajectory file. AIWG does not scrape home '
|
|
419
|
+
+ 'directories for this provider.');
|
|
420
|
+
}
|
|
421
|
+
function contextFromTrajectory(trajectory, bytesRead) {
|
|
422
|
+
return {
|
|
423
|
+
locatorClass: MUSE_LOCATOR_CLASS,
|
|
424
|
+
sourceLabel: 'muse export trajectory',
|
|
425
|
+
bytesRead,
|
|
426
|
+
fallbackSessionId: trajectory.sessions[0].session_id,
|
|
427
|
+
spawns: acceptedSpawnsById(trajectory),
|
|
428
|
+
exportSchemaVersion: trajectory.export_schema_version,
|
|
429
|
+
redaction: trajectory.redaction,
|
|
430
|
+
exporterVersion: trajectory.exporter_version?.display,
|
|
431
|
+
sessionBuild: trajectory.session_build?.display,
|
|
432
|
+
terminatedAbnormally: trajectory.session_terminated_abnormally,
|
|
433
|
+
diagnostics: trajectory.diagnostics,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
async function* museNativeSessionLogs(root) {
|
|
437
|
+
let years;
|
|
438
|
+
try {
|
|
439
|
+
years = await opendir(root);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
for await (const year of years) {
|
|
445
|
+
if (!year.isDirectory() || !/^\d{4}$/.test(year.name))
|
|
446
|
+
continue;
|
|
447
|
+
const yearPath = resolve(root, year.name);
|
|
448
|
+
let months;
|
|
449
|
+
try {
|
|
450
|
+
months = await opendir(yearPath);
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
for await (const month of months) {
|
|
456
|
+
if (!month.isDirectory() || !/^(0[1-9]|1[0-2])$/.test(month.name))
|
|
457
|
+
continue;
|
|
458
|
+
const monthPath = resolve(yearPath, month.name);
|
|
459
|
+
let days;
|
|
460
|
+
try {
|
|
461
|
+
days = await opendir(monthPath);
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
for await (const day of days) {
|
|
467
|
+
if (!day.isDirectory() || !/^(0[1-9]|[12]\d|3[01])$/.test(day.name))
|
|
468
|
+
continue;
|
|
469
|
+
const dayPath = resolve(monthPath, day.name);
|
|
470
|
+
let sessions;
|
|
471
|
+
try {
|
|
472
|
+
sessions = await opendir(dayPath);
|
|
473
|
+
}
|
|
474
|
+
catch {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
for await (const session of sessions) {
|
|
478
|
+
if (!session.isDirectory() || !/^[A-Za-z0-9._-]+$/.test(session.name))
|
|
479
|
+
continue;
|
|
480
|
+
const sessionPath = resolve(dayPath, session.name);
|
|
481
|
+
let entries;
|
|
482
|
+
try {
|
|
483
|
+
entries = await opendir(sessionPath);
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
for await (const entry of entries) {
|
|
489
|
+
if (entry.isFile() && entry.name === 'session.jsonl') {
|
|
490
|
+
yield resolve(sessionPath, entry.name);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
export async function museNativeSourceMatchesWorkspace(source, workspacePath) {
|
|
499
|
+
let input;
|
|
500
|
+
try {
|
|
501
|
+
input = await readBoundedJsonLines({ selectedPath: source.locator, allowedRoots: source.authorizedScope.allowedRoots }, { consistency: 'complete', limits: { maxRecords: 100, maxRecordBytes: 8 * 1024 * 1024 } });
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
for (const line of input.records) {
|
|
507
|
+
for (const envelope of nativeEnvelopesFromLine(line.value)) {
|
|
508
|
+
const candidate = workspaceEvidenceOf(envelope);
|
|
509
|
+
if (!candidate)
|
|
510
|
+
continue;
|
|
511
|
+
if (workspacePathEquals(candidate, workspacePath))
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
function nativeEnvelopesFromLine(value) {
|
|
518
|
+
if (isOmissionMarker(value))
|
|
519
|
+
return [];
|
|
520
|
+
const event = recordEventFromEnvelope(value);
|
|
521
|
+
if (event)
|
|
522
|
+
return [event.envelope];
|
|
523
|
+
const retained = MuseRetainedFrameSchema.safeParse(value);
|
|
524
|
+
if (!retained.success)
|
|
525
|
+
return [];
|
|
526
|
+
const envelopes = [];
|
|
527
|
+
for (const child of retained.data.children) {
|
|
528
|
+
try {
|
|
529
|
+
const childEvent = recordEventFromEnvelope(JSON.parse(child.record_json));
|
|
530
|
+
if (childEvent)
|
|
531
|
+
envelopes.push(childEvent.envelope);
|
|
532
|
+
}
|
|
533
|
+
catch {
|
|
534
|
+
return [];
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return envelopes;
|
|
538
|
+
}
|
|
539
|
+
function recordEventFromEnvelope(value) {
|
|
540
|
+
const envelope = MuseEnvelopeSchema.safeParse(value);
|
|
541
|
+
return envelope.success ? { kind: 'record', envelope: envelope.data } : null;
|
|
542
|
+
}
|
|
543
|
+
function isOmissionMarker(value) {
|
|
544
|
+
const record = asObject(value);
|
|
545
|
+
return Object.prototype.hasOwnProperty.call(record, 'omitted_record')
|
|
546
|
+
|| record.retained_marker === 'omitted_live_only';
|
|
547
|
+
}
|
|
548
|
+
function workspaceEvidenceOf(envelope) {
|
|
549
|
+
const payload = asObject(envelope.payload);
|
|
550
|
+
const record = asObject(payload.record);
|
|
551
|
+
for (const candidate of [record.workspace_root, record.cwd]) {
|
|
552
|
+
if (typeof candidate === 'string' && candidate.length > 0)
|
|
553
|
+
return candidate;
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
function workspacePathEquals(candidate, workspacePath) {
|
|
558
|
+
return resolve(candidate) === workspacePath;
|
|
559
|
+
}
|
|
560
|
+
function nativeSessionIdFromLocator(locator) {
|
|
561
|
+
const parts = locator.replaceAll('\\', '/').split('/');
|
|
562
|
+
const leaf = parts.at(-1);
|
|
563
|
+
if (leaf !== 'session.jsonl')
|
|
564
|
+
return null;
|
|
565
|
+
const sessionId = parts.at(-2);
|
|
566
|
+
return sessionId && /^[A-Za-z0-9._-]+$/.test(sessionId) ? sessionId : null;
|
|
275
567
|
}
|
|
276
568
|
/**
|
|
277
569
|
* Effective event kind per the documented jq projection:
|
|
@@ -371,6 +663,11 @@ function objectField(payload, key) {
|
|
|
371
663
|
? value
|
|
372
664
|
: null;
|
|
373
665
|
}
|
|
666
|
+
function asObject(value) {
|
|
667
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
668
|
+
? value
|
|
669
|
+
: {};
|
|
670
|
+
}
|
|
374
671
|
function occurredAtOf(recordedAt) {
|
|
375
672
|
if (typeof recordedAt === 'number') {
|
|
376
673
|
// Epoch microseconds (Muse Code 1.4.0 export and native log).
|
|
@@ -381,8 +678,8 @@ function occurredAtOf(recordedAt) {
|
|
|
381
678
|
return null;
|
|
382
679
|
return Rfc3339Schema.safeParse(recordedAt).success ? recordedAt : null;
|
|
383
680
|
}
|
|
384
|
-
function describeEvent(eventKind, sequence, provenance) {
|
|
385
|
-
const parts = [
|
|
681
|
+
function describeEvent(sourceLabel, eventKind, sequence, provenance) {
|
|
682
|
+
const parts = [`${sourceLabel} event ${eventKind} (sequence ${sequence})`];
|
|
386
683
|
if (provenance.operation)
|
|
387
684
|
parts.push(`operation=${provenance.operation}`);
|
|
388
685
|
if (provenance.policyDecision)
|
|
@@ -5,6 +5,7 @@ import { CLAUDE_ADAPTER_VERSION, ClaudeSessionAdapter, } from './adapters/claude
|
|
|
5
5
|
import { CODEX_ADAPTER_VERSION, CodexSessionAdapter, } from './adapters/codex.js';
|
|
6
6
|
import { CURSOR_ADAPTER_VERSION, CursorSessionAdapter, } from './adapters/cursor.js';
|
|
7
7
|
import { FACTORY_ADAPTER_VERSION, FactorySessionAdapter, } from './adapters/factory.js';
|
|
8
|
+
import { MUSE_ADAPTER_VERSION, MuseSessionAdapter, } from './adapters/muse.js';
|
|
8
9
|
import { SESSION_CONTRACT_VERSION, SessionContractError, SessionSourceSchema, sha256, } from './contracts.js';
|
|
9
10
|
import { BATCH_IMPORT_VERSION, coverageFromBatchRun, } from './batch-contracts.js';
|
|
10
11
|
import { IncrementalSessionImporter, SessionImportFailure } from './importer.js';
|
|
@@ -211,6 +212,8 @@ function adapterFor(provider) {
|
|
|
211
212
|
return new CursorSessionAdapter();
|
|
212
213
|
if (provider === 'factory')
|
|
213
214
|
return new FactorySessionAdapter();
|
|
215
|
+
if (provider === 'muse')
|
|
216
|
+
return new MuseSessionAdapter();
|
|
214
217
|
throw new SessionContractError('UNSUPPORTED_OPERATION', `batch discovery import is not implemented for ${provider}`);
|
|
215
218
|
}
|
|
216
219
|
async function sessionSource(selected, adapter) {
|
|
@@ -244,6 +247,8 @@ function adapterVersion(provider) {
|
|
|
244
247
|
return CURSOR_ADAPTER_VERSION;
|
|
245
248
|
if (provider === 'factory')
|
|
246
249
|
return FACTORY_ADAPTER_VERSION;
|
|
250
|
+
if (provider === 'muse')
|
|
251
|
+
return MUSE_ADAPTER_VERSION;
|
|
247
252
|
return '1.0.0';
|
|
248
253
|
}
|
|
249
254
|
function providerProfile(provider, locatorClass) {
|
|
@@ -262,6 +267,8 @@ function providerProfile(provider, locatorClass) {
|
|
|
262
267
|
}
|
|
263
268
|
if (provider === 'factory')
|
|
264
269
|
return 'documented-project-jsonl';
|
|
270
|
+
if (provider === 'muse')
|
|
271
|
+
return 'muse-native-session-log-v1';
|
|
265
272
|
return 'manual-interchange';
|
|
266
273
|
}
|
|
267
274
|
function importErrorCode(error) {
|
|
@@ -7,6 +7,7 @@ import { ClaudeSessionAdapter } from './adapters/claude.js';
|
|
|
7
7
|
import { CodexSessionAdapter } from './adapters/codex.js';
|
|
8
8
|
import { CursorSessionAdapter } from './adapters/cursor.js';
|
|
9
9
|
import { FactorySessionAdapter } from './adapters/factory.js';
|
|
10
|
+
import { MuseSessionAdapter, museNativeSourceMatchesWorkspace } from './adapters/muse.js';
|
|
10
11
|
import { OmpSessionAdapter, readOmpSessionHeader } from './adapters/omp.js';
|
|
11
12
|
import { resolveOmpPaths } from '../providers/omp-paths.mjs';
|
|
12
13
|
import { PiSessionAdapter } from './adapters/pi.js';
|
|
@@ -17,7 +18,7 @@ import { fingerprintSourceFile } from './readers.js';
|
|
|
17
18
|
export const DISCOVERY_MANIFEST_VERSION = '1.0.0';
|
|
18
19
|
const MANUAL_EXPORT_PROVIDERS = new Set([
|
|
19
20
|
'copilot', 'hermes', 'opencode', 'openclaw', 'openhuman', 'grokbot', 'grok-build',
|
|
20
|
-
'warp', 'devin-desktop', '
|
|
21
|
+
'warp', 'devin-desktop', 'generic',
|
|
21
22
|
]);
|
|
22
23
|
export async function discoverWorkspaceHistories(options) {
|
|
23
24
|
const workspacePath = await canonicalPath(options.workspace);
|
|
@@ -32,6 +33,8 @@ export async function discoverWorkspaceHistories(options) {
|
|
|
32
33
|
{ provider: 'omp', adapter: new OmpSessionAdapter(), roots: options.ompRoot
|
|
33
34
|
? [resolve(options.ompRoot)] : options.providerHome
|
|
34
35
|
? [resolveOmpPaths({ home: resolve(options.providerHome), cwd: workspacePath }).sessionsDir] : [] },
|
|
36
|
+
{ provider: 'muse', adapter: new MuseSessionAdapter(), roots: options.museRoot
|
|
37
|
+
? [resolve(options.museRoot)] : [] },
|
|
35
38
|
{
|
|
36
39
|
provider: 'claude',
|
|
37
40
|
adapter: new ClaudeSessionAdapter(),
|
|
@@ -79,7 +82,8 @@ export async function discoverWorkspaceHistories(options) {
|
|
|
79
82
|
availableRoots.push(await canonicalPath(root));
|
|
80
83
|
}
|
|
81
84
|
if (availableRoots.length === 0) {
|
|
82
|
-
const codexNeedsAuthorization = (entry.provider === 'codex' || entry.provider === 'omp'
|
|
85
|
+
const codexNeedsAuthorization = (entry.provider === 'codex' || entry.provider === 'omp'
|
|
86
|
+
|| entry.provider === 'deepseek-harness' || entry.provider === 'muse')
|
|
83
87
|
&& entry.roots.length === 0;
|
|
84
88
|
reports.set(entry.provider, providerReport(entry.provider, codexNeedsAuthorization ? 'export-required' : 'unavailable', codexNeedsAuthorization ? 'manual-export' : 'discoverable', [], codexNeedsAuthorization
|
|
85
89
|
? 'SHARED_ROOT_AUTHORIZATION_REQUIRED'
|
|
@@ -98,6 +102,13 @@ export async function discoverWorkspaceHistories(options) {
|
|
|
98
102
|
if (entry.provider === 'codex'
|
|
99
103
|
&& !await codexSourceMatchesWorkspace(locator, workspacePath))
|
|
100
104
|
continue;
|
|
105
|
+
if (entry.provider === 'muse'
|
|
106
|
+
&& !await museNativeSourceMatchesWorkspace({
|
|
107
|
+
...descriptor,
|
|
108
|
+
sourceId: 'discovery',
|
|
109
|
+
authorizedScope: scope,
|
|
110
|
+
}, workspacePath))
|
|
111
|
+
continue;
|
|
101
112
|
const ompHeader = entry.provider === 'omp' ? await readOmpSessionHeader({ ...descriptor, sourceId: 'discovery', authorizedScope: scope }) : undefined;
|
|
102
113
|
if (ompHeader && resolve(ompHeader.cwd) !== workspacePath)
|
|
103
114
|
continue;
|