@hasna/skills 0.10.82 → 0.10.88
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/README.md +133 -15
- package/bin/index.js +5691 -2868
- package/bin/mcp.js +1689 -810
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/cli/commands/agent-integration.d.ts +35 -0
- package/dist/cli/commands/context.d.ts +4 -0
- package/dist/cli/commands/runtime-launcher.d.ts +4 -9
- package/dist/index.js +3022 -1530
- package/dist/lib/agent-adapters.d.ts +5 -2
- package/dist/lib/agent-discovery.d.ts +22 -4
- package/dist/lib/agent-hermes.d.ts +7 -1
- package/dist/lib/agent-integration.d.ts +31 -2
- package/dist/lib/agent-opencode.d.ts +4 -0
- package/dist/lib/claude-hook-disable.d.ts +32 -0
- package/dist/lib/claude-settings-witness.d.ts +28 -0
- package/dist/lib/codex-settings-witness.d.ts +20 -0
- package/dist/lib/guarded-agent-config.d.ts +3 -0
- package/dist/lib/hook-diagnostics.d.ts +3 -1
- package/dist/lib/narrowed-witness-ledger.d.ts +24 -0
- package/dist/lib/native-discovery-roots.d.ts +8 -0
- package/dist/lib/native-drift-receipt.d.ts +55 -0
- package/dist/lib/opencode-hook-protocol.d.ts +5 -0
- package/dist/lib/profile-client.d.ts +1 -0
- package/dist/lib/selection-cache.d.ts +47 -2
- package/dist/lib/session-background-renewal.d.ts +118 -0
- package/dist/lib/session-reconciliation.d.ts +82 -2
- package/dist/lib/skill-context.d.ts +39 -1
- package/dist/lib/skill-relevance.d.ts +95 -0
- package/dist/runtime-prerequisites.js +570 -165
- package/dist/sdk/index.js +2627 -1396
- package/docs/plugin-admission.md +132 -3
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { renderOpenCodePlugin } from "./agent-opencode.js";
|
|
1
2
|
export declare const INTEGRATION_AGENTS: readonly ["claude", "codex", "gemini", "opencode", "cursor", "hermes", "sumi"];
|
|
2
3
|
export type IntegrationAgent = typeof INTEGRATION_AGENTS[number];
|
|
3
4
|
export declare function renderAgentHookCommand(command: string, agent: IntegrationAgent, profileId: string, event: string): string;
|
|
@@ -23,7 +24,7 @@ export declare const AGENT_ADAPTERS: {
|
|
|
23
24
|
readonly opencode: {
|
|
24
25
|
readonly root: ".config/opencode/skills";
|
|
25
26
|
readonly config: ".config/opencode/opencode.json";
|
|
26
|
-
readonly events: readonly ["
|
|
27
|
+
readonly events: readonly ["prompt", "context"];
|
|
27
28
|
readonly promptContext: true;
|
|
28
29
|
};
|
|
29
30
|
readonly sumi: {
|
|
@@ -49,4 +50,6 @@ export declare const AGENT_ADAPTERS: {
|
|
|
49
50
|
};
|
|
50
51
|
};
|
|
51
52
|
export declare function normalizeAgentHookEvent(agent: IntegrationAgent, event: string): string;
|
|
52
|
-
export declare function
|
|
53
|
+
export declare function renderLegacyOpenCodePlugin(command: string, profileId: string): string;
|
|
54
|
+
/** Recognize exact managed bytes only, including the shipped v1 generator. */
|
|
55
|
+
export declare function isManagedOpenCodePlugin(text: string | null, command: string, profileId: string): boolean;
|
|
@@ -5,6 +5,7 @@ import { CLAUDE_ORPHAN_MARKER_MODE } from "./claude-plugin-cache-marker.js";
|
|
|
5
5
|
import { type NativeDiscoveryWitnessTolerance } from "./native-discovery-witness-change.js";
|
|
6
6
|
import { type ManagedPluginRegistrationWitness } from "./plugin-discovery.js";
|
|
7
7
|
import { type CodexHookDiscoveryRecovery } from "./codex-hook-discovery-recovery.js";
|
|
8
|
+
import { type NarrowedWitnessLedger } from "./narrowed-witness-ledger.js";
|
|
8
9
|
import { type CodexPluginSkillControl, type CodexPluginSourceInput } from "./codex-plugin-skill-controls.js";
|
|
9
10
|
import { type RetainedReviewArtifact, type ReviewedArtifact } from "./retained-review-artifacts.js";
|
|
10
11
|
import { type CodexSemanticCacheWitness, type CodexSemanticCacheAppOnlyParent, type CodexSemanticCacheReviewedHookParent } from "./codex-semantic-cache-witness.js";
|
|
@@ -13,7 +14,7 @@ export interface DiscoverySource {
|
|
|
13
14
|
reviewArtifact?: RetainedReviewArtifact;
|
|
14
15
|
path: string;
|
|
15
16
|
sha256: string | null;
|
|
16
|
-
hashMode?: "bytes" | "path-bytes" | "claude-plugin-orphaned-at-v1" | "claude-plugin-manifest-v1" | "claude-plugin-registry" | "claude-marketplace-registry" | "claude-settings-v1" | "claude-settings-v2" | "claude-settings-v3" | "claude-settings-v4" | "claude-marketplace-registry-v2" | "codex-settings-v1" | "codex-settings-v2" | "codex-settings-v3" | "codex-settings-v4" | "codex-settings-v5" | "codex-settings-v6" | "executable-v1" | "sumi-settings-v1" | "claude-marketplace-entry-v1";
|
|
17
|
+
hashMode?: "bytes" | "path-bytes" | "claude-plugin-orphaned-at-v1" | "claude-plugin-manifest-v1" | "claude-plugin-registry" | "claude-marketplace-registry" | "claude-settings-v1" | "claude-settings-v2" | "claude-settings-v3" | "claude-settings-v4" | "claude-settings-v5" | "claude-marketplace-registry-v2" | "codex-settings-v1" | "codex-settings-v2" | "codex-settings-v3" | "codex-settings-v4" | "codex-settings-v5" | "codex-settings-v6" | "codex-settings-v7" | "executable-v1" | "sumi-settings-v1" | "claude-marketplace-entry-v1";
|
|
17
18
|
hookSources?: CodexReviewedHookSource[];
|
|
18
19
|
managedPlugins?: ManagedPluginRegistrationWitness[];
|
|
19
20
|
format?: "json" | "toml" | "yaml";
|
|
@@ -120,12 +121,15 @@ export declare function assertCodexSemanticCacheHookSafety(cacheRoot: string, pa
|
|
|
120
121
|
/** Source-byte and directory-membership drift are NativeDiscoveryWitnessChange
|
|
121
122
|
* errors. Only the live Codex prompt hook passes `witnessTolerance`; a change it
|
|
122
123
|
* accepts as a vendor refresh is collected and the remaining checks still run.
|
|
124
|
+
* Only the live hooks pass `narrowed`: a legacy full-file settings witness that
|
|
125
|
+
* no longer matches is still current when the narrowed digest recorded for it
|
|
126
|
+
* matches (see narrowed-witness-ledger.ts), and a matching one is observed.
|
|
123
127
|
* Every other change and every other failure throws as before. */
|
|
124
128
|
export declare function verifyAgentDiscovery(binding: AgentDiscoveryBinding, codexRecovery?: CodexHookDiscoveryRecovery, reviewedRootAliases?: readonly {
|
|
125
129
|
agent: IntegrationAgent;
|
|
126
130
|
alias: string;
|
|
127
131
|
target: string;
|
|
128
|
-
}[], witnessTolerance?: NativeDiscoveryWitnessTolerance): void;
|
|
132
|
+
}[], witnessTolerance?: NativeDiscoveryWitnessTolerance, narrowed?: NarrowedWitnessLedger): void;
|
|
129
133
|
/** One stored Claude discovery source as an installer sees it. */
|
|
130
134
|
export type ClaudeDiscoverySourceVerdict = {
|
|
131
135
|
status: "current";
|
|
@@ -193,11 +197,25 @@ export declare function discoveryTextKeepsWitness(binding: Pick<AgentDiscoveryBi
|
|
|
193
197
|
/** `executable` is the agent's runtime: omitted, it is resolved through PATH;
|
|
194
198
|
* a value (or null for none) is used as given, so verification never depends
|
|
195
199
|
* on the caller's PATH. */
|
|
196
|
-
|
|
200
|
+
type DiscoveryOptions = {
|
|
197
201
|
home: string;
|
|
198
202
|
agent: IntegrationAgent;
|
|
199
203
|
reviewed?: ReviewedDiscoveryInputs;
|
|
200
204
|
retainedReview?: AgentDiscoveryBinding;
|
|
201
205
|
canonical?: (path: string) => string;
|
|
202
206
|
executable?: DiscoveryExecutable | null;
|
|
203
|
-
}
|
|
207
|
+
};
|
|
208
|
+
export declare function resolveAgentDiscovery(options: DiscoveryOptions): AgentDiscoveryBinding;
|
|
209
|
+
/** Read-only exclusion, not native admission. Retained roots remain excluded,
|
|
210
|
+
* while current supported controls are re-derived even when old settings or
|
|
211
|
+
* directory witnesses are stale. Non-enumerable executable inputs still need
|
|
212
|
+
* their existing review. No witness, policy or enrollment is written. */
|
|
213
|
+
export declare function resolveAgentDiscoveryExclusionRoots(options: Omit<DiscoveryOptions, "reviewed" | "retainedReview"> & {
|
|
214
|
+
retained?: AgentDiscoveryBinding;
|
|
215
|
+
narrowed?: NarrowedWitnessLedger;
|
|
216
|
+
nativeHome?: string;
|
|
217
|
+
}): readonly string[];
|
|
218
|
+
/** Metadata-only closure of aliases inside the selected native discovery
|
|
219
|
+
* trees. Never search the account generally or load a payload/plugin. Each
|
|
220
|
+
* resolved alias remains excluded while unrelated portable paths stay usable. */
|
|
221
|
+
export declare function nativeDiscoveryAliasTargets(roots: readonly string[], home: string): string[];
|
|
@@ -12,13 +12,19 @@ export declare function hermesHookDefinitions(supervisor: Pick<HermesSupervisorB
|
|
|
12
12
|
fail_closed?: boolean;
|
|
13
13
|
}>;
|
|
14
14
|
export declare function configureHermesHooks(text: string | null, supervisor: HermesSupervisorBinding, previous?: HermesSupervisorBinding): string;
|
|
15
|
+
/** Every refusal here leaves the effective Hermes discovery unchecked (another
|
|
16
|
+
* project, home, bundled tree or project plugins), so a payload named skills-cli
|
|
17
|
+
* there could load through the bridge. They are bridge-integrity refusals: the
|
|
18
|
+
* live skill_view(skills-cli) call is refused while prompts still fail open. */
|
|
15
19
|
export declare function assertHermesEnvironment(home: string): void;
|
|
16
20
|
export declare function assertHermesProtection(home: string, config: Record<string, any>, command: string, profile: string, supervisor: HermesSupervisorBinding): void;
|
|
17
21
|
/** skill_view also searches legacy <name>.md with rglob, including hidden and
|
|
18
22
|
* dependency directories that the normal SKILL.md index skips. Check the one
|
|
19
23
|
* name admitted by the native tool guard without reading any candidate bytes.
|
|
20
24
|
* Only support folders directly under a real skill descriptor are excluded,
|
|
21
|
-
* matching Hermes is_skill_support_path. Every other bounded path is checked.
|
|
25
|
+
* matching Hermes is_skill_support_path. Every other bounded path is checked.
|
|
26
|
+
* A found or unrulable shadow is a bridge-integrity refusal: the live
|
|
27
|
+
* skill_view(skills-cli) call is refused, while prompts still fail open. */
|
|
22
28
|
export declare function assertNoHermesLegacyShadow(root: string): void;
|
|
23
29
|
export declare function normalizeHermesHookInput(input: Record<string, any>): Record<string, any>;
|
|
24
30
|
export declare function assertHermesTool(input: Record<string, any>): void;
|
|
@@ -4,6 +4,7 @@ import { type ReviewedCodexSkillDenial, type CodexPluginSkillControl } from "./c
|
|
|
4
4
|
import { type CodexNativeHookEnvelope, type ProcessInspector, type NativePolicyHelperRunner } from "./codex-native-skill-policy.js";
|
|
5
5
|
import { type CodexNativeSkillCatalog } from "./codex-native-skill-catalog.js";
|
|
6
6
|
import type { NativeDiscoveryWitnessKind } from "./native-discovery-witness-change.js";
|
|
7
|
+
import { type BigIntStats } from "node:fs";
|
|
7
8
|
import { type DiscoveryExecutable, type AgentDiscoveryBinding, type ReviewedDiscoveryInputs } from "./agent-discovery.js";
|
|
8
9
|
import { type IntegrationAgent } from "./agent-adapters.js";
|
|
9
10
|
import type { CodexHookDiscoveryRecovery } from "./codex-hook-discovery-recovery.js";
|
|
@@ -178,6 +179,11 @@ export interface ClaudeManagedHookProjectionOptions {
|
|
|
178
179
|
/** Supply the preceding plan's source witness when checking it before use. */
|
|
179
180
|
expectedSourceSha256?: string;
|
|
180
181
|
}
|
|
182
|
+
export declare function assertNativePathAcl(path: string, observed: BigIntStats, options?: {
|
|
183
|
+
allowDenyOnly?: boolean;
|
|
184
|
+
descriptor?: number;
|
|
185
|
+
creationParent?: boolean;
|
|
186
|
+
}): void;
|
|
181
187
|
/** Read-only projection for a copied Claude configuration. This does not install
|
|
182
188
|
* hooks, adopt target discovery, change policy, or confer write/admission authority.
|
|
183
189
|
* The caller must preserve the full target, hold its owning writer lease, replan
|
|
@@ -207,8 +213,8 @@ export declare function planClaudeHookEventsUpdate(options: ClaudeHookUpdateOpti
|
|
|
207
213
|
*/
|
|
208
214
|
export declare function planAgentSettingsWitnessUpgrade(options: {
|
|
209
215
|
agent: "claude" | "codex" | "sumi";
|
|
210
|
-
targetCodexVersion?: 2 | 3 | 4 | 5;
|
|
211
|
-
targetClaudeVersion?: 3 | 4;
|
|
216
|
+
targetCodexVersion?: 2 | 3 | 4 | 5 | 7;
|
|
217
|
+
targetClaudeVersion?: 3 | 4 | 5;
|
|
212
218
|
reviewedPreimage: string;
|
|
213
219
|
home?: string;
|
|
214
220
|
dataDir?: string;
|
|
@@ -404,6 +410,25 @@ interface ManagedBridgeOptions {
|
|
|
404
410
|
* vendor copies and every other change still refuse. Install, trust, migrate
|
|
405
411
|
* and sync never pass it. */
|
|
406
412
|
codexPromptHook?: boolean;
|
|
413
|
+
/** Live lifecycle hooks only (prompt, session, subagent and tool events).
|
|
414
|
+
* - A legacy full-file settings witness that no longer matches stays current
|
|
415
|
+
* when the narrowed digest recorded for its review is unchanged, and a
|
|
416
|
+
* matching one is recorded (narrowed-witness-ledger.ts).
|
|
417
|
+
* - Anything that stops the skills-cli bridge from being verified is a
|
|
418
|
+
* NativeBridgeIntegrityRefusal, and any other failure to verify native
|
|
419
|
+
* discovery (a changed root alias, an unreadable settings file, an
|
|
420
|
+
* inventory error) is reported as NATIVE_SKILL_DRIFT, so the hook can fail
|
|
421
|
+
* open instead of blocking the prompt.
|
|
422
|
+
* Install, trust, migrate, sync and upgrades never pass it. */
|
|
423
|
+
liveHook?: boolean;
|
|
424
|
+
/** Live tool events that would load the skills-cli bridge (Claude
|
|
425
|
+
* Skill(skills-cli), Gemini activate_skill(skills-cli), Hermes
|
|
426
|
+
* skill_view(skills-cli)); requires liveHook. Before such a call proceeds,
|
|
427
|
+
* no native copy may be able to resolve under the bridge's own name, in any
|
|
428
|
+
* tier the agent searches, including after an earlier drift skipped the
|
|
429
|
+
* inventory. A found copy, or a check that cannot complete, is a
|
|
430
|
+
* NativeBridgeIntegrityRefusal. */
|
|
431
|
+
bridgeToolCall?: boolean;
|
|
407
432
|
}
|
|
408
433
|
/** Result of a guard call; both lists are empty unless the caller opted in.
|
|
409
434
|
* `codexInertVendorCopies` holds the canonical skill directories exempted as
|
|
@@ -444,7 +469,11 @@ export declare function codexPromptDriftWarning(report: ManagedBridgeReport): st
|
|
|
444
469
|
/** Run before any prompt context load. Missing ownership or reappearing native
|
|
445
470
|
* discovery files require repair; verified cache availability is not an override. */
|
|
446
471
|
export declare function assertManagedAgentBridge(agent: IntegrationAgent, options?: ManagedBridgeOptions): ManagedBridgeReport;
|
|
472
|
+
/** Consumption-edge check: native registry content and path must name the
|
|
473
|
+
* exact owned bridge, and live on-disk custody must still verify now. */
|
|
474
|
+
export declare function assertOpenCodeNativeBridge(skill: unknown, options?: ManagedBridgeOptions): void;
|
|
447
475
|
export declare function normalizeAgentHookPrompt(agent: IntegrationAgent, event: string, prompt: string): string;
|
|
476
|
+
export declare function isAgentSubmittedPrompt(prompt: unknown): boolean;
|
|
448
477
|
export declare function hookContextOutput(event: string, result: {
|
|
449
478
|
context: string;
|
|
450
479
|
receipt?: unknown;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** OpenCode v2.0.32 Promise contract: plugin/module.ts, promise/session.ts,
|
|
2
|
+
* promise/tool.ts and promise/registration.ts in anomalyco/opencode.
|
|
3
|
+
* Prompt admission captures genuine input; context matches/restores at delivery. */
|
|
4
|
+
export declare function renderOpenCodePlugin(command: string, profile: string): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ClaudeHookDisableOptions {
|
|
2
|
+
settings: string;
|
|
3
|
+
expectedSettingsSha256: string;
|
|
4
|
+
expectedMode: "0600" | "absent";
|
|
5
|
+
command: string;
|
|
6
|
+
expectedCommandSha256: string;
|
|
7
|
+
profile: string;
|
|
8
|
+
apply?: boolean;
|
|
9
|
+
/** New, exclusive, private directory. Its parent must already exist. */
|
|
10
|
+
preimageDir?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ClaudeHookDisableResult {
|
|
13
|
+
schema: "hasna.claude-hook-disable.v1";
|
|
14
|
+
state: "preview" | "applied" | "no-op" | "no-data" | "ambiguous";
|
|
15
|
+
mutationOccurred: boolean;
|
|
16
|
+
target: string;
|
|
17
|
+
beforeSha256: string | null;
|
|
18
|
+
plannedAfterSha256: string | null;
|
|
19
|
+
afterSha256: string | null;
|
|
20
|
+
removed: Array<{
|
|
21
|
+
event: string;
|
|
22
|
+
groupIndex: number;
|
|
23
|
+
hookIndex: number;
|
|
24
|
+
}>;
|
|
25
|
+
settingsWitness: "unchanged" | "not-renewed";
|
|
26
|
+
preimage?: string;
|
|
27
|
+
displaced?: string;
|
|
28
|
+
receipt?: string;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Only removes exact rendered context registrations. Never installs, admits or rebinds. */
|
|
32
|
+
export declare function disableClaudeHooks(options: ClaudeHookDisableOptions): ClaudeHookDisableResult;
|
|
@@ -10,6 +10,9 @@ export interface ClaudeSettingsWitnessBudget {
|
|
|
10
10
|
remaining: number;
|
|
11
11
|
}
|
|
12
12
|
export declare function readNativeSettingsWitnessFile(path: string, budget: ClaudeSettingsWitnessBudget, filename?: "settings.json" | "config.toml" | "sumi.json" | "marketplace.json"): string;
|
|
13
|
+
/** The same bounded, stable, strict-UTF8 read for root-exclusion inputs whose
|
|
14
|
+
* filenames are selected by the owning agent adapter rather than settings. */
|
|
15
|
+
export declare function readNativeDiscoveryWitnessFile(path: string, budget: ClaudeSettingsWitnessBudget): string;
|
|
13
16
|
export type NativeJsonObject = ObjectValue;
|
|
14
17
|
export type NativeJsonValue = Value;
|
|
15
18
|
type ObjectValue = {
|
|
@@ -93,6 +96,31 @@ export declare function upgradeClaudeSettingsWitnessV4(previous: {
|
|
|
93
96
|
hashMode?: "bytes" | "claude-settings-v1" | "claude-settings-v2" | "claude-settings-v3";
|
|
94
97
|
sha256: string;
|
|
95
98
|
}, reviewedSettingsPath: string): ReturnType<typeof captureClaudeSettingsV4>;
|
|
99
|
+
/** Current discovery controls, parsed by the same bounded, duplicate-key-safe
|
|
100
|
+
* adapter as the v5 witness. Root exclusion consumes this without changing a
|
|
101
|
+
* stored review or accepting that review for native loading. */
|
|
102
|
+
export declare function claudeDiscoveryControlKeys(text: string): string[];
|
|
103
|
+
/** Discovery environment names from the same owning projection, without
|
|
104
|
+
* returning their values or treating ordinary environment as discovery. */
|
|
105
|
+
export declare function claudeDiscoveryEnvironmentKeys(text: string): string[];
|
|
106
|
+
/** Explicit v5 review: the narrowed discovery projection above. v1-v4
|
|
107
|
+
* witnesses keep their meaning; nothing selects v5 implicitly. */
|
|
108
|
+
export declare function captureClaudeSettingsV5(path: string, budget?: ClaudeSettingsWitnessBudget): {
|
|
109
|
+
path: string;
|
|
110
|
+
hashMode: "claude-settings-v5";
|
|
111
|
+
sha256: string;
|
|
112
|
+
};
|
|
113
|
+
export declare function hashClaudeSettingsReplacementV5(text: string, budget: ClaudeSettingsWitnessBudget): string;
|
|
114
|
+
/** Explicit upgrade from any prior witness (raw bytes, v1-v4) with an exact
|
|
115
|
+
* preserved preimage of its review. v5 binds a subset of what each earlier mode
|
|
116
|
+
* binds, so only a difference in settings v5 ignores is accepted; a change to a
|
|
117
|
+
* hook, plugin, marketplace, skill key, Skill rule, added directory or
|
|
118
|
+
* discovery environment variable still refuses. */
|
|
119
|
+
export declare function upgradeClaudeSettingsWitnessV5(previous: {
|
|
120
|
+
path: string;
|
|
121
|
+
hashMode?: "bytes" | "claude-settings-v1" | "claude-settings-v2" | "claude-settings-v3" | "claude-settings-v4";
|
|
122
|
+
sha256: string;
|
|
123
|
+
}, reviewedSettingsPath: string): ReturnType<typeof captureClaudeSettingsV5>;
|
|
96
124
|
/** Strict bounded JSON control witness; metadata exclusion must be explicit. */
|
|
97
125
|
export declare function hashNativeJsonControls(text: string, excludedMetadata?: "version"): string;
|
|
98
126
|
/** Sumi's versioned review uses the same strict JSON parser and bounded syntax
|
|
@@ -79,6 +79,26 @@ export declare function upgradeCodexSettingsWitnessV5(previous: {
|
|
|
79
79
|
hashMode?: "bytes" | "codex-settings-v1" | "codex-settings-v2" | "codex-settings-v3" | "codex-settings-v4";
|
|
80
80
|
sha256: string;
|
|
81
81
|
}, reviewedSettingsPath: string): ReturnType<typeof captureCodexSettingsV5>;
|
|
82
|
+
/** Root exclusion uses the same discovery projection as V7, including every
|
|
83
|
+
* profile and instruction/MCP control, without creating a settings witness. */
|
|
84
|
+
export declare function codexDiscoveryControlKeys(config: Record<string, any>): string[];
|
|
85
|
+
/** Explicit V7 review: the narrowed discovery projection above. Earlier modes
|
|
86
|
+
* keep their meaning; nothing selects V7 implicitly. */
|
|
87
|
+
export declare function hashCodexSettingsReplacementV7(text: string, budget?: ClaudeSettingsWitnessBudget): string;
|
|
88
|
+
export declare function captureCodexSettingsV7(path: string, budget?: ClaudeSettingsWitnessBudget): {
|
|
89
|
+
path: string;
|
|
90
|
+
hashMode: "codex-settings-v7";
|
|
91
|
+
sha256: string;
|
|
92
|
+
};
|
|
93
|
+
/** Prove the preserved original under its exact original contract (raw bytes or
|
|
94
|
+
* V1-V5), then require the same V7 projection. V7 binds a subset of what each
|
|
95
|
+
* of those modes binds, so only a difference in settings V7 ignores passes.
|
|
96
|
+
* V6 is not eligible: it binds hook MCP dependencies V7 does not carry. */
|
|
97
|
+
export declare function upgradeCodexSettingsWitnessV7(previous: {
|
|
98
|
+
path: string;
|
|
99
|
+
hashMode?: "bytes" | "codex-settings-v1" | "codex-settings-v2" | "codex-settings-v3" | "codex-settings-v4" | "codex-settings-v5";
|
|
100
|
+
sha256: string;
|
|
101
|
+
}, reviewedSettingsPath: string): ReturnType<typeof captureCodexSettingsV7>;
|
|
82
102
|
/** V6 keeps V5 display tolerances and binds routes referenced by the complete
|
|
83
103
|
* independently reviewed native hook source population. No legacy migration. */
|
|
84
104
|
export declare function captureCodexSettingsV6(path: string, reviewedSources: readonly CodexReviewedHookSource[], budget?: ClaudeSettingsWitnessBudget, changes?: Map<string, string>): {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function guardedAgentConfigRefusal(error: unknown): string;
|
|
2
|
+
/** One transaction for the direct-file adapters. Failed evidence stays beside the original. */
|
|
3
|
+
export declare function guardedAgentConfigWrite(path: string, transform: (current: Buffer | null) => string): void;
|
|
@@ -5,7 +5,9 @@ export declare class HookDiagnosticError extends Error {
|
|
|
5
5
|
readonly stage: "context" | "sync";
|
|
6
6
|
/** Fixed marker: a refused renewal whose automatic pin migration ran out of budget. */
|
|
7
7
|
readonly migration?: "timeout";
|
|
8
|
-
|
|
8
|
+
/** Fixed marker: an expired pin whose renewal continues in a background worker. */
|
|
9
|
+
readonly renewal?: "background";
|
|
10
|
+
constructor(code: string, stage: "context" | "sync", migration?: "timeout", renewal?: "background");
|
|
9
11
|
}
|
|
10
12
|
export declare function hookChildError(stdout: string, stage: "context" | "sync"): HookDiagnosticError;
|
|
11
13
|
export declare function hookFailureReason(error: unknown, profileId?: string): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DiscoverySource } from "./agent-discovery.js";
|
|
2
|
+
export type NarrowedSettingsMode = "claude-settings-v5" | "codex-settings-v7";
|
|
3
|
+
export declare const NARROWED_WITNESS_LEDGER_FILE = "native-witness-narrowed.json";
|
|
4
|
+
/** The narrowed mode that covers this legacy full-file settings witness, or
|
|
5
|
+
* null when it has none. */
|
|
6
|
+
export declare function narrowedLegacyWitnessMode(source: DiscoverySource): NarrowedSettingsMode | null;
|
|
7
|
+
export interface NarrowedWitnessLedger {
|
|
8
|
+
/** The legacy witness no longer matches: accept only when the current file's
|
|
9
|
+
* narrowed digest equals the one recorded for this exact witness. */
|
|
10
|
+
accepts(source: DiscoverySource): boolean;
|
|
11
|
+
/** The legacy witness verified the current file: record its narrowed digest,
|
|
12
|
+
* re-proving the legacy match on the same bytes first. */
|
|
13
|
+
observe(source: DiscoverySource): void;
|
|
14
|
+
/** Paths accepted through a recorded narrowed digest during this check. */
|
|
15
|
+
readonly accepted: string[];
|
|
16
|
+
}
|
|
17
|
+
/** Opened by the live hook only. `record` permits observations to be written
|
|
18
|
+
* by flush(); reads never write. Every failure is fail-closed: an unreadable or
|
|
19
|
+
* malformed ledger accepts nothing and is never overwritten. */
|
|
20
|
+
export declare function openNarrowedWitnessLedger(dataDir: string, options?: {
|
|
21
|
+
record: boolean;
|
|
22
|
+
}): NarrowedWitnessLedger & {
|
|
23
|
+
flush(): void;
|
|
24
|
+
};
|
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
/** Shared default discovery roots for inventory and authoring exclusion. */
|
|
2
2
|
export declare const NATIVE_SKILL_ROOTS: readonly [readonly ["claude", ".claude/skills"], readonly ["codex", ".codex/skills"], readonly ["codex", ".agents/skills"], readonly ["gemini", ".gemini/skills"], readonly ["sumi", ".sumi/skills"], readonly ["sumi", ".sumi/skill"], readonly ["codewith", ".codewith/skills"], readonly ["opencode", ".config/opencode/skills"], readonly ["opencode", ".opencode/skills"], readonly ["cursor", ".cursor/skills"], readonly ["hermes", ".hermes/skills"], readonly ["windsurf", ".windsurf/skills"], readonly ["pi", ".pi/agent/skills"], readonly ["amp", ".amp/skills"], readonly ["cline", ".cline/skills"], readonly ["roo", ".roo/skills"], readonly ["copilot", ".github/skills"]];
|
|
3
|
+
/** Supplemental Sumi project tiers are shared with inventory. The caller
|
|
4
|
+
* supplies Sumi's owning resolver so this root contract has no runtime or
|
|
5
|
+
* enrollment dependency. Authoring can still exclude the shared tiers when
|
|
6
|
+
* the Sumi resolver is absent. */
|
|
7
|
+
export declare function nativeSumiProjectSkillRoots(home: string, project: string, resolveSumiRoots: (home: string, project: string) => readonly string[]): string[];
|
|
8
|
+
/** Native project discovery includes every ancestor. Keep inventory and
|
|
9
|
+
* authoring on this same bounded context enumeration. */
|
|
10
|
+
export declare function nativeProjectAncestorDirectories(projects: readonly string[], canonical?: (path: string) => string): string[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare const NATIVE_DRIFT_RECEIPT_SCHEMA = "hasna.skills.native-drift-receipt.v1";
|
|
2
|
+
export declare const NATIVE_DRIFT_RECEIPT_DIRECTORY = "native-drift";
|
|
3
|
+
/** A native tool-policy refusal: denying a native payload skill is the
|
|
4
|
+
* protection that keeps a drifted station safe, so it is never failed open. */
|
|
5
|
+
export declare class NativeSkillPolicyRefusal extends Error {
|
|
6
|
+
}
|
|
7
|
+
/** The skills-cli bridge itself could not be verified: it is missing or
|
|
8
|
+
* modified, or the managed binding that names it is missing, incompatible or
|
|
9
|
+
* no longer resolves. A tool call that would load the bridge is refused; a
|
|
10
|
+
* prompt, session or subagent event fails open with NATIVE_DRIFT_BRIDGE_NOTICE. */
|
|
11
|
+
export declare class NativeBridgeIntegrityRefusal extends NativeSkillPolicyRefusal {
|
|
12
|
+
}
|
|
13
|
+
export declare function isNativeSkillDrift(error: unknown): error is Error;
|
|
14
|
+
export declare function isNativeBridgeIntegrityRefusal(error: unknown): error is NativeBridgeIntegrityRefusal;
|
|
15
|
+
/** Escape controls, format characters and line separators as \uXXXX so a path
|
|
16
|
+
* from the file system cannot hide or reorder warning text, then bound it. */
|
|
17
|
+
export declare function boundedDriftReason(message: string, limit?: number): string;
|
|
18
|
+
export declare function nativeDriftRepair(agent: string): string;
|
|
19
|
+
/** One visible line: what happened, the bounded drift reason (it names the
|
|
20
|
+
* changed path or copies), the repair command and the receipt path. */
|
|
21
|
+
export declare function nativeDriftWarning(agent: string, message: string, receiptPath: string | null): string;
|
|
22
|
+
/** Fixed agent-facing notice for the turn whose Skills context was omitted. */
|
|
23
|
+
export declare const NATIVE_DRIFT_AGENT_NOTICE = "Skills context is unavailable for this turn because the station's native skill discovery changed; the change was reported to the operator. Continue the user's task. Load a selected skill explicitly with `skills load <slug>` if one is needed, and do not load native skill copies.";
|
|
24
|
+
/** Fixed agent-facing notice when the skills-cli bridge itself is unverified:
|
|
25
|
+
* the bridge tool is refused this turn, so the agent uses the CLI instead. */
|
|
26
|
+
export declare const NATIVE_DRIFT_BRIDGE_NOTICE = "Skills context is unavailable for this turn because the station's skills-cli bridge could not be verified; the change was reported to the operator. Continue the user's task, but do not invoke the skills-cli native skill until it is repaired. Run the `skills` command directly (for example `skills load <slug>`) if a skill is needed, and do not load native skill copies.";
|
|
27
|
+
export interface NativeDriftReceipt {
|
|
28
|
+
schema: typeof NATIVE_DRIFT_RECEIPT_SCHEMA;
|
|
29
|
+
agent: string;
|
|
30
|
+
status: "active" | "cleared";
|
|
31
|
+
code: "NATIVE_SKILL_DRIFT";
|
|
32
|
+
event: string;
|
|
33
|
+
promptBlocked: false;
|
|
34
|
+
skillsContext: "omitted";
|
|
35
|
+
reason: string;
|
|
36
|
+
reasonSha256: string;
|
|
37
|
+
repair: string;
|
|
38
|
+
firstSeenAt: string;
|
|
39
|
+
lastSeenAt: string;
|
|
40
|
+
occurrences: number;
|
|
41
|
+
clearedAt?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function nativeDriftReceiptPath(dataDir: string, agent: string): string;
|
|
44
|
+
/** Record or refresh the active receipt for this agent. Never throws: the
|
|
45
|
+
* warning says when the receipt could not be recorded. */
|
|
46
|
+
export declare function recordNativeDriftReceipt(dataDir: string, agent: string, event: string, message: string, now?: Date): string | null;
|
|
47
|
+
/** After a clean verification: mark an active receipt cleared, keeping its
|
|
48
|
+
* history. Absent or already cleared receipts are left untouched. */
|
|
49
|
+
export declare function clearNativeDriftReceipt(dataDir: string, agent: string, now?: Date): void;
|
|
50
|
+
/** Every readable receipt, for operators and monitors. */
|
|
51
|
+
export declare function readNativeDriftReceipts(dataDir: string): NativeDriftReceipt[];
|
|
52
|
+
/** The non-blocking envelope for drift, in each native adapter's own shape. */
|
|
53
|
+
export declare function nativeDriftFailOpen(dataDir: string, agent: string, event: string, nativeEvent: string, message: string, options?: {
|
|
54
|
+
bridgeUnverified?: boolean;
|
|
55
|
+
}): Record<string, unknown>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const OPENCODE_BRIDGE_BODY_SHA256: string;
|
|
2
|
+
export declare const OPENCODE_BRIDGE_DESCRIPTION_SHA256: string;
|
|
3
|
+
export declare function isVerifiedOpenCodeSkillDescriptor(value: unknown, expectedPath: string): boolean;
|
|
4
|
+
/** Explicit adapter phase, including empty attachment-only prompt admission. */
|
|
5
|
+
export declare function openCodeContextDelivery(input: unknown): boolean;
|
|
@@ -20,6 +20,7 @@ export declare class HttpProfileClient implements ProfileClient {
|
|
|
20
20
|
private signal?;
|
|
21
21
|
readonly authority: string;
|
|
22
22
|
private origin;
|
|
23
|
+
private responseSignals;
|
|
23
24
|
constructor(key: string, origin: string, signal?: AbortSignal | undefined);
|
|
24
25
|
private requestRoute;
|
|
25
26
|
private request;
|
|
@@ -55,6 +55,25 @@ export declare function validateSelection(selection: ResolvedSkillSelection): vo
|
|
|
55
55
|
export declare function validateResolvedProfile(profile: ResolvedSkillProfile, authority?: string): void;
|
|
56
56
|
export declare function selectionBundlePath(selection: ResolvedSkillSelection, options?: SelectionCacheOptions): string;
|
|
57
57
|
export declare function writeSelectionJson(path: string, value: unknown): void;
|
|
58
|
+
/**
|
|
59
|
+
* Create a small private JSON file with exclusive, no-follow semantics. Returns
|
|
60
|
+
* false when the path already exists; never replaces anything.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createExclusiveSelectionJson(path: string, value: unknown, maximumBytes?: number): boolean;
|
|
63
|
+
/** A small private regular file's bytes and identity, or null when it is absent. */
|
|
64
|
+
export declare function readSelectionFileSnapshot(path: string, maximumBytes?: number): {
|
|
65
|
+
bytes: Uint8Array;
|
|
66
|
+
sha256: string;
|
|
67
|
+
mtimeMs: number;
|
|
68
|
+
dev: number;
|
|
69
|
+
ino: number;
|
|
70
|
+
} | null;
|
|
71
|
+
/** Remove a small private file only while it still holds exactly the inspected bytes and inode. */
|
|
72
|
+
export declare function removeSelectionFileIfUnchanged(path: string, expected: {
|
|
73
|
+
sha256: string;
|
|
74
|
+
dev: number;
|
|
75
|
+
ino: number;
|
|
76
|
+
}): boolean;
|
|
58
77
|
export declare function readSelectionJson<T>(path: string, maximumBytes?: number): T | null;
|
|
59
78
|
export declare function readCachedSelection(selection: ResolvedSkillSelection, options?: SelectionCacheOptions): Promise<SkillBundleEntry[] | null>;
|
|
60
79
|
/** Verify an authenticated exact-version response without changing any cache or receipt. */
|
|
@@ -93,6 +112,24 @@ export declare function inspectSessionWriteLock(sessionId: string, options?: Sel
|
|
|
93
112
|
hostBound: boolean;
|
|
94
113
|
};
|
|
95
114
|
export declare function recoverSessionWriteLock(sessionId: string, reviewDigest: string, options?: SelectionCacheOptions): string;
|
|
115
|
+
/**
|
|
116
|
+
* How long a receipt write waits for another live holder of a session write
|
|
117
|
+
* lock before it refuses with SESSION_WRITE_BUSY. Holders keep a lock only for
|
|
118
|
+
* one bounded receipt read-compare-write (or one archived replacement), so
|
|
119
|
+
* concurrent hooks of one session (a prompt and its subagents starting
|
|
120
|
+
* together) serialize instead of refusing. Waiting never replaces, recovers or
|
|
121
|
+
* ignores a lock: a held lock that outlives the wait still refuses.
|
|
122
|
+
*/
|
|
123
|
+
export declare const SESSION_WRITE_LOCK_WAIT_MS = 2000;
|
|
124
|
+
/**
|
|
125
|
+
* A context that writes nothing never takes the session write lock, so a
|
|
126
|
+
* live writer cannot make it wait or refuse. It still refuses, exactly as a
|
|
127
|
+
* writer would, when the lock path holds something that is not a structurally
|
|
128
|
+
* valid writer lock (SESSION_WRITE_LOCKED: damaged, foreign or unsafe state
|
|
129
|
+
* that needs recovery review). A lock that changes while it is inspected (a
|
|
130
|
+
* writer publishing or releasing it) is inspected again a few times first.
|
|
131
|
+
*/
|
|
132
|
+
export declare function assertSessionWriteLockReadable(sessionId: string, options?: SelectionCacheOptions): void;
|
|
96
133
|
/**
|
|
97
134
|
* Hold this session's receipt write lock for state that must change only with
|
|
98
135
|
* its pin (the managed-hook migration notice). Another holder refuses with
|
|
@@ -100,9 +137,17 @@ export declare function recoverSessionWriteLock(sessionId: string, reviewDigest:
|
|
|
100
137
|
*/
|
|
101
138
|
export declare function withSkillSessionWriteLock<T>(sessionId: string, options: SelectionCacheOptions, action: (assertOwned: () => void) => T): T;
|
|
102
139
|
export declare function nextSkillSessionGeneration(generation: number): number;
|
|
103
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Receipt creation and updates are exact-snapshot CAS operations. Child
|
|
142
|
+
* creation also fences its parent. Under contention this blocks the calling
|
|
143
|
+
* thread for at most SESSION_WRITE_LOCK_WAIT_MS.
|
|
144
|
+
*/
|
|
104
145
|
export declare function writeSkillSession(receipt: SkillSessionReceipt, expected: SkillSessionWritePrecondition, options?: SelectionCacheOptions): void;
|
|
105
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* Preserve both sides before the single atomic replacement; failures retain
|
|
148
|
+
* recovery evidence. Under contention this blocks the calling thread for at
|
|
149
|
+
* most SESSION_WRITE_LOCK_WAIT_MS.
|
|
150
|
+
*/
|
|
106
151
|
export declare function replaceSkillSession(expected: SkillSessionParentBinding, replacement: SkillSessionReceipt, plan: unknown, options?: SelectionCacheOptions, beforeCommit?: () => void): {
|
|
107
152
|
archivePath: string;
|
|
108
153
|
receiptPath: string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { SkillSelectionError, type SelectionCacheOptions } from "./selection-cache.js";
|
|
2
|
+
import { type SessionReconciliationOptions } from "./session-reconciliation.js";
|
|
3
|
+
/** The longest an expired-pin prompt waits for its background renewal. */
|
|
4
|
+
export declare const BACKGROUND_RENEWAL_WAIT_MS = 3000;
|
|
5
|
+
/** A lock older than this belongs to no live worker (the worker's own budget plus margin). */
|
|
6
|
+
export declare const BACKGROUND_RENEWAL_LOCK_TTL_MS: number;
|
|
7
|
+
/** A failed attempt for the same pin is reported again, not retried, within these windows. */
|
|
8
|
+
export declare const EXPIRED_RENEWAL_RETRY_MS = 30000;
|
|
9
|
+
export declare const AHEAD_RENEWAL_RETRY_MS: number;
|
|
10
|
+
export type BackgroundRenewalMode = "expired" | "ahead";
|
|
11
|
+
export type BackgroundRenewalStatus = "running" | "renewed" | "migrated" | "unchanged" | "failed";
|
|
12
|
+
export interface BackgroundRenewalState {
|
|
13
|
+
schemaVersion: 1;
|
|
14
|
+
kind: "session-pin-background-renewal";
|
|
15
|
+
sessionId: string;
|
|
16
|
+
profileId: string;
|
|
17
|
+
operationId: string;
|
|
18
|
+
/** verifiedAt of the exact pin this attempt renews. */
|
|
19
|
+
pinVerifiedAt: string;
|
|
20
|
+
mode: BackgroundRenewalMode;
|
|
21
|
+
status: BackgroundRenewalStatus;
|
|
22
|
+
startedAt: string;
|
|
23
|
+
finishedAt?: string;
|
|
24
|
+
workerPid?: number;
|
|
25
|
+
code?: string;
|
|
26
|
+
migrationTimeout?: true;
|
|
27
|
+
/** No worker could be started; such a record never delays the next attempt. */
|
|
28
|
+
notStarted?: true;
|
|
29
|
+
/**
|
|
30
|
+
* The exact request this attempt answers: the receipt bytes, mode,
|
|
31
|
+
* migration setting and prompt directory. A recorded failure is reused only
|
|
32
|
+
* for the same request; any change (a rewritten receipt, migration turned
|
|
33
|
+
* on, another directory) asks again at once.
|
|
34
|
+
*/
|
|
35
|
+
requestDigest?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface BackgroundRenewalRequest {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
profileId: string;
|
|
40
|
+
pinVerifiedAt: string;
|
|
41
|
+
mode: BackgroundRenewalMode;
|
|
42
|
+
/** SHA-256 of the exact receipt bytes this request read. */
|
|
43
|
+
receiptSha256: string;
|
|
44
|
+
/** Expired pins only: the managed hook's automatic migration of a refused renewal. */
|
|
45
|
+
migrate?: boolean;
|
|
46
|
+
/** The prompt's directory, which migration requires (project locks keep the refusal). */
|
|
47
|
+
projectDir?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface BackgroundRenewalOptions extends SelectionCacheOptions {
|
|
50
|
+
/**
|
|
51
|
+
* Tests replace the detached worker; production spawns `skills sessions
|
|
52
|
+
* renew-background`. `notStarted` is called if the worker fails to start
|
|
53
|
+
* after this returns (an asynchronous spawn error such as EAGAIN).
|
|
54
|
+
*/
|
|
55
|
+
spawnWorker?: (args: string[], notStarted: () => void) => void;
|
|
56
|
+
}
|
|
57
|
+
/** The identity of one renewal request; equal digests ask the authority the same question. */
|
|
58
|
+
export declare function backgroundRenewalRequestDigest(request: BackgroundRenewalRequest): string;
|
|
59
|
+
/**
|
|
60
|
+
* The last recorded attempt for this session, or null when absent or not
|
|
61
|
+
* exact. Only validated fields are returned; anything else in the file is
|
|
62
|
+
* dropped, so no unvalidated value reaches a caller's output.
|
|
63
|
+
*/
|
|
64
|
+
export declare function readBackgroundRenewalState(sessionId: string, options?: SelectionCacheOptions): BackgroundRenewalState | null;
|
|
65
|
+
export type BackgroundRenewalStart =
|
|
66
|
+
/** `operationId` names the attempt to wait for, when its lock is readable. */
|
|
67
|
+
{
|
|
68
|
+
status: "started" | "running";
|
|
69
|
+
operationId?: string;
|
|
70
|
+
}
|
|
71
|
+
/** `notStarted`: no worker could be started, so the caller may renew inline instead. */
|
|
72
|
+
| {
|
|
73
|
+
status: "failed";
|
|
74
|
+
state: BackgroundRenewalState;
|
|
75
|
+
notStarted?: true;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Start the session's background renewal unless one is running, or report a
|
|
79
|
+
* recent failure of the same pin without starting another.
|
|
80
|
+
*/
|
|
81
|
+
export declare function startBackgroundRenewal(request: BackgroundRenewalRequest, options?: BackgroundRenewalOptions): BackgroundRenewalStart;
|
|
82
|
+
export type BackgroundRenewalWait = {
|
|
83
|
+
status: "running" | "changed";
|
|
84
|
+
} | {
|
|
85
|
+
status: Exclude<BackgroundRenewalStatus, "running">;
|
|
86
|
+
state: BackgroundRenewalState;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Wait up to waitMs for the attempt renewing this exact pin to finish, or for
|
|
90
|
+
* the session receipt to stop holding that pin. With an operation id, only
|
|
91
|
+
* that attempt's outcome counts.
|
|
92
|
+
*/
|
|
93
|
+
export declare function awaitBackgroundRenewal(sessionId: string, pinVerifiedAt: string, waitMs: number, options?: SelectionCacheOptions, operationId?: string): Promise<BackgroundRenewalWait>;
|
|
94
|
+
export interface BackgroundRenewalRun {
|
|
95
|
+
status: BackgroundRenewalStatus | "superseded";
|
|
96
|
+
code?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The worker: renew (or, for an expired pin with migration on, migrate) one
|
|
100
|
+
* session pin with the background budget, record the outcome, release the lock.
|
|
101
|
+
*/
|
|
102
|
+
export declare function runBackgroundRenewal(sessionId: string, profileId: string, operationId: string, request: {
|
|
103
|
+
migrate?: boolean;
|
|
104
|
+
projectDir?: string;
|
|
105
|
+
}, options?: SessionReconciliationOptions): Promise<BackgroundRenewalRun>;
|
|
106
|
+
/**
|
|
107
|
+
* An expired pin whose background renewal is still running. It keeps the
|
|
108
|
+
* renewal timeout's code (fixed codes cross the hook boundary) and a fixed
|
|
109
|
+
* marker so the hook can say the renewal continues instead of restarting.
|
|
110
|
+
*/
|
|
111
|
+
export declare class SessionRenewalInBackground extends SkillSelectionError {
|
|
112
|
+
readonly renewal: "background";
|
|
113
|
+
constructor();
|
|
114
|
+
}
|
|
115
|
+
/** The recorded failure of a background attempt, as the error the inline renewal would have raised. */
|
|
116
|
+
export declare function backgroundRenewalError(state: BackgroundRenewalState): SkillSelectionError;
|
|
117
|
+
/** The pin's age class, from its verifiedAt; null when it is neither due nor expired. */
|
|
118
|
+
export declare function renewalModeFor(verifiedAt: string, now: number): BackgroundRenewalMode | null;
|