@adhdev/daemon-core 0.9.82-rc.144 → 0.9.82-rc.145
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/index.js +80 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -45
- package/dist/index.mjs.map +1 -1
- package/dist/providers/contracts.d.ts +23 -5
- package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +9 -0
- package/dist/providers/sdk/v1/index.d.ts +1 -1
- package/dist/providers/sdk/v1/types/cli/index.d.ts +11 -2
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +13 -13
- package/src/commands/router.ts +1 -1
- package/src/providers/cli-provider-instance.ts +3 -3
- package/src/providers/contracts.ts +25 -5
- package/src/providers/provider-loader.ts +14 -9
- package/src/providers/provider-schema.ts +21 -18
- package/src/providers/sdk/v1/builders/cli/parse-session.ts +30 -1
- package/src/providers/sdk/v1/index.ts +1 -0
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +23 -7
- package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
- package/src/providers/sdk/v1/types/cli/index.ts +13 -3
|
@@ -445,8 +445,16 @@ export interface ProviderModule {
|
|
|
445
445
|
/** History behavior config — controls message filtering and collapse during replay */
|
|
446
446
|
historyBehavior?: ProviderHistoryBehavior;
|
|
447
447
|
/**
|
|
448
|
-
*
|
|
449
|
-
* When set, daemon
|
|
448
|
+
* Native history config — for providers that maintain native history files.
|
|
449
|
+
* When set, daemon reads/lists provider-native transcripts directly. This is
|
|
450
|
+
* the canonical v1 field name; the legacy `canonicalHistory` field name is
|
|
451
|
+
* still accepted by the loader and aliased onto this field at load time.
|
|
452
|
+
*/
|
|
453
|
+
nativeHistory?: NativeHistoryConfig;
|
|
454
|
+
/**
|
|
455
|
+
* @deprecated Legacy v0 alias for {@link ProviderModule.nativeHistory}.
|
|
456
|
+
* Loader populates this from `nativeHistory` so existing internal readers
|
|
457
|
+
* keep working during the transition. Remove after one release.
|
|
450
458
|
*/
|
|
451
459
|
canonicalHistory?: ProviderCanonicalHistoryConfig;
|
|
452
460
|
/**
|
|
@@ -577,20 +585,25 @@ export interface ProviderHistoryBehavior {
|
|
|
577
585
|
* daemon-core. They let each provider own native transcript file discovery and
|
|
578
586
|
* parsing while daemon-core only validates/pages the normalized result.
|
|
579
587
|
*/
|
|
580
|
-
export interface
|
|
588
|
+
export interface NativeHistoryScriptsConfig {
|
|
581
589
|
/** Reads one native session. Default: 'readNativeHistory'. */
|
|
582
590
|
readSession?: string;
|
|
583
591
|
/** Lists native sessions with summary metadata. Default: 'listNativeHistory'. */
|
|
584
592
|
listSessions?: string;
|
|
585
593
|
}
|
|
586
594
|
/**
|
|
587
|
-
*
|
|
595
|
+
* @deprecated Use {@link NativeHistoryScriptsConfig}. Retained as an alias for
|
|
596
|
+
* one release so external consumers that referenced the old name keep compiling.
|
|
597
|
+
*/
|
|
598
|
+
export type ProviderCanonicalHistoryScriptsConfig = NativeHistoryScriptsConfig;
|
|
599
|
+
/**
|
|
600
|
+
* Native history config — for providers that maintain their own native history files.
|
|
588
601
|
*
|
|
589
602
|
* Preferred mode is provider-owned scripts via `scripts`. `format` is now an
|
|
590
603
|
* opaque provider label retained for diagnostics/backward compatibility; daemon
|
|
591
604
|
* live paths must not branch on provider-specific format values.
|
|
592
605
|
*/
|
|
593
|
-
export interface
|
|
606
|
+
export interface NativeHistoryConfig {
|
|
594
607
|
/** Opaque provider-owned history format label. */
|
|
595
608
|
format?: string;
|
|
596
609
|
/** Optional native history glob/template for diagnostics only. */
|
|
@@ -618,6 +631,11 @@ export interface ProviderCanonicalHistoryConfig {
|
|
|
618
631
|
*/
|
|
619
632
|
contractVersion?: import('./transcript-v2.js').ChatContractVersion;
|
|
620
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* @deprecated Use {@link NativeHistoryConfig}. Retained as an alias for one
|
|
636
|
+
* release so external consumers that referenced the old name keep compiling.
|
|
637
|
+
*/
|
|
638
|
+
export type ProviderCanonicalHistoryConfig = NativeHistoryConfig;
|
|
621
639
|
/**
|
|
622
640
|
* Auto-implement spawn config — controls how the provider is spawned for autonomous AI-driven
|
|
623
641
|
* provider script implementation (dev-auto-implement.ts).
|
|
@@ -40,12 +40,20 @@ export interface TranscriptPtySpec {
|
|
|
40
40
|
stripLeadingChrome?: boolean;
|
|
41
41
|
scope?: 'screen' | 'buffer' | 'tail';
|
|
42
42
|
}
|
|
43
|
+
export interface SessionIdExtractionSpec {
|
|
44
|
+
$schema?: 'adhdev:tui/session-id-extraction@1';
|
|
45
|
+
regex: string;
|
|
46
|
+
flags?: string;
|
|
47
|
+
scope?: 'screen' | 'tail' | 'buffer';
|
|
48
|
+
label?: string;
|
|
49
|
+
}
|
|
43
50
|
export interface ParseSessionTuiSpec {
|
|
44
51
|
spinner?: any;
|
|
45
52
|
settledPrompt?: any;
|
|
46
53
|
modal?: ModalTuiSpec;
|
|
47
54
|
dispatchOrder?: any;
|
|
48
55
|
transcriptPty: TranscriptPtySpec;
|
|
56
|
+
sessionIdExtraction?: SessionIdExtractionSpec;
|
|
49
57
|
}
|
|
50
58
|
export interface SynthesizedMessage {
|
|
51
59
|
role: 'user' | 'assistant';
|
|
@@ -67,6 +75,7 @@ export interface SynthesizedSession {
|
|
|
67
75
|
parsedStatus: string | null;
|
|
68
76
|
transcriptAuthority?: 'provider' | 'daemon';
|
|
69
77
|
coverage?: 'full' | 'tail' | 'current-turn';
|
|
78
|
+
providerSessionId?: string;
|
|
70
79
|
}
|
|
71
80
|
export declare function normalizeMessageIdentity<T extends {
|
|
72
81
|
role?: string;
|
|
@@ -12,7 +12,7 @@ export { buildDetectStatusFromTui, type DetectStatusTuiSpec, } from './builders/
|
|
|
12
12
|
export { buildParseApprovalFromTui, type ModalTuiSpec, } from './builders/cli/parse-approval.js';
|
|
13
13
|
export { applyVisibleRegion, type VisibleRegionSpec, } from './builders/cli/visible-region.js';
|
|
14
14
|
export { buildParseApprovalFromSquash, compactText, type ApprovalSquashSpec, } from './builders/cli/parse-approval-squash.js';
|
|
15
|
-
export { buildParseSessionFromTui, normalizeMessageIdentity, type ParseSessionTuiSpec, type TranscriptPtySpec, type SynthesizedMessage, type SynthesizedSession, } from './builders/cli/parse-session.js';
|
|
15
|
+
export { buildParseSessionFromTui, normalizeMessageIdentity, type ParseSessionTuiSpec, type TranscriptPtySpec, type SessionIdExtractionSpec, type SynthesizedMessage, type SynthesizedSession, } from './builders/cli/parse-session.js';
|
|
16
16
|
export { buildDetectStatusFromAcp, type AcpSessionSpec, type AcpStatusInput, type AcpDetectedStatus, } from './builders/acp/detect-status.js';
|
|
17
17
|
export { loadFixtureExpected, replayFixture, formatReplayReport, type FixtureExpected, type FixtureAnchor, type MessageShape, type AnchorReplayResult, type FixtureReplayResult, type CliProviderHandlers, type ReplayOptions, } from './fixture-tooling/index.js';
|
|
18
18
|
export { analyzeOverrideTaint, formatTaintResult, type TaintLevel, type TaintCategory, type TaintFinding, type TaintResult, validateCliProviderManifest, formatManifestValidationIssues, type ManifestValidationIssue, type ManifestValidationResult, } from './validators/index.js';
|
|
@@ -191,7 +191,9 @@ export interface CliListNativeHistoryEntry {
|
|
|
191
191
|
export type CliListNativeHistoryFn = () => {
|
|
192
192
|
sessions: CliListNativeHistoryEntry[];
|
|
193
193
|
};
|
|
194
|
-
export interface
|
|
194
|
+
export interface CliNativeHistoryDef {
|
|
195
|
+
/** Built-in adapter $schema (e.g. "adhdev:native-history/claude-jsonl@1"). */
|
|
196
|
+
$schema?: string;
|
|
195
197
|
format: string;
|
|
196
198
|
watchPath: string;
|
|
197
199
|
mode: 'native-source' | 'daemon-mirror';
|
|
@@ -201,6 +203,11 @@ export interface CliCanonicalHistoryDef {
|
|
|
201
203
|
listSessions?: string;
|
|
202
204
|
};
|
|
203
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* @deprecated Use {@link CliNativeHistoryDef}. Retained as an alias for one
|
|
208
|
+
* release so SDK consumers that referenced the v0 name keep compiling.
|
|
209
|
+
*/
|
|
210
|
+
export type CliCanonicalHistoryDef = CliNativeHistoryDef;
|
|
204
211
|
export interface CliPatternEntry {
|
|
205
212
|
source: string;
|
|
206
213
|
flags?: string;
|
|
@@ -259,7 +266,9 @@ export interface CliProviderManifest {
|
|
|
259
266
|
capabilities?: CapabilitiesDef;
|
|
260
267
|
/** Mesh coordinator setup */
|
|
261
268
|
meshCoordinator?: MeshCoordinatorDef;
|
|
262
|
-
/** Native history */
|
|
269
|
+
/** Native history (v1 canonical field name) */
|
|
270
|
+
nativeHistory?: CliNativeHistoryDef;
|
|
271
|
+
/** @deprecated v0 alias for `nativeHistory`. */
|
|
263
272
|
canonicalHistory?: CliCanonicalHistoryDef;
|
|
264
273
|
/** Settings (UI toggles persisted to ~/.adhdev/config.json) */
|
|
265
274
|
settings?: SettingsDef;
|
package/package.json
CHANGED
|
@@ -904,7 +904,7 @@ function supportsCliNativeTranscript(providerType: string, provider?: ProviderMo
|
|
|
904
904
|
// provider.json. We trust that declaration regardless of the legacy
|
|
905
905
|
// allow-list. A2 will additionally require canonicalHistory.contractVersion
|
|
906
906
|
// to be a supported value (transcript-v2.ts).
|
|
907
|
-
if (provider?.category === 'cli' && isNativeSourceCanonicalHistory(provider?.
|
|
907
|
+
if (provider?.category === 'cli' && isNativeSourceCanonicalHistory(provider?.nativeHistory)) {
|
|
908
908
|
return true;
|
|
909
909
|
}
|
|
910
910
|
// Last-resort fallback for early call sites where the provider module is
|
|
@@ -1429,7 +1429,7 @@ function summarizeProviderForDebug(provider: ProviderModule | undefined): Record
|
|
|
1429
1429
|
name: provider.name,
|
|
1430
1430
|
category: provider.category,
|
|
1431
1431
|
version: (provider as any).version,
|
|
1432
|
-
canonicalHistory: provider.
|
|
1432
|
+
canonicalHistory: provider.nativeHistory,
|
|
1433
1433
|
historyBehavior: provider.historyBehavior,
|
|
1434
1434
|
webviewMatchText: provider.webviewMatchText,
|
|
1435
1435
|
scriptNames: scripts,
|
|
@@ -1809,9 +1809,9 @@ export async function handleChatHistory(h: CommandHelpers, args: any): Promise<C
|
|
|
1809
1809
|
|| (typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
1810
1810
|
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
1811
1811
|
);
|
|
1812
|
-
const result = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.
|
|
1812
|
+
const result = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.nativeHistory)
|
|
1813
1813
|
? readCliProviderNativeHistory(agentStr, {
|
|
1814
|
-
canonicalHistory: provider?.
|
|
1814
|
+
canonicalHistory: provider?.nativeHistory,
|
|
1815
1815
|
historySessionId,
|
|
1816
1816
|
workspace,
|
|
1817
1817
|
offset: offset || 0,
|
|
@@ -1821,7 +1821,7 @@ export async function handleChatHistory(h: CommandHelpers, args: any): Promise<C
|
|
|
1821
1821
|
scripts: provider?.scripts as any,
|
|
1822
1822
|
})
|
|
1823
1823
|
: readProviderChatHistory(agentStr, {
|
|
1824
|
-
canonicalHistory: provider?.
|
|
1824
|
+
canonicalHistory: provider?.nativeHistory,
|
|
1825
1825
|
historySessionId,
|
|
1826
1826
|
workspace,
|
|
1827
1827
|
offset: offset || 0,
|
|
@@ -1830,7 +1830,7 @@ export async function handleChatHistory(h: CommandHelpers, args: any): Promise<C
|
|
|
1830
1830
|
historyBehavior: provider?.historyBehavior,
|
|
1831
1831
|
scripts: provider?.scripts as any,
|
|
1832
1832
|
});
|
|
1833
|
-
if (supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.
|
|
1833
|
+
if (supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.nativeHistory)) {
|
|
1834
1834
|
const lookup = (result as any).lookup === 'workspace' ? 'workspace' : 'session';
|
|
1835
1835
|
const messages = Array.isArray((result as any).messages)
|
|
1836
1836
|
? normalizeNativeHistoryMessages(agentStr, (result as any).messages as ChatMessage[], (result as any)?.providerSessionId)
|
|
@@ -1969,7 +1969,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1969
1969
|
// ───────────────────────────────────────────────────────────
|
|
1970
1970
|
|
|
1971
1971
|
const supportsNative = supportsCliNativeTranscript(providerType, provider)
|
|
1972
|
-
&& isNativeSourceCanonicalHistory(provider?.
|
|
1972
|
+
&& isNativeSourceCanonicalHistory(provider?.nativeHistory);
|
|
1973
1973
|
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
|
|
1974
1974
|
const workspace = sessionWorkspace;
|
|
1975
1975
|
const nativeHistoryLimit = Math.max(
|
|
@@ -1995,7 +1995,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1995
1995
|
if (supportsNative) {
|
|
1996
1996
|
try {
|
|
1997
1997
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
1998
|
-
canonicalHistory: provider?.
|
|
1998
|
+
canonicalHistory: provider?.nativeHistory,
|
|
1999
1999
|
historySessionId: nativeHistorySessionId,
|
|
2000
2000
|
workspace,
|
|
2001
2001
|
offset: 0,
|
|
@@ -2089,7 +2089,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2089
2089
|
&& (!historyProviderSessionId || historyProviderSessionId === nativeHistorySessionId || historyProviderSessionId === historySessionId);
|
|
2090
2090
|
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative
|
|
2091
2091
|
? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
2092
|
-
canonicalHistory: provider?.
|
|
2092
|
+
canonicalHistory: provider?.nativeHistory,
|
|
2093
2093
|
workspace,
|
|
2094
2094
|
offset: 0,
|
|
2095
2095
|
limit: nativeHistoryLimit,
|
|
@@ -2200,7 +2200,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2200
2200
|
selectedMessageSource: (messageSource as any).selected,
|
|
2201
2201
|
messageSource,
|
|
2202
2202
|
shouldPreferAdapterMessages: supportsCliNativeTranscript(providerType, provider)
|
|
2203
|
-
&& isNativeSourceCanonicalHistory(provider?.
|
|
2203
|
+
&& isNativeSourceCanonicalHistory(provider?.nativeHistory)
|
|
2204
2204
|
&& (messageSource as any).selected !== 'native-history'
|
|
2205
2205
|
&& typeof (messageSource as any).fallbackReason === 'string'
|
|
2206
2206
|
&& (messageSource as any).fallbackReason.startsWith('native_history_')
|
|
@@ -2229,10 +2229,10 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2229
2229
|
: undefined;
|
|
2230
2230
|
const intendedWorkspace = typeof args?.workspace === 'string' ? args.workspace : undefined;
|
|
2231
2231
|
const supportsNative = supportsCliNativeTranscript(agentStr, provider)
|
|
2232
|
-
&& isNativeSourceCanonicalHistory(provider?.
|
|
2232
|
+
&& isNativeSourceCanonicalHistory(provider?.nativeHistory);
|
|
2233
2233
|
const history = supportsNative
|
|
2234
2234
|
? readCliProviderNativeHistory(agentStr, {
|
|
2235
|
-
canonicalHistory: provider?.
|
|
2235
|
+
canonicalHistory: provider?.nativeHistory,
|
|
2236
2236
|
historySessionId,
|
|
2237
2237
|
workspace,
|
|
2238
2238
|
offset: 0,
|
|
@@ -2242,7 +2242,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2242
2242
|
scripts: provider?.scripts as any,
|
|
2243
2243
|
})
|
|
2244
2244
|
: readProviderChatHistory(agentStr, {
|
|
2245
|
-
canonicalHistory: provider?.
|
|
2245
|
+
canonicalHistory: provider?.nativeHistory,
|
|
2246
2246
|
historySessionId,
|
|
2247
2247
|
workspace,
|
|
2248
2248
|
offset: 0,
|
package/src/commands/router.ts
CHANGED
|
@@ -3855,7 +3855,7 @@ export class DaemonCommandRouter {
|
|
|
3855
3855
|
: '';
|
|
3856
3856
|
const providerMeta = this.deps.providerLoader.resolve?.(providerType) || this.deps.providerLoader.getMeta(providerType);
|
|
3857
3857
|
const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
|
|
3858
|
-
canonicalHistory: providerMeta?.
|
|
3858
|
+
canonicalHistory: providerMeta?.nativeHistory,
|
|
3859
3859
|
offset,
|
|
3860
3860
|
limit,
|
|
3861
3861
|
historyBehavior: providerMeta?.historyBehavior,
|
|
@@ -1692,7 +1692,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1692
1692
|
|
|
1693
1693
|
private syncCanonicalSavedHistoryIfNeeded(): boolean {
|
|
1694
1694
|
if (!this.providerSessionId) return false;
|
|
1695
|
-
const canonicalHistory = this.provider.
|
|
1695
|
+
const canonicalHistory = this.provider.nativeHistory;
|
|
1696
1696
|
if (!canonicalHistory) return false;
|
|
1697
1697
|
|
|
1698
1698
|
if (isNativeSourceCanonicalHistory(canonicalHistory)) {
|
|
@@ -1754,9 +1754,9 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1754
1754
|
private restorePersistedHistoryFromCurrentSession(): void {
|
|
1755
1755
|
if (!this.providerSessionId) return;
|
|
1756
1756
|
this.syncCanonicalSavedHistoryIfNeeded();
|
|
1757
|
-
const restoredHistory = isNativeSourceCanonicalHistory(this.provider.
|
|
1757
|
+
const restoredHistory = isNativeSourceCanonicalHistory(this.provider.nativeHistory)
|
|
1758
1758
|
? readProviderChatHistory(this.type, {
|
|
1759
|
-
canonicalHistory: this.provider.
|
|
1759
|
+
canonicalHistory: this.provider.nativeHistory,
|
|
1760
1760
|
historySessionId: this.providerSessionId,
|
|
1761
1761
|
workspace: this.workingDir,
|
|
1762
1762
|
offset: 0,
|
|
@@ -541,8 +541,16 @@ export interface ProviderModule {
|
|
|
541
541
|
/** History behavior config — controls message filtering and collapse during replay */
|
|
542
542
|
historyBehavior?: ProviderHistoryBehavior;
|
|
543
543
|
/**
|
|
544
|
-
*
|
|
545
|
-
* When set, daemon
|
|
544
|
+
* Native history config — for providers that maintain native history files.
|
|
545
|
+
* When set, daemon reads/lists provider-native transcripts directly. This is
|
|
546
|
+
* the canonical v1 field name; the legacy `canonicalHistory` field name is
|
|
547
|
+
* still accepted by the loader and aliased onto this field at load time.
|
|
548
|
+
*/
|
|
549
|
+
nativeHistory?: NativeHistoryConfig;
|
|
550
|
+
/**
|
|
551
|
+
* @deprecated Legacy v0 alias for {@link ProviderModule.nativeHistory}.
|
|
552
|
+
* Loader populates this from `nativeHistory` so existing internal readers
|
|
553
|
+
* keep working during the transition. Remove after one release.
|
|
546
554
|
*/
|
|
547
555
|
canonicalHistory?: ProviderCanonicalHistoryConfig;
|
|
548
556
|
/**
|
|
@@ -688,7 +696,7 @@ export interface ProviderHistoryBehavior {
|
|
|
688
696
|
* daemon-core. They let each provider own native transcript file discovery and
|
|
689
697
|
* parsing while daemon-core only validates/pages the normalized result.
|
|
690
698
|
*/
|
|
691
|
-
export interface
|
|
699
|
+
export interface NativeHistoryScriptsConfig {
|
|
692
700
|
/** Reads one native session. Default: 'readNativeHistory'. */
|
|
693
701
|
readSession?: string;
|
|
694
702
|
/** Lists native sessions with summary metadata. Default: 'listNativeHistory'. */
|
|
@@ -696,13 +704,19 @@ export interface ProviderCanonicalHistoryScriptsConfig {
|
|
|
696
704
|
}
|
|
697
705
|
|
|
698
706
|
/**
|
|
699
|
-
*
|
|
707
|
+
* @deprecated Use {@link NativeHistoryScriptsConfig}. Retained as an alias for
|
|
708
|
+
* one release so external consumers that referenced the old name keep compiling.
|
|
709
|
+
*/
|
|
710
|
+
export type ProviderCanonicalHistoryScriptsConfig = NativeHistoryScriptsConfig;
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Native history config — for providers that maintain their own native history files.
|
|
700
714
|
*
|
|
701
715
|
* Preferred mode is provider-owned scripts via `scripts`. `format` is now an
|
|
702
716
|
* opaque provider label retained for diagnostics/backward compatibility; daemon
|
|
703
717
|
* live paths must not branch on provider-specific format values.
|
|
704
718
|
*/
|
|
705
|
-
export interface
|
|
719
|
+
export interface NativeHistoryConfig {
|
|
706
720
|
/** Opaque provider-owned history format label. */
|
|
707
721
|
format?: string;
|
|
708
722
|
/** Optional native history glob/template for diagnostics only. */
|
|
@@ -731,6 +745,12 @@ export interface ProviderCanonicalHistoryConfig {
|
|
|
731
745
|
contractVersion?: import('./transcript-v2.js').ChatContractVersion;
|
|
732
746
|
}
|
|
733
747
|
|
|
748
|
+
/**
|
|
749
|
+
* @deprecated Use {@link NativeHistoryConfig}. Retained as an alias for one
|
|
750
|
+
* release so external consumers that referenced the old name keep compiling.
|
|
751
|
+
*/
|
|
752
|
+
export type ProviderCanonicalHistoryConfig = NativeHistoryConfig;
|
|
753
|
+
|
|
734
754
|
/**
|
|
735
755
|
* Auto-implement spawn config — controls how the provider is spawned for autonomous AI-driven
|
|
736
756
|
* provider script implementation (dev-auto-implement.ts).
|
|
@@ -1958,15 +1958,20 @@ export class ProviderLoader {
|
|
|
1958
1958
|
...(extensionIdPattern instanceof RegExp ? { extensionIdPattern } : {}),
|
|
1959
1959
|
};
|
|
1960
1960
|
|
|
1961
|
-
// v1
|
|
1962
|
-
//
|
|
1963
|
-
//
|
|
1964
|
-
//
|
|
1965
|
-
//
|
|
1966
|
-
//
|
|
1967
|
-
//
|
|
1968
|
-
|
|
1969
|
-
|
|
1961
|
+
// v1 manifests use `nativeHistory` as the canonical field name.
|
|
1962
|
+
// Legacy v0 manifests use `canonicalHistory`. The daemon's
|
|
1963
|
+
// runtime + downstream code reads `provider.nativeHistory`, so
|
|
1964
|
+
// for legacy manifests we copy `canonicalHistory` into
|
|
1965
|
+
// `nativeHistory` here. We also keep `canonicalHistory`
|
|
1966
|
+
// populated in both directions (deprecated alias) so any
|
|
1967
|
+
// external consumers still reading the old name keep working
|
|
1968
|
+
// during the one-release deprecation window.
|
|
1969
|
+
const nh = (normalizedProvider as any).nativeHistory;
|
|
1970
|
+
const ch = (normalizedProvider as any).canonicalHistory;
|
|
1971
|
+
if (nh && !ch) {
|
|
1972
|
+
(normalizedProvider as any).canonicalHistory = nh;
|
|
1973
|
+
} else if (ch && !nh) {
|
|
1974
|
+
(normalizedProvider as any).nativeHistory = ch;
|
|
1970
1975
|
}
|
|
1971
1976
|
|
|
1972
1977
|
const validation = validateProviderDefinition(normalizedProvider);
|
|
@@ -37,10 +37,13 @@ const KNOWN_PROVIDER_FIELDS = new Set<string>([
|
|
|
37
37
|
'approvalPositiveHints',
|
|
38
38
|
'sessionIdPattern',
|
|
39
39
|
'historyBehavior',
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
// canonicalHistory so downstream code reads the legacy name.
|
|
40
|
+
// v1 canonical field name. The loader fills this in for legacy v0
|
|
41
|
+
// manifests that ship the old `canonicalHistory` spelling.
|
|
43
42
|
'nativeHistory',
|
|
43
|
+
// Deprecated v0 alias for `nativeHistory`. Kept in the allowed-keys
|
|
44
|
+
// list so legacy provider.json manifests don't trip the unknown-key
|
|
45
|
+
// warning during the one-release deprecation window.
|
|
46
|
+
'canonicalHistory',
|
|
44
47
|
'autoFixProfile',
|
|
45
48
|
'ideLevelScripts',
|
|
46
49
|
'allowInputDuringGeneration',
|
|
@@ -133,7 +136,7 @@ export function validateProviderDefinition(raw: unknown): ProviderValidationResu
|
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
validateCapabilities(provider as unknown as ProviderModule, controls, errors)
|
|
136
|
-
|
|
139
|
+
validateNativeHistory(provider.nativeHistory, errors)
|
|
137
140
|
validateMeshCoordinator(provider.meshCoordinator, errors)
|
|
138
141
|
|
|
139
142
|
for (const control of controls) {
|
|
@@ -233,43 +236,43 @@ function validateCapabilities(provider: ProviderModule, controls: ProviderContro
|
|
|
233
236
|
}
|
|
234
237
|
}
|
|
235
238
|
|
|
236
|
-
function
|
|
239
|
+
function validateNativeHistory(raw: unknown, errors: string[]): void {
|
|
237
240
|
if (raw === undefined) return
|
|
238
241
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
239
|
-
errors.push('
|
|
242
|
+
errors.push('nativeHistory must be an object')
|
|
240
243
|
return
|
|
241
244
|
}
|
|
242
245
|
|
|
243
|
-
const
|
|
244
|
-
const format =
|
|
246
|
+
const nativeHistory = raw as Record<string, unknown>
|
|
247
|
+
const format = nativeHistory.format
|
|
245
248
|
if (format !== undefined && (typeof format !== 'string' || !format.trim())) {
|
|
246
|
-
errors.push('
|
|
249
|
+
errors.push('nativeHistory.format must be a non-empty string when provided')
|
|
247
250
|
}
|
|
248
251
|
|
|
249
|
-
const watchPath =
|
|
252
|
+
const watchPath = nativeHistory.watchPath
|
|
250
253
|
if (watchPath !== undefined && (typeof watchPath !== 'string' || !watchPath.trim())) {
|
|
251
|
-
errors.push('
|
|
254
|
+
errors.push('nativeHistory.watchPath must be a non-empty string when provided')
|
|
252
255
|
}
|
|
253
256
|
|
|
254
|
-
const mode =
|
|
257
|
+
const mode = nativeHistory.mode
|
|
255
258
|
if (mode !== undefined && !['native-source', 'materialized-mirror', 'disabled'].includes(String(mode))) {
|
|
256
|
-
errors.push('
|
|
259
|
+
errors.push('nativeHistory.mode must be one of: native-source, materialized-mirror, disabled')
|
|
257
260
|
}
|
|
258
261
|
|
|
259
262
|
// Chat transcript contract version (transcript-v2.ts). Absent → treated as
|
|
260
263
|
// v1 by readDeclaredChatContractVersion(). A2 will reject unrecognised
|
|
261
264
|
// values at load time; A1 only validates the field shape.
|
|
262
|
-
const chatContractVersion =
|
|
265
|
+
const chatContractVersion = nativeHistory.contractVersion
|
|
263
266
|
if (chatContractVersion !== undefined
|
|
264
267
|
&& chatContractVersion !== '1.0'
|
|
265
268
|
&& chatContractVersion !== '2.0') {
|
|
266
|
-
errors.push(`
|
|
269
|
+
errors.push(`nativeHistory.contractVersion must be '1.0' or '2.0' when provided (got ${JSON.stringify(chatContractVersion)})`)
|
|
267
270
|
}
|
|
268
271
|
|
|
269
|
-
const scripts =
|
|
272
|
+
const scripts = nativeHistory.scripts
|
|
270
273
|
if (scripts === undefined) return
|
|
271
274
|
if (!scripts || typeof scripts !== 'object' || Array.isArray(scripts)) {
|
|
272
|
-
errors.push('
|
|
275
|
+
errors.push('nativeHistory.scripts must be an object')
|
|
273
276
|
return
|
|
274
277
|
}
|
|
275
278
|
|
|
@@ -277,7 +280,7 @@ function validateCanonicalHistory(raw: unknown, errors: string[]): void {
|
|
|
277
280
|
for (const key of ['readSession', 'listSessions']) {
|
|
278
281
|
const value = scriptConfig[key]
|
|
279
282
|
if (typeof value !== 'string' || !value.trim()) {
|
|
280
|
-
errors.push(`
|
|
283
|
+
errors.push(`nativeHistory.scripts.${key} must be a non-empty string`)
|
|
281
284
|
}
|
|
282
285
|
}
|
|
283
286
|
}
|
|
@@ -48,12 +48,21 @@ export interface TranscriptPtySpec {
|
|
|
48
48
|
scope?: 'screen' | 'buffer' | 'tail'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
export interface SessionIdExtractionSpec {
|
|
52
|
+
$schema?: 'adhdev:tui/session-id-extraction@1'
|
|
53
|
+
regex: string
|
|
54
|
+
flags?: string
|
|
55
|
+
scope?: 'screen' | 'tail' | 'buffer'
|
|
56
|
+
label?: string
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
export interface ParseSessionTuiSpec {
|
|
52
60
|
spinner?: any
|
|
53
61
|
settledPrompt?: any
|
|
54
62
|
modal?: ModalTuiSpec
|
|
55
63
|
dispatchOrder?: any
|
|
56
64
|
transcriptPty: TranscriptPtySpec
|
|
65
|
+
sessionIdExtraction?: SessionIdExtractionSpec
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
// ─── Output shape ────────────────────────────────
|
|
@@ -73,6 +82,7 @@ export interface SynthesizedSession {
|
|
|
73
82
|
parsedStatus: string | null
|
|
74
83
|
transcriptAuthority?: 'provider' | 'daemon'
|
|
75
84
|
coverage?: 'full' | 'tail' | 'current-turn'
|
|
85
|
+
providerSessionId?: string
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
// ─── ANSI / line helpers ─────────────────────────
|
|
@@ -176,6 +186,16 @@ export function buildParseSessionFromTui(spec: ParseSessionTuiSpec): (input: any
|
|
|
176
186
|
: () => null
|
|
177
187
|
const parseApproval = spec.modal ? buildParseApprovalFromTui(spec.modal) : () => null
|
|
178
188
|
|
|
189
|
+
// Optional session-id extraction (tui/session-id-extraction@1). Compile once
|
|
190
|
+
// so each parseSession call is a single regex.exec on the chosen scope.
|
|
191
|
+
const sessionIdRe = spec.sessionIdExtraction
|
|
192
|
+
? new RegExp(
|
|
193
|
+
spec.sessionIdExtraction.regex,
|
|
194
|
+
spec.sessionIdExtraction.flags ?? 'i',
|
|
195
|
+
)
|
|
196
|
+
: null
|
|
197
|
+
const sessionIdScope: TranscriptPtySpec['scope'] = spec.sessionIdExtraction?.scope ?? 'tail'
|
|
198
|
+
|
|
179
199
|
return function parseSession(input: any): SynthesizedSession {
|
|
180
200
|
// status + modal first
|
|
181
201
|
const status = detectStatus(input as any) ?? 'idle'
|
|
@@ -236,12 +256,21 @@ export function buildParseSessionFromTui(spec: ParseSessionTuiSpec): (input: any
|
|
|
236
256
|
if (cont) last.content = last.content ? `${last.content}\n${cont}` : cont
|
|
237
257
|
}
|
|
238
258
|
|
|
239
|
-
|
|
259
|
+
const result: SynthesizedSession = {
|
|
240
260
|
status,
|
|
241
261
|
messages,
|
|
242
262
|
activeModal: modal,
|
|
243
263
|
modal,
|
|
244
264
|
parsedStatus: status,
|
|
245
265
|
}
|
|
266
|
+
|
|
267
|
+
if (sessionIdRe) {
|
|
268
|
+
const haystack = stripAnsi(pickInputText(input, sessionIdScope))
|
|
269
|
+
const match = haystack.match(sessionIdRe)
|
|
270
|
+
const captured = match?.[1]?.trim()
|
|
271
|
+
if (captured) result.providerSessionId = captured
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return result
|
|
246
275
|
}
|
|
247
276
|
}
|
|
@@ -309,13 +309,34 @@
|
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
},
|
|
312
|
+
"nativeHistory": {
|
|
313
|
+
"type": "object",
|
|
314
|
+
"description": "Native transcript adapter declaration. v1 canonical field name. Daemon reads/lists provider-native history files via the named scripts (or the built-in adapter identified by $schema).",
|
|
315
|
+
"additionalProperties": true,
|
|
316
|
+
"properties": {
|
|
317
|
+
"$schema": { "type": "string" },
|
|
318
|
+
"format": { "type": "string" },
|
|
319
|
+
"watchPath": { "type": "string" },
|
|
320
|
+
"mode": { "enum": ["native-source", "materialized-mirror", "disabled", "daemon-mirror"] },
|
|
321
|
+
"contractVersion": { "type": "string" },
|
|
322
|
+
"scripts": {
|
|
323
|
+
"type": "object",
|
|
324
|
+
"additionalProperties": false,
|
|
325
|
+
"properties": {
|
|
326
|
+
"readSession": { "type": "string" },
|
|
327
|
+
"listSessions": { "type": "string" }
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
},
|
|
312
332
|
"canonicalHistory": {
|
|
313
333
|
"type": "object",
|
|
314
|
-
"
|
|
334
|
+
"description": "Deprecated v0 alias for `nativeHistory`. The loader copies this block into `nativeHistory` at load time. New manifests should use `nativeHistory` directly.",
|
|
335
|
+
"additionalProperties": true,
|
|
315
336
|
"properties": {
|
|
316
337
|
"format": { "type": "string" },
|
|
317
338
|
"watchPath": { "type": "string" },
|
|
318
|
-
"mode": { "enum": ["native-source", "daemon-mirror"] },
|
|
339
|
+
"mode": { "enum": ["native-source", "materialized-mirror", "disabled", "daemon-mirror"] },
|
|
319
340
|
"contractVersion": { "type": "string" },
|
|
320
341
|
"scripts": {
|
|
321
342
|
"type": "object",
|
|
@@ -340,11 +361,6 @@
|
|
|
340
361
|
"description": "Declarative TUI parsing primitives. When present, daemon's builder synthesises detectStatus / parseApproval / parseSession from these blocks. Each block is identified by its $schema.",
|
|
341
362
|
"additionalProperties": true
|
|
342
363
|
},
|
|
343
|
-
"nativeHistory": {
|
|
344
|
-
"type": "object",
|
|
345
|
-
"description": "Declarative native-history adapter declaration. Daemon's builder routes readChat history through the named adapter ($schema).",
|
|
346
|
-
"additionalProperties": true
|
|
347
|
-
},
|
|
348
364
|
"overrides": {
|
|
349
365
|
"type": "object",
|
|
350
366
|
"description": "Optional JS override pointers. Presence promotes the provider tier to `extended`. Each value identifies the handler being overridden and the relative path to the JS file implementing it.",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "adhdev:tui/session-id-extraction@1",
|
|
4
|
+
"title": "tui/session-id-extraction — v1",
|
|
5
|
+
"description": "Declares a regex that captures the provider-issued session UUID off the PTY chrome (e.g. codex footer `gpt-5.5 high · ~/Work/adhdev · 019e8e58-4bd2-7c80-8f5b-b49b6c0e25fa`). The builder runs the regex over the chosen scope's text and exposes the captured group (1) as `providerSessionId` on the parseSession result, so downstream native-history lookup can locate the matching transcript file (`~/.codex/sessions/*-019e8e58-...jsonl`, `~/.claude/projects/*/<uuid>.jsonl`, etc.). Without this primitive a manifest had to ship a scripts/v1 override or fall back to v0 scripts/1.0 just to surface a session id — that's the gap this closes.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["$schema", "regex"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"const": "adhdev:tui/session-id-extraction@1"
|
|
12
|
+
},
|
|
13
|
+
"regex": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "ECMAScript regex source. Capture group 1 must hold the session identifier."
|
|
16
|
+
},
|
|
17
|
+
"flags": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"pattern": "^[gimsuy]*$",
|
|
20
|
+
"default": "i"
|
|
21
|
+
},
|
|
22
|
+
"scope": {
|
|
23
|
+
"default": "tail",
|
|
24
|
+
"enum": ["screen", "tail", "buffer"],
|
|
25
|
+
"description": "Which input view to search. `tail` (default) covers the recent buffer where chrome footers usually live; `screen` is just the visible frame; `buffer` is the full scrollback."
|
|
26
|
+
},
|
|
27
|
+
"label": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Optional tag included in debug traces — handy when a manifest declares more than one extraction candidate during authoring."
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"examples": [
|
|
33
|
+
{
|
|
34
|
+
"$schema": "adhdev:tui/session-id-extraction@1",
|
|
35
|
+
"regex": "(?:gpt-|o\\d|codex-)[^·]+·[^·]+·\\s*([0-9a-f-]{36})",
|
|
36
|
+
"scope": "tail",
|
|
37
|
+
"label": "codex-footer"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"$schema": "adhdev:tui/session-id-extraction@1",
|
|
41
|
+
"regex": "session id:\\s*([0-9a-f-]{36})",
|
|
42
|
+
"flags": "i",
|
|
43
|
+
"scope": "buffer"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|