sidekick-shared 0.27.5 → 0.28.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/CHANGELOG.md +58 -0
- package/README.md +93 -52
- package/dist/accountHealth.d.ts +14 -0
- package/dist/accountHealth.js +61 -14
- package/dist/accountLaunch.d.ts +6 -0
- package/dist/accountLaunch.js +61 -4
- package/dist/accountLease.d.ts +5 -0
- package/dist/accountLease.js +98 -0
- package/dist/accountManager.d.ts +7 -0
- package/dist/accountManager.js +226 -89
- package/dist/accountSync.d.ts +1 -5
- package/dist/accountSync.js +22 -6
- package/dist/accountSyncTypes.d.ts +9 -0
- package/dist/accounts.d.ts +75 -18
- package/dist/accounts.js +712 -189
- package/dist/browser.d.ts +13 -2
- package/dist/browser.js +30 -2
- package/dist/claudeCredentialDoctor.d.ts +50 -0
- package/dist/claudeCredentialDoctor.js +277 -0
- package/dist/claudeCredentialLedger.d.ts +15 -0
- package/dist/claudeCredentialLedger.js +130 -0
- package/dist/claudeCredentials.d.ts +20 -3
- package/dist/claudeCredentials.js +50 -3
- package/dist/claudeLiveGuard.d.ts +33 -0
- package/dist/claudeLiveGuard.js +46 -0
- package/dist/claudePaths.d.ts +11 -0
- package/dist/claudePaths.js +61 -0
- package/dist/claudeProfiles.d.ts +15 -8
- package/dist/claudeProfiles.js +30 -23
- package/dist/claudeRefreshLock.d.ts +15 -0
- package/dist/claudeRefreshLock.js +145 -0
- package/dist/codexAuth.d.ts +4 -0
- package/dist/codexAuth.js +18 -0
- package/dist/codexCredentialDoctor.d.ts +33 -0
- package/dist/codexCredentialDoctor.js +302 -0
- package/dist/codexCredentialStore.d.ts +29 -0
- package/dist/codexCredentialStore.js +213 -0
- package/dist/codexKeepAlive.d.ts +2 -0
- package/dist/codexKeepAlive.js +116 -0
- package/dist/codexPaths.d.ts +30 -2
- package/dist/codexPaths.js +118 -7
- package/dist/codexProfiles.d.ts +38 -35
- package/dist/codexProfiles.js +848 -715
- package/dist/credentialIO.d.ts +67 -7
- package/dist/credentialIO.js +211 -47
- package/dist/doctor.js +2 -2
- package/dist/ensureDefaultAccounts.js +1 -8
- package/dist/esm/accountChangeSignal.js +15 -0
- package/dist/esm/accountChanges.js +152 -0
- package/dist/esm/accountHealth.js +288 -0
- package/dist/esm/accountLaunch.js +145 -0
- package/dist/esm/accountLease.js +60 -0
- package/dist/esm/accountManager.js +606 -0
- package/dist/esm/accountRegistry.js +214 -0
- package/dist/esm/accountStatus.js +51 -0
- package/dist/esm/accountSwitch.js +74 -0
- package/dist/esm/accountSync.js +156 -0
- package/dist/esm/accountSyncTypes.js +4 -0
- package/dist/esm/accounts.js +1291 -0
- package/dist/esm/aggregation/EventAggregator.js +2034 -0
- package/dist/esm/aggregation/FrequencyTracker.js +69 -0
- package/dist/esm/aggregation/HeatmapTracker.js +89 -0
- package/dist/esm/aggregation/PatternExtractor.js +168 -0
- package/dist/esm/aggregation/costProvenance.js +31 -0
- package/dist/esm/aggregation/snapshot.js +161 -0
- package/dist/esm/aggregation/types.js +5 -0
- package/dist/esm/analytics/codeImpact.js +18 -0
- package/dist/esm/analytics/compactionLedger.js +37 -0
- package/dist/esm/analytics/qualityScore.js +112 -0
- package/dist/esm/autoSwitch.js +185 -0
- package/dist/esm/browser.js +34 -0
- package/dist/esm/claudeCredentialDoctor.js +239 -0
- package/dist/esm/claudeCredentialLedger.js +91 -0
- package/dist/esm/claudeCredentials.js +111 -0
- package/dist/esm/claudeLiveGuard.js +43 -0
- package/dist/esm/claudePaths.js +22 -0
- package/dist/esm/claudeProfiles.js +142 -0
- package/dist/esm/claudeRefreshLock.js +106 -0
- package/dist/esm/codexAuth.js +101 -0
- package/dist/esm/codexCredentialDoctor.js +265 -0
- package/dist/esm/codexCredentialStore.js +164 -0
- package/dist/esm/codexKeepAlive.js +112 -0
- package/dist/esm/codexPaths.js +172 -0
- package/dist/esm/codexProfiles.js +1251 -0
- package/dist/esm/codexQuota.js +564 -0
- package/dist/esm/codexQuotaWatcher.js +363 -0
- package/dist/esm/context/composer.js +71 -0
- package/dist/esm/context/sessionContext.js +546 -0
- package/dist/esm/credentialIO.js +283 -0
- package/dist/esm/credentials.js +49 -0
- package/dist/esm/doctor.js +305 -0
- package/dist/esm/ensureDefaultAccounts.js +62 -0
- package/dist/esm/errorHistory.js +56 -0
- package/dist/esm/extractors/errorTaxonomy.js +43 -0
- package/dist/esm/extractors/gatherAssets.js +32 -0
- package/dist/esm/extractors/sessionAssets.js +176 -0
- package/dist/esm/extractors/sources/claudeAssets.js +158 -0
- package/dist/esm/extractors/sources/codexAssets.js +234 -0
- package/dist/esm/extractors/tokenUsage.js +41 -0
- package/dist/esm/extractors/toolCall.js +142 -0
- package/dist/esm/failingTools.js +65 -0
- package/dist/esm/fileHead.js +27 -0
- package/dist/esm/formatters/eventHighlighter.js +332 -0
- package/dist/esm/formatters/noiseClassifier.js +209 -0
- package/dist/esm/formatters/sessionDump.js +328 -0
- package/dist/esm/formatters/toolSummary.js +226 -0
- package/dist/esm/formatting.js +82 -0
- package/dist/esm/handoffUrl.js +23 -0
- package/dist/esm/historicalStore.js +305 -0
- package/dist/esm/humanPrompt.js +88 -0
- package/dist/esm/index.js +213 -0
- package/dist/esm/keepAlive.js +189 -0
- package/dist/esm/liveCredentialGuard.js +33 -0
- package/dist/esm/modelAliases.js +51 -0
- package/dist/esm/modelCatalog.js +139 -0
- package/dist/esm/modelContext.js +280 -0
- package/dist/esm/modelInfo.js +832 -0
- package/dist/esm/multiProviderQuotaService.js +450 -0
- package/dist/esm/node.js +46 -0
- package/dist/esm/observedContextWindows.js +165 -0
- package/dist/esm/observedSessionCollector.js +939 -0
- package/dist/esm/parsers/changelogParser.js +71 -0
- package/dist/esm/parsers/codexHistory.js +89 -0
- package/dist/esm/parsers/codexParser.js +906 -0
- package/dist/esm/parsers/debugLogParser.js +126 -0
- package/dist/esm/parsers/jsonl.js +66 -0
- package/dist/esm/parsers/mcpToolName.js +28 -0
- package/dist/esm/parsers/openCodeParser.js +625 -0
- package/dist/esm/parsers/planExtractor.js +335 -0
- package/dist/esm/parsers/sessionActivityDetector.js +246 -0
- package/dist/esm/parsers/sessionPathResolver.js +713 -0
- package/dist/esm/parsers/subagentScanner.js +360 -0
- package/dist/esm/parsers/subagentStatsCache.js +45 -0
- package/dist/esm/parsers/subagentTraceParser.js +325 -0
- package/dist/esm/paths.js +134 -0
- package/dist/esm/peakHours.js +194 -0
- package/dist/esm/phrases.js +1330 -0
- package/dist/esm/pricingCatalog.js +247 -0
- package/dist/esm/processDetection.js +200 -0
- package/dist/esm/projectMigration.js +59 -0
- package/dist/esm/promptHistory.js +1221 -0
- package/dist/esm/providerFailure.js +362 -0
- package/dist/esm/providerIds.js +6 -0
- package/dist/esm/providerQuota.js +1 -0
- package/dist/esm/providerServiceStatus.js +145 -0
- package/dist/esm/providerServiceStatusTypes.js +1 -0
- package/dist/esm/providerStatus.js +117 -0
- package/dist/esm/providers/claudeCode.js +575 -0
- package/dist/esm/providers/claudeListing.js +121 -0
- package/dist/esm/providers/codex.js +1034 -0
- package/dist/esm/providers/codexDatabase.js +297 -0
- package/dist/esm/providers/codexRollouts.js +215 -0
- package/dist/esm/providers/detect.js +185 -0
- package/dist/esm/providers/diagnostics.js +83 -0
- package/dist/esm/providers/directoryListingCache.js +206 -0
- package/dist/esm/providers/factory.js +54 -0
- package/dist/esm/providers/openCode.js +2008 -0
- package/dist/esm/providers/openCodeDatabase.js +419 -0
- package/dist/esm/providers/rolloutWalker.js +252 -0
- package/dist/esm/providers/types.js +12 -0
- package/dist/esm/quota.js +182 -0
- package/dist/esm/quotaHistory.js +364 -0
- package/dist/esm/quotaPoller.js +230 -0
- package/dist/esm/quotaPresentation.js +97 -0
- package/dist/esm/quotaResolver.js +231 -0
- package/dist/esm/quotaSnapshots.js +130 -0
- package/dist/esm/quotaThresholds.js +85 -0
- package/dist/esm/readers/decisions.js +24 -0
- package/dist/esm/readers/handoff.js +20 -0
- package/dist/esm/readers/helpers.js +27 -0
- package/dist/esm/readers/history.js +9 -0
- package/dist/esm/readers/notes.js +48 -0
- package/dist/esm/readers/plans.js +225 -0
- package/dist/esm/readers/tasks.js +19 -0
- package/dist/esm/report/htmlHelpers.js +280 -0
- package/dist/esm/report/htmlReportGenerator.js +704 -0
- package/dist/esm/report/index.js +7 -0
- package/dist/esm/report/logo.js +2 -0
- package/dist/esm/report/openBrowser.js +19 -0
- package/dist/esm/report/sessionReportInputs.js +33 -0
- package/dist/esm/report/transcriptParser.js +83 -0
- package/dist/esm/report/types.js +4 -0
- package/dist/esm/schemas/accountManager.js +204 -0
- package/dist/esm/schemas/accountStatus.js +25 -0
- package/dist/esm/schemas/assistantTurn.js +74 -0
- package/dist/esm/schemas/index.js +25 -0
- package/dist/esm/schemas/observedSessionV1.js +77 -0
- package/dist/esm/schemas/providerFailure.js +37 -0
- package/dist/esm/schemas/quota.js +132 -0
- package/dist/esm/schemas/quotaHistory.js +40 -0
- package/dist/esm/schemas/sessionEvent.js +216 -0
- package/dist/esm/schemas/stateFile.js +75 -0
- package/dist/esm/schemas/tokenEstimation.js +7 -0
- package/dist/esm/schemas/transcript.js +86 -0
- package/dist/esm/schemas/usageNormalization.js +38 -0
- package/dist/esm/search/advancedFilter.js +197 -0
- package/dist/esm/search/sessionSearch.js +66 -0
- package/dist/esm/sessionFingerprint.js +40 -0
- package/dist/esm/sessionMonitor.js +198 -0
- package/dist/esm/sessionPreviews.js +522 -0
- package/dist/esm/sessionPromptHistory.js +254 -0
- package/dist/esm/sessionPromptSignals.js +364 -0
- package/dist/esm/sessionStats.js +160 -0
- package/dist/esm/sessionTokenTotals.js +98 -0
- package/dist/esm/sessionTranscripts.js +49 -0
- package/dist/esm/stateFile.js +119 -0
- package/dist/esm/statusline/BurnRateCalculator.js +40 -0
- package/dist/esm/statusline/claudeStatuslinePayload.js +148 -0
- package/dist/esm/statusline/formatter.js +122 -0
- package/dist/esm/statusline/index.js +8 -0
- package/dist/esm/terminalSync.js +95 -0
- package/dist/esm/testing/credentialGuard.js +197 -0
- package/dist/esm/testing/index.js +12 -0
- package/dist/esm/testing/sessionLogFixtures.js +128 -0
- package/dist/esm/tokenEstimation.js +67 -0
- package/dist/esm/tokenSummary.js +113 -0
- package/dist/esm/toolCategory.js +82 -0
- package/dist/esm/transcript.js +257 -0
- package/dist/esm/turns/assistantTurn.js +373 -0
- package/dist/esm/types/codex.js +23 -0
- package/dist/esm/types/decisionLog.js +5 -0
- package/dist/esm/types/historicalData.js +47 -0
- package/dist/esm/types/knowledgeNote.js +15 -0
- package/dist/esm/types/observedSessionV1.js +257 -0
- package/dist/esm/types/opencode.js +12 -0
- package/dist/esm/types/plan.js +7 -0
- package/dist/esm/types/sessionEvent.js +10 -0
- package/dist/esm/types/taskPersistence.js +12 -0
- package/dist/esm/usage/billingBlocks.js +148 -0
- package/dist/esm/usage/claudeUsageDedupe.js +189 -0
- package/dist/esm/usage/importSessionHistory.js +84 -0
- package/dist/esm/usage/subagentUsage.js +18 -0
- package/dist/esm/usage/usageEvents.js +402 -0
- package/dist/esm/usage/usageReports.js +202 -0
- package/dist/esm/usageNormalization.js +95 -0
- package/dist/esm/watchers/eventBridge.js +219 -0
- package/dist/esm/watchers/factory.js +63 -0
- package/dist/esm/watchers/jsonlTail.js +289 -0
- package/dist/esm/watchers/jsonlWatcher.js +435 -0
- package/dist/esm/watchers/providerReaderWatcher.js +118 -0
- package/dist/esm/watchers/sqliteWatcher.js +285 -0
- package/dist/esm/watchers/types.js +4 -0
- package/dist/esm/workspaceRoots.js +56 -0
- package/dist/esm/writers/atomic.js +375 -0
- package/dist/esm/writers/decisions.js +51 -0
- package/dist/esm/writers/notes.js +46 -0
- package/dist/esm/writers/tasks.js +63 -0
- package/dist/esm/zaiQuota.js +323 -0
- package/dist/esm/zaiQuotaApi.js +271 -0
- package/dist/esm/zaiQuotaWatcher.js +265 -0
- package/dist/fileHead.d.ts +22 -0
- package/dist/fileHead.js +33 -0
- package/dist/index.d.ts +30 -11
- package/dist/index.js +72 -15
- package/dist/keepAlive.d.ts +2 -1
- package/dist/keepAlive.js +116 -29
- package/dist/liveCredentialGuard.d.ts +28 -0
- package/dist/liveCredentialGuard.js +36 -0
- package/dist/node.d.ts +13 -1
- package/dist/node.js +43 -2
- package/dist/parsers/codexHistory.js +2 -2
- package/dist/parsers/codexParser.d.ts +12 -0
- package/dist/parsers/codexParser.js +34 -12
- package/dist/parsers/debugLogParser.js +2 -2
- package/dist/parsers/sessionPathResolver.js +5 -4
- package/dist/processDetection.d.ts +10 -3
- package/dist/processDetection.js +44 -11
- package/dist/promptHistory.d.ts +32 -0
- package/dist/promptHistory.js +115 -59
- package/dist/providerFailure.d.ts +12 -6
- package/dist/providerFailure.js +45 -0
- package/dist/providers/claudeCode.js +7 -99
- package/dist/providers/claudeListing.d.ts +22 -0
- package/dist/providers/claudeListing.js +158 -0
- package/dist/providers/codex.d.ts +3 -1
- package/dist/providers/codex.js +26 -227
- package/dist/providers/codexRollouts.d.ts +44 -0
- package/dist/providers/codexRollouts.js +261 -0
- package/dist/providers/detect.js +4 -4
- package/dist/readers/plans.js +3 -3
- package/dist/schemas/accountManager.d.ts +22 -0
- package/dist/schemas/accountManager.js +4 -0
- package/dist/schemas/assistantTurn.d.ts +2 -2
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/providerFailure.d.ts +154 -0
- package/dist/schemas/providerFailure.js +40 -0
- package/dist/sessionPromptHistory.d.ts +12 -7
- package/dist/sessionPromptHistory.js +15 -3
- package/dist/sessionPromptSignals.d.ts +9 -0
- package/dist/sessionPromptSignals.js +13 -0
- package/dist/terminalSync.d.ts +12 -2
- package/dist/terminalSync.js +27 -2
- package/dist/testing/credentialGuard.d.ts +23 -0
- package/dist/testing/credentialGuard.js +233 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/sessionLogFixtures.d.ts +28 -0
- package/dist/testing/sessionLogFixtures.js +169 -0
- package/dist/tokenEstimation.d.ts +2 -0
- package/dist/tokenEstimation.js +21 -11
- package/dist/toolCategory.d.ts +18 -0
- package/dist/toolCategory.js +86 -0
- package/dist/types/codex.d.ts +4 -0
- package/dist/usage/usageEvents.d.ts +16 -0
- package/dist/usage/usageEvents.js +53 -9
- package/dist/watchers/jsonlTail.d.ts +26 -1
- package/dist/watchers/jsonlTail.js +136 -28
- package/dist/watchers/jsonlWatcher.js +7 -0
- package/dist/watchers/providerReaderWatcher.js +1 -0
- package/dist/watchers/types.d.ts +6 -0
- package/dist/workspaceRoots.d.ts +23 -0
- package/dist/workspaceRoots.js +93 -0
- package/package.json +22 -2
|
@@ -37,11 +37,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
};
|
|
38
38
|
})();
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.DEFAULT_JSONL_TAIL_MAX_LINE_BYTES = exports.DEFAULT_JSONL_TAIL_READ_BYTES = void 0;
|
|
40
41
|
exports.createJsonlTail = createJsonlTail;
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
43
|
+
const fileHead_1 = require("../fileHead");
|
|
42
44
|
const jsonl_1 = require("../parsers/jsonl");
|
|
43
45
|
const DEFAULT_DEBOUNCE_MS = 100;
|
|
44
46
|
const DEFAULT_CATCHUP_INTERVAL_MS = 30_000;
|
|
47
|
+
/** Default bytes read from the file per chunk. */
|
|
48
|
+
exports.DEFAULT_JSONL_TAIL_READ_BYTES = 1024 * 1024;
|
|
49
|
+
/** Default longest line parsed; longer lines are skipped and reported. */
|
|
50
|
+
exports.DEFAULT_JSONL_TAIL_MAX_LINE_BYTES = 16 * 1024 * 1024;
|
|
45
51
|
/** Skip old complete events while retaining an in-progress final line. */
|
|
46
52
|
function lastCompleteLineOffset(filePath) {
|
|
47
53
|
const fd = fs.openSync(filePath, 'r');
|
|
@@ -73,6 +79,15 @@ class JsonlTailReader {
|
|
|
73
79
|
/** Resume-safe byte position ending immediately after a newline. */
|
|
74
80
|
committedOffset;
|
|
75
81
|
pendingBytes = Buffer.alloc(0);
|
|
82
|
+
/** Inside a line over `maxLineBytes`: drop bytes until its newline. */
|
|
83
|
+
skippingLine = false;
|
|
84
|
+
currentLine = { offset: 0, length: 0 };
|
|
85
|
+
/** Identity and prefix of the file the offsets refer to, once read. */
|
|
86
|
+
identity = null;
|
|
87
|
+
head = null;
|
|
88
|
+
lastMtimeMs = -1;
|
|
89
|
+
maxReadBytes;
|
|
90
|
+
maxLineBytes;
|
|
76
91
|
fsWatcher = null;
|
|
77
92
|
debounceTimer = null;
|
|
78
93
|
catchupTimer = null;
|
|
@@ -82,10 +97,12 @@ class JsonlTailReader {
|
|
|
82
97
|
this.options = options;
|
|
83
98
|
this.readOffset = options.startOffset ?? 0;
|
|
84
99
|
this.committedOffset = this.readOffset;
|
|
100
|
+
this.maxReadBytes = positiveInteger(options.maxReadBytes, exports.DEFAULT_JSONL_TAIL_READ_BYTES);
|
|
101
|
+
this.maxLineBytes = positiveInteger(options.maxLineBytes, exports.DEFAULT_JSONL_TAIL_MAX_LINE_BYTES);
|
|
85
102
|
this.parser = new jsonl_1.JsonlParser({
|
|
86
103
|
onEvent: (event) => {
|
|
87
104
|
this.eventsInCurrentBatch += 1;
|
|
88
|
-
this.options.onEvent(event);
|
|
105
|
+
this.options.onEvent(event, this.currentLine);
|
|
89
106
|
},
|
|
90
107
|
onError: (error, line) => this.options.onError?.(error, line),
|
|
91
108
|
}, { schema: options.schema });
|
|
@@ -137,36 +154,25 @@ class JsonlTailReader {
|
|
|
137
154
|
readNow() {
|
|
138
155
|
let fd = null;
|
|
139
156
|
try {
|
|
140
|
-
const stat = fs.statSync(this.options.path);
|
|
141
|
-
if (stat.size < this.readOffset) {
|
|
142
|
-
this.readOffset = 0;
|
|
143
|
-
this.committedOffset = 0;
|
|
144
|
-
this.pendingBytes = Buffer.alloc(0);
|
|
145
|
-
this.parser.reset();
|
|
146
|
-
}
|
|
147
|
-
if (stat.size <= this.readOffset)
|
|
148
|
-
return;
|
|
149
|
-
const bytesToRead = stat.size - this.readOffset;
|
|
150
|
-
const buffer = Buffer.alloc(bytesToRead);
|
|
151
157
|
fd = fs.openSync(this.options.path, 'r');
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (bytesRead <= 0)
|
|
158
|
+
const stat = fs.fstatSync(fd);
|
|
159
|
+
this.checkContinuity(fd, stat);
|
|
160
|
+
if (stat.size <= this.readOffset)
|
|
156
161
|
return;
|
|
157
|
-
this.readOffset += bytesRead;
|
|
158
162
|
this.eventsInCurrentBatch = 0;
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
this.
|
|
163
|
+
let bytesRead = 0;
|
|
164
|
+
const chunk = Buffer.alloc(Math.min(this.maxReadBytes, stat.size - this.readOffset));
|
|
165
|
+
while (this.readOffset < stat.size) {
|
|
166
|
+
const want = Math.min(chunk.length, stat.size - this.readOffset);
|
|
167
|
+
const count = fs.readSync(fd, chunk, 0, want, this.readOffset);
|
|
168
|
+
if (count <= 0)
|
|
169
|
+
break;
|
|
170
|
+
this.consume(chunk.subarray(0, count), this.readOffset);
|
|
171
|
+
this.readOffset += count;
|
|
172
|
+
bytesRead += count;
|
|
168
173
|
}
|
|
169
|
-
|
|
174
|
+
if (bytesRead <= 0)
|
|
175
|
+
return;
|
|
170
176
|
this.options.onBatchComplete?.({
|
|
171
177
|
bytesRead,
|
|
172
178
|
eventsRead: this.eventsInCurrentBatch,
|
|
@@ -174,6 +180,9 @@ class JsonlTailReader {
|
|
|
174
180
|
});
|
|
175
181
|
}
|
|
176
182
|
catch (error) {
|
|
183
|
+
this.options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
177
186
|
if (fd !== null) {
|
|
178
187
|
try {
|
|
179
188
|
fs.closeSync(fd);
|
|
@@ -182,9 +191,97 @@ class JsonlTailReader {
|
|
|
182
191
|
/* ignore close errors */
|
|
183
192
|
}
|
|
184
193
|
}
|
|
185
|
-
this.options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
186
194
|
}
|
|
187
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Starts over when the path now names another file, the file shrank, its
|
|
198
|
+
* first bytes changed, or the resume point no longer follows a newline.
|
|
199
|
+
*/
|
|
200
|
+
checkContinuity(fd, stat) {
|
|
201
|
+
let reason = null;
|
|
202
|
+
if (this.identity && (stat.dev !== this.identity.dev || stat.ino !== this.identity.ino)) {
|
|
203
|
+
reason = 'replaced';
|
|
204
|
+
}
|
|
205
|
+
else if (stat.size < this.readOffset) {
|
|
206
|
+
reason = 'truncated';
|
|
207
|
+
}
|
|
208
|
+
if (reason === null && this.identity && stat.mtimeMs !== this.lastMtimeMs) {
|
|
209
|
+
const prefix = readAt(fd, 0, Math.min(fileHead_1.HEAD_BYTES, stat.size));
|
|
210
|
+
const before = this.committedOffset > 0 ? readAt(fd, this.committedOffset - 1, 1) : null;
|
|
211
|
+
if ((this.head && !(0, fileHead_1.headMatches)(this.head, prefix)) || (before && before[0] !== 0x0a)) {
|
|
212
|
+
reason = 'rewritten';
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (reason !== null)
|
|
216
|
+
this.reset(reason);
|
|
217
|
+
this.identity = { dev: stat.dev, ino: stat.ino };
|
|
218
|
+
this.lastMtimeMs = stat.mtimeMs;
|
|
219
|
+
if (!this.head || this.head.bytes < Math.min(fileHead_1.HEAD_BYTES, stat.size)) {
|
|
220
|
+
this.head = (0, fileHead_1.fileHeadOf)(readAt(fd, 0, Math.min(fileHead_1.HEAD_BYTES, stat.size)));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
reset(reason) {
|
|
224
|
+
const previousOffset = this.committedOffset;
|
|
225
|
+
this.readOffset = 0;
|
|
226
|
+
this.committedOffset = 0;
|
|
227
|
+
this.pendingBytes = Buffer.alloc(0);
|
|
228
|
+
this.skippingLine = false;
|
|
229
|
+
this.head = null;
|
|
230
|
+
this.parser.reset();
|
|
231
|
+
if (reason === 'replaced' && this.active) {
|
|
232
|
+
// fs.watch follows the old inode; watch the file now at the path.
|
|
233
|
+
this.fsWatcher?.close();
|
|
234
|
+
this.fsWatcher = null;
|
|
235
|
+
this.watchFile();
|
|
236
|
+
}
|
|
237
|
+
this.options.onReset?.({ reason, previousOffset });
|
|
238
|
+
}
|
|
239
|
+
/** Parses the complete lines in `bytes`, which start at file offset `position`. */
|
|
240
|
+
consume(bytes, position) {
|
|
241
|
+
let start = 0;
|
|
242
|
+
if (this.skippingLine) {
|
|
243
|
+
const newline = bytes.indexOf(0x0a);
|
|
244
|
+
if (newline < 0)
|
|
245
|
+
return;
|
|
246
|
+
this.skippingLine = false;
|
|
247
|
+
start = newline + 1;
|
|
248
|
+
this.committedOffset = position + start;
|
|
249
|
+
}
|
|
250
|
+
let lineStart = this.committedOffset;
|
|
251
|
+
let cursor = start;
|
|
252
|
+
for (;;) {
|
|
253
|
+
const newline = bytes.indexOf(0x0a, cursor);
|
|
254
|
+
if (newline < 0)
|
|
255
|
+
break;
|
|
256
|
+
const piece = bytes.subarray(cursor, newline);
|
|
257
|
+
const line = this.pendingBytes.length > 0 ? Buffer.concat([this.pendingBytes, piece]) : piece;
|
|
258
|
+
this.pendingBytes = Buffer.alloc(0);
|
|
259
|
+
const lineEnd = position + newline + 1;
|
|
260
|
+
if (line.length > this.maxLineBytes) {
|
|
261
|
+
this.reportOversized(lineStart, line.length);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
this.currentLine = { offset: lineStart, length: line.length };
|
|
265
|
+
this.parser.processChunk(line.toString('utf8') + '\n');
|
|
266
|
+
}
|
|
267
|
+
this.committedOffset = lineEnd;
|
|
268
|
+
lineStart = lineEnd;
|
|
269
|
+
cursor = newline + 1;
|
|
270
|
+
}
|
|
271
|
+
const rest = bytes.subarray(cursor);
|
|
272
|
+
if (rest.length === 0)
|
|
273
|
+
return;
|
|
274
|
+
if (this.pendingBytes.length + rest.length > this.maxLineBytes) {
|
|
275
|
+
this.reportOversized(lineStart, this.pendingBytes.length + rest.length);
|
|
276
|
+
this.pendingBytes = Buffer.alloc(0);
|
|
277
|
+
this.skippingLine = true;
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this.pendingBytes = Buffer.concat([this.pendingBytes, rest]);
|
|
281
|
+
}
|
|
282
|
+
reportOversized(offset, atLeast) {
|
|
283
|
+
this.options.onError?.(new Error(`JSONL line at byte ${offset} is over ${this.maxLineBytes} bytes (${atLeast} so far); skipped.`));
|
|
284
|
+
}
|
|
188
285
|
getOffset() {
|
|
189
286
|
return this.committedOffset;
|
|
190
287
|
}
|
|
@@ -192,6 +289,7 @@ class JsonlTailReader {
|
|
|
192
289
|
this.readOffset = Math.max(0, offset);
|
|
193
290
|
this.committedOffset = this.readOffset;
|
|
194
291
|
this.pendingBytes = Buffer.alloc(0);
|
|
292
|
+
this.skippingLine = false;
|
|
195
293
|
this.parser.reset();
|
|
196
294
|
}
|
|
197
295
|
watchFile() {
|
|
@@ -216,3 +314,13 @@ class JsonlTailReader {
|
|
|
216
314
|
this.debounceTimer = setTimeout(() => this.readNow(), debounceMs);
|
|
217
315
|
}
|
|
218
316
|
}
|
|
317
|
+
function positiveInteger(value, fallback) {
|
|
318
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 1
|
|
319
|
+
? Math.floor(value)
|
|
320
|
+
: fallback;
|
|
321
|
+
}
|
|
322
|
+
function readAt(fd, position, length) {
|
|
323
|
+
const buffer = Buffer.alloc(length);
|
|
324
|
+
const count = length > 0 ? fs.readSync(fd, buffer, 0, length, position) : 0;
|
|
325
|
+
return buffer.subarray(0, count);
|
|
326
|
+
}
|
|
@@ -240,6 +240,13 @@ class JsonlSessionWatcher {
|
|
|
240
240
|
onEvent: (event) => this.handleRawEvent(event),
|
|
241
241
|
onBatchComplete: () => this.callbacks.onBatchComplete?.(),
|
|
242
242
|
onError: (error) => this.callbacks.onError?.(error),
|
|
243
|
+
// The file starts over, so per-file state from the old content must go too.
|
|
244
|
+
onReset: () => {
|
|
245
|
+
this.codexInPlanMode = false;
|
|
246
|
+
this.claudeUsageDeduper.reset();
|
|
247
|
+
this.codexPrevTotal = undefined;
|
|
248
|
+
this.callbacks.onReset?.();
|
|
249
|
+
},
|
|
243
250
|
});
|
|
244
251
|
this.tail.start();
|
|
245
252
|
}
|
package/dist/watchers/types.d.ts
CHANGED
|
@@ -54,6 +54,12 @@ export interface SessionWatcherCallbacks {
|
|
|
54
54
|
/** All events in this read have been delivered; the cursor can now be checkpointed. */
|
|
55
55
|
onBatchComplete?: () => void;
|
|
56
56
|
onError?: (error: Error) => void;
|
|
57
|
+
/**
|
|
58
|
+
* The session file was truncated, rewritten, or replaced, and its events
|
|
59
|
+
* are being delivered again from the beginning: discard anything built
|
|
60
|
+
* from earlier events.
|
|
61
|
+
*/
|
|
62
|
+
onReset?: () => void;
|
|
57
63
|
}
|
|
58
64
|
export interface SessionWatcher {
|
|
59
65
|
/** Start watching. If replay=true, emit existing events before streaming. */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace-root expansion shared by the session readers: realpath each root
|
|
3
|
+
* and, optionally, add its git worktree siblings.
|
|
4
|
+
*
|
|
5
|
+
* @module workspaceRoots
|
|
6
|
+
*/
|
|
7
|
+
export interface ResolveWorkspaceRootsOptions {
|
|
8
|
+
/** Add the main checkout and every git worktree of each root. Default true. */
|
|
9
|
+
includeWorktrees?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ResolvedWorkspaceRoots {
|
|
12
|
+
/** Realpaths of the roots, after worktree expansion; scope checks use these. */
|
|
13
|
+
roots: string[];
|
|
14
|
+
/** The roots plus their unresolved spellings, for listing session files. */
|
|
15
|
+
listingRoots: string[];
|
|
16
|
+
}
|
|
17
|
+
/** Realpath of an absolute path, or null when it does not resolve. */
|
|
18
|
+
export declare function realpathOrNull(input: string, cache?: Map<string, string | null>): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Realpaths each absolute root and, by default, adds its main checkout and
|
|
21
|
+
* git worktree siblings. Relative and unresolvable roots are dropped.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveWorkspaceRoots(workspacePaths: string[], options?: ResolveWorkspaceRootsOptions, realpaths?: Map<string, string | null>): ResolvedWorkspaceRoots;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Workspace-root expansion shared by the session readers: realpath each root
|
|
4
|
+
* and, optionally, add its git worktree siblings.
|
|
5
|
+
*
|
|
6
|
+
* @module workspaceRoots
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.realpathOrNull = realpathOrNull;
|
|
43
|
+
exports.resolveWorkspaceRoots = resolveWorkspaceRoots;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const sessionPathResolver_1 = require("./parsers/sessionPathResolver");
|
|
47
|
+
/** Realpath of an absolute path, or null when it does not resolve. */
|
|
48
|
+
function realpathOrNull(input, cache = new Map()) {
|
|
49
|
+
const cached = cache.get(input);
|
|
50
|
+
if (cached !== undefined)
|
|
51
|
+
return cached;
|
|
52
|
+
let resolved = null;
|
|
53
|
+
try {
|
|
54
|
+
resolved = path.isAbsolute(input) ? fs.realpathSync.native(input) : null;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
resolved = null;
|
|
58
|
+
}
|
|
59
|
+
cache.set(input, resolved);
|
|
60
|
+
return resolved;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Realpaths each absolute root and, by default, adds its main checkout and
|
|
64
|
+
* git worktree siblings. Relative and unresolvable roots are dropped.
|
|
65
|
+
*/
|
|
66
|
+
function resolveWorkspaceRoots(workspacePaths, options = {}, realpaths = new Map()) {
|
|
67
|
+
const includeWorktrees = options.includeWorktrees !== false;
|
|
68
|
+
const roots = new Set();
|
|
69
|
+
const listingRoots = new Set();
|
|
70
|
+
const add = (candidate) => {
|
|
71
|
+
const real = realpathOrNull(candidate, realpaths);
|
|
72
|
+
if (!real)
|
|
73
|
+
return;
|
|
74
|
+
roots.add(real);
|
|
75
|
+
listingRoots.add(real);
|
|
76
|
+
listingRoots.add(path.resolve(candidate));
|
|
77
|
+
};
|
|
78
|
+
for (const workspacePath of workspacePaths) {
|
|
79
|
+
if (typeof workspacePath !== 'string' || !path.isAbsolute(workspacePath))
|
|
80
|
+
continue;
|
|
81
|
+
add(workspacePath);
|
|
82
|
+
if (!includeWorktrees)
|
|
83
|
+
continue;
|
|
84
|
+
const real = realpathOrNull(workspacePath, realpaths);
|
|
85
|
+
if (!real)
|
|
86
|
+
continue;
|
|
87
|
+
const mainRepo = (0, sessionPathResolver_1.resolveWorktreeMainRepo)(real) ?? real;
|
|
88
|
+
add(mainRepo);
|
|
89
|
+
for (const sibling of (0, sessionPathResolver_1.discoverWorktreeSiblings)(mainRepo))
|
|
90
|
+
add(sibling);
|
|
91
|
+
}
|
|
92
|
+
return { roots: [...roots], listingRoots: [...listingRoots] };
|
|
93
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sidekick-shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Shared data access layer for Sidekick — readers, types, providers, credentials, quota",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -35,58 +35,75 @@
|
|
|
35
35
|
"exports": {
|
|
36
36
|
".": {
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
38
|
+
"module": "./dist/esm/index.js",
|
|
38
39
|
"import": "./dist/index.js",
|
|
39
40
|
"require": "./dist/index.js",
|
|
40
41
|
"default": "./dist/index.js"
|
|
41
42
|
},
|
|
42
43
|
"./browser": {
|
|
43
44
|
"types": "./dist/browser.d.ts",
|
|
45
|
+
"module": "./dist/esm/browser.js",
|
|
44
46
|
"import": "./dist/browser.js",
|
|
45
47
|
"require": "./dist/browser.js",
|
|
46
48
|
"default": "./dist/browser.js"
|
|
47
49
|
},
|
|
48
50
|
"./node": {
|
|
49
51
|
"types": "./dist/node.d.ts",
|
|
52
|
+
"module": "./dist/esm/node.js",
|
|
50
53
|
"import": "./dist/node.js",
|
|
51
54
|
"require": "./dist/node.js",
|
|
52
55
|
"default": "./dist/node.js"
|
|
53
56
|
},
|
|
54
57
|
"./schemas": {
|
|
55
58
|
"types": "./dist/schemas/index.d.ts",
|
|
59
|
+
"module": "./dist/esm/schemas/index.js",
|
|
56
60
|
"import": "./dist/schemas/index.js",
|
|
57
61
|
"require": "./dist/schemas/index.js",
|
|
58
62
|
"default": "./dist/schemas/index.js"
|
|
59
63
|
},
|
|
60
64
|
"./phrases": {
|
|
61
65
|
"types": "./dist/phrases.d.ts",
|
|
66
|
+
"module": "./dist/esm/phrases.js",
|
|
62
67
|
"import": "./dist/phrases.js",
|
|
63
68
|
"require": "./dist/phrases.js",
|
|
64
69
|
"default": "./dist/phrases.js"
|
|
65
70
|
},
|
|
66
71
|
"./modelContext": {
|
|
67
72
|
"types": "./dist/modelContext.d.ts",
|
|
73
|
+
"module": "./dist/esm/modelContext.js",
|
|
68
74
|
"import": "./dist/modelContext.js",
|
|
69
75
|
"require": "./dist/modelContext.js",
|
|
70
76
|
"default": "./dist/modelContext.js"
|
|
71
77
|
},
|
|
72
78
|
"./modelInfo": {
|
|
73
79
|
"types": "./dist/modelInfo.d.ts",
|
|
80
|
+
"module": "./dist/esm/modelInfo.js",
|
|
74
81
|
"import": "./dist/modelInfo.js",
|
|
75
82
|
"require": "./dist/modelInfo.js",
|
|
76
83
|
"default": "./dist/modelInfo.js"
|
|
77
84
|
},
|
|
78
85
|
"./formatting": {
|
|
79
86
|
"types": "./dist/formatting.d.ts",
|
|
87
|
+
"module": "./dist/esm/formatting.js",
|
|
80
88
|
"import": "./dist/formatting.js",
|
|
81
89
|
"require": "./dist/formatting.js",
|
|
82
90
|
"default": "./dist/formatting.js"
|
|
83
91
|
},
|
|
84
92
|
"./statusline": {
|
|
85
93
|
"types": "./dist/statusline/index.d.ts",
|
|
94
|
+
"module": "./dist/esm/statusline/index.js",
|
|
86
95
|
"import": "./dist/statusline/index.js",
|
|
87
96
|
"require": "./dist/statusline/index.js",
|
|
88
97
|
"default": "./dist/statusline/index.js"
|
|
89
98
|
},
|
|
99
|
+
"./testing": {
|
|
100
|
+
"types": "./dist/testing/index.d.ts",
|
|
101
|
+
"module": "./dist/esm/testing/index.js",
|
|
102
|
+
"import": "./dist/testing/index.js",
|
|
103
|
+
"require": "./dist/testing/index.js",
|
|
104
|
+
"default": "./dist/testing/index.js"
|
|
105
|
+
},
|
|
106
|
+
"./dist/esm/*": null,
|
|
90
107
|
"./dist/*": {
|
|
91
108
|
"types": "./dist/*.d.ts",
|
|
92
109
|
"import": "./dist/*.js",
|
|
@@ -120,6 +137,9 @@
|
|
|
120
137
|
],
|
|
121
138
|
"statusline": [
|
|
122
139
|
"dist/statusline/index.d.ts"
|
|
140
|
+
],
|
|
141
|
+
"testing": [
|
|
142
|
+
"dist/testing/index.d.ts"
|
|
123
143
|
]
|
|
124
144
|
}
|
|
125
145
|
},
|
|
@@ -133,7 +153,7 @@
|
|
|
133
153
|
"access": "public"
|
|
134
154
|
},
|
|
135
155
|
"scripts": {
|
|
136
|
-
"build": "tsc",
|
|
156
|
+
"build": "tsc && tsc -p tsconfig.esm.json",
|
|
137
157
|
"clean": "rm -rf dist",
|
|
138
158
|
"lint": "eslint src/",
|
|
139
159
|
"lint:fix": "eslint src/ --fix",
|