@lmzhen/dsh-evolution-core 0.13.5 → 0.14.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/lib/index.js +65 -18
- package/lib/types/skill-history.d.ts +45 -2
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -6489,25 +6489,67 @@ function versionTarget(action) {
|
|
|
6489
6489
|
return "other";
|
|
6490
6490
|
}
|
|
6491
6491
|
/**
|
|
6492
|
+
* Which artifact one INDEX ENTRY holds.
|
|
6493
|
+
*
|
|
6494
|
+
* {@link versionTarget} reads the ACTION, which is enough for the entries a write mints under its own
|
|
6495
|
+
* label and is NOT enough for a {@link BASELINE_ACTION}: a baseline minted for a support write holds
|
|
6496
|
+
* that FILE's previous bytes while its action says only "this is what was there". Two facts recover
|
|
6497
|
+
* the artifact:
|
|
6498
|
+
*
|
|
6499
|
+
* - `path` is written exactly when the bytes come from a support file, on BOTH entries one support
|
|
6500
|
+
* write can mint, so it decides on its own;
|
|
6501
|
+
* - an entry recorded before `path` existed has none, and the link is the evidence left: a support
|
|
6502
|
+
* write names the content it replaced through `beforeHash`, so a baseline that a support write
|
|
6503
|
+
* names as its predecessor holds that file's bytes.
|
|
6504
|
+
*
|
|
6505
|
+
* The inference runs only for a baseline. Every other entry keeps the action's verdict, which is also
|
|
6506
|
+
* the fail-closed one for an action this module does not know.
|
|
6507
|
+
* @param entry - one entry of a skill's index.
|
|
6508
|
+
* @param index - the index the entry came from: the legacy link is only readable across the whole
|
|
6509
|
+
* index. Omitting it answers from `path` and the action alone.
|
|
6510
|
+
* @returns the artifact class; `other` when nothing attributes the bytes.
|
|
6511
|
+
*/
|
|
6512
|
+
function entryTarget(entry, index = []) {
|
|
6513
|
+
if (entry.path !== void 0) return "support";
|
|
6514
|
+
if (entry.action !== "baseline") return versionTarget(entry.action);
|
|
6515
|
+
return index.some((candidate) => SUPPORT_ACTIONS.includes(candidate.action) && candidate.beforeHash === entry.hash) ? "support" : "other";
|
|
6516
|
+
}
|
|
6517
|
+
/**
|
|
6492
6518
|
* Split one index into the skill body's chain and the support files' versions.
|
|
6493
6519
|
*
|
|
6494
6520
|
* Both share ONE index, so a skill that ever wrote a support file has two chains and
|
|
6495
6521
|
* {@link orderVersions} cannot account for every entry (it falls back to the stored order). Splitting
|
|
6496
6522
|
* first lets each group rebuild its own order, and keeps the body's chain intact by leaving every
|
|
6497
|
-
* entry
|
|
6523
|
+
* entry whose artifact nothing attributes in it — a `baseline` predecessor is usually the body's
|
|
6524
|
+
* first link, and only the support-file baselines {@link entryTarget} recovers leave it.
|
|
6498
6525
|
* @param versions - the stored index, oldest first as recorded.
|
|
6499
6526
|
* @returns the two groups, each in content order when its chain is complete.
|
|
6500
6527
|
*/
|
|
6501
6528
|
function partitionVersions(versions) {
|
|
6502
6529
|
const content = [];
|
|
6503
6530
|
const support = [];
|
|
6504
|
-
for (const entry of versions) if (
|
|
6531
|
+
for (const entry of versions) if (entryTarget(entry, versions) === "support") support.push(entry);
|
|
6505
6532
|
else content.push(entry);
|
|
6506
6533
|
return {
|
|
6507
6534
|
content: orderVersions(content),
|
|
6508
6535
|
support: orderVersions(support)
|
|
6509
6536
|
};
|
|
6510
6537
|
}
|
|
6538
|
+
/**
|
|
6539
|
+
* When this skill's content last changed: the newest `at` across BOTH chains, or null when the index
|
|
6540
|
+
* holds nothing.
|
|
6541
|
+
*
|
|
6542
|
+
* The stored array is APPEND order and two writers of one skill can interleave, so the answer is the
|
|
6543
|
+
* maximum timestamp rather than the tail. Every `at` this family writes is the same ISO-8601 UTC
|
|
6544
|
+
* form, so comparing the strings is comparing the instants.
|
|
6545
|
+
* @param versions - every entry the index holds, in any order.
|
|
6546
|
+
* @returns the newest timestamp, or null when there is none to report.
|
|
6547
|
+
*/
|
|
6548
|
+
function latestVersionAt(versions) {
|
|
6549
|
+
let newest = null;
|
|
6550
|
+
for (const entry of versions) if (newest === null || entry.at > newest) newest = entry.at;
|
|
6551
|
+
return newest;
|
|
6552
|
+
}
|
|
6511
6553
|
/** Keep nothing less than one version, whatever the deployment asks for. */
|
|
6512
6554
|
function clampKeep(keep) {
|
|
6513
6555
|
return Number.isFinite(keep) ? Math.max(1, Math.floor(keep)) : 1;
|
|
@@ -6535,21 +6577,20 @@ function readVersionEntry(entry) {
|
|
|
6535
6577
|
if (typeof candidate.action !== "string") return null;
|
|
6536
6578
|
if (typeof candidate.chars !== "number") return null;
|
|
6537
6579
|
const summary = typeof candidate.summary === "string" && candidate.summary !== "" ? candidate.summary : void 0;
|
|
6580
|
+
const path = typeof candidate.path === "string" && candidate.path !== "" ? candidate.path : void 0;
|
|
6538
6581
|
const base = {
|
|
6539
6582
|
v: candidate.v,
|
|
6540
6583
|
at: candidate.at,
|
|
6541
6584
|
action: candidate.action,
|
|
6542
6585
|
hash: candidate.hash,
|
|
6543
|
-
chars: candidate.chars
|
|
6586
|
+
chars: candidate.chars,
|
|
6587
|
+
...summary === void 0 ? {} : { summary },
|
|
6588
|
+
...path === void 0 ? {} : { path }
|
|
6544
6589
|
};
|
|
6545
6590
|
return typeof candidate.beforeHash === "string" && candidate.beforeHash !== "" ? {
|
|
6546
6591
|
...base,
|
|
6547
|
-
beforeHash: candidate.beforeHash
|
|
6548
|
-
|
|
6549
|
-
} : {
|
|
6550
|
-
...base,
|
|
6551
|
-
...summary === void 0 ? {} : { summary }
|
|
6552
|
-
};
|
|
6592
|
+
beforeHash: candidate.beforeHash
|
|
6593
|
+
} : base;
|
|
6553
6594
|
}
|
|
6554
6595
|
/**
|
|
6555
6596
|
* Read one index body for a RECORDER: "understood", "no file", or "cannot be understood".
|
|
@@ -6609,12 +6650,14 @@ function nextHistoryIndex(versions, input, keep) {
|
|
|
6609
6650
|
const beforeHash = input.before === null ? null : contentHash(input.before);
|
|
6610
6651
|
const afterHash = input.after === null ? null : contentHash(input.after);
|
|
6611
6652
|
const grown = [...versions];
|
|
6653
|
+
const pathField = input.path === void 0 ? {} : { path: input.path };
|
|
6612
6654
|
if (beforeHash !== null && !grown.some((entry) => entry.hash === beforeHash)) grown.push({
|
|
6613
6655
|
v: nextVersion(grown),
|
|
6614
6656
|
at: input.at,
|
|
6615
6657
|
action: BASELINE_ACTION,
|
|
6616
6658
|
hash: beforeHash,
|
|
6617
|
-
chars: input.before?.length ?? 0
|
|
6659
|
+
chars: input.before?.length ?? 0,
|
|
6660
|
+
...pathField
|
|
6618
6661
|
});
|
|
6619
6662
|
if (afterHash !== null) {
|
|
6620
6663
|
if (grown[grown.length - 1]?.hash !== afterHash) grown.push({
|
|
@@ -6623,6 +6666,7 @@ function nextHistoryIndex(versions, input, keep) {
|
|
|
6623
6666
|
action: input.action,
|
|
6624
6667
|
hash: afterHash,
|
|
6625
6668
|
chars: input.after?.length ?? 0,
|
|
6669
|
+
...pathField,
|
|
6626
6670
|
...input.summary === void 0 ? {} : { summary: input.summary },
|
|
6627
6671
|
...beforeHash === null ? {} : { beforeHash }
|
|
6628
6672
|
});
|
|
@@ -7485,7 +7529,7 @@ var SkillLibrary = class {
|
|
|
7485
7529
|
if (o.ghostDir === true) await this.cleanupGhostDir(path);
|
|
7486
7530
|
let result = o.result;
|
|
7487
7531
|
if (o.write !== null && o.audit) {
|
|
7488
|
-
await this.audit(o.audit.skillName, o.audit.action, o.audit.before, o.audit.after, o.audit.summary);
|
|
7532
|
+
await this.audit(o.audit.skillName, o.audit.action, o.audit.before, o.audit.after, o.audit.summary, o.audit.path);
|
|
7489
7533
|
const retention = contentRetentionFeedback({
|
|
7490
7534
|
name: o.audit.skillName,
|
|
7491
7535
|
action: o.audit.action,
|
|
@@ -7810,18 +7854,20 @@ var SkillLibrary = class {
|
|
|
7810
7854
|
* mutation ledger that points at it. The history failure is not silent — a deployment whose
|
|
7811
7855
|
* history stopped growing is a degradation worth seeing once (the ledger keeps hashes either
|
|
7812
7856
|
* way). */
|
|
7813
|
-
async audit(skillName, action, before, after, summary) {
|
|
7857
|
+
async audit(skillName, action, before, after, summary, path) {
|
|
7814
7858
|
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
7815
7859
|
let versions = null;
|
|
7816
7860
|
try {
|
|
7817
7861
|
const keep = this.limits.versionKeep ?? 20;
|
|
7818
|
-
|
|
7862
|
+
const input = {
|
|
7819
7863
|
skillName,
|
|
7820
7864
|
action,
|
|
7821
7865
|
before,
|
|
7822
7866
|
after,
|
|
7823
|
-
at
|
|
7824
|
-
|
|
7867
|
+
at,
|
|
7868
|
+
...path === void 0 ? {} : { path }
|
|
7869
|
+
};
|
|
7870
|
+
versions = await recordVersions(this.root, this.io, input, keep);
|
|
7825
7871
|
} catch (error) {
|
|
7826
7872
|
if (!this.historyWarned) {
|
|
7827
7873
|
this.historyWarned = true;
|
|
@@ -9230,7 +9276,8 @@ var SkillLibrary = class {
|
|
|
9230
9276
|
action: "write_file",
|
|
9231
9277
|
before: current,
|
|
9232
9278
|
after: content,
|
|
9233
|
-
summary: `wrote ${filePath}
|
|
9279
|
+
summary: `wrote ${filePath}`,
|
|
9280
|
+
path: filePath
|
|
9234
9281
|
},
|
|
9235
9282
|
event: {
|
|
9236
9283
|
action: "write_file",
|
|
@@ -9293,7 +9340,7 @@ var SkillLibrary = class {
|
|
|
9293
9340
|
};
|
|
9294
9341
|
} else if (verdict === "match") await this.io.remove(target);
|
|
9295
9342
|
if (verdict !== "match") return anchorRefusalFile(name, filePath, verdict);
|
|
9296
|
-
await this.audit(name, "remove_file", before, null, `removed ${filePath}
|
|
9343
|
+
await this.audit(name, "remove_file", before, null, `removed ${filePath}`, filePath);
|
|
9297
9344
|
this.notifyMutation({
|
|
9298
9345
|
action: "remove_file",
|
|
9299
9346
|
name,
|
|
@@ -11159,4 +11206,4 @@ function sessionAudited(ctx, sessionId, sessionScoped) {
|
|
|
11159
11206
|
return false;
|
|
11160
11207
|
}
|
|
11161
11208
|
//#endregion
|
|
11162
|
-
export { ALIVE_LOCK_TAKEOVER_MS, AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEAD_LOCK_TAKEOVER_MS, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, EMPTY_LOCK_TAKEOVER_MS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, INSTANCE_KEYS, KEEP_LINE_RE, LOCK_BODY_RE, LOCK_SUFFIX, LOCK_TEAR_TAKEOVER_MS, LOW_QUALITY_THRESHOLD, LostWriteLock, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MUTATIONS_FILE_VERSION, MemoryStore, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UPSTREAM_LIMIT_CHARS_PER_TOKEN, VERSION_SUMMARY_MAX_CHARS, advanceReview, affinity, allowRowCollisions, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyReferenceRewrite, assertDispatchPayload, assertSkillsRootAliasRetired, assessStructureHealth, authoringFeedback, blobPath, bodyCost, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, canonicalWriteId, claimInstance, clampedNumber, clearReviewChannel, collectReadSkillNames, composePresetComposition, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, createGateSet, daysSinceIso, decideTakeover, describeReferenceRewrite, duplicateHeadings, elapsedSince, emptyRecord, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionEventPayloadIssue, evolutionHome, evolutionIoAdapter, evolutionRoot, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurn, frontmatterBlock, frontmatterCatalogInvalid, getRecord, historyIndexFile, historyRoot, identity, idleDays, installParamSection, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, latestActivityAt, lifecycleCandidate, listEventArchives, loadMutations, loadRowOverrides, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, neutralizePromptVariables, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramSectionOverrides, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, parseLockBody, partitionVersions, pendingSelfCleanup, persistedWriteSite, persistedWriteSites, planReferenceRewrite, planRehoming, policyStageLimits, probeAbsent, probeList, probeMtime, probePresent, probeReason, probeUnknown, projectionText, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readNumberParam, readParam, recordMutation, recordVersions, redactSecrets, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, retainEventArchives, retirementReport, reviewPrompt, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopedProbeReport, sessionAudited, sessionReadSkillNames, sessionSeesFamilyTools, skillReadNameOf, skillsRoot, supportFileReadOf, suppressedFile, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, unhookedSupportPointers, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, validateRestructureTarget, valueOr, verifyPromptBundle, versionActionKind, versionSummaryPrompt, versionTarget, vocabulary, writeDurableTmp, yamlPlainScalarNeedsQuotes };
|
|
11209
|
+
export { ALIVE_LOCK_TAKEOVER_MS, AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEAD_LOCK_TAKEOVER_MS, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, EMPTY_LOCK_TAKEOVER_MS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, INSTANCE_KEYS, KEEP_LINE_RE, LOCK_BODY_RE, LOCK_SUFFIX, LOCK_TEAR_TAKEOVER_MS, LOW_QUALITY_THRESHOLD, LostWriteLock, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MUTATIONS_FILE_VERSION, MemoryStore, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UPSTREAM_LIMIT_CHARS_PER_TOKEN, VERSION_SUMMARY_MAX_CHARS, advanceReview, affinity, allowRowCollisions, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyReferenceRewrite, assertDispatchPayload, assertSkillsRootAliasRetired, assessStructureHealth, authoringFeedback, blobPath, bodyCost, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, canonicalWriteId, claimInstance, clampedNumber, clearReviewChannel, collectReadSkillNames, composePresetComposition, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, createGateSet, daysSinceIso, decideTakeover, describeReferenceRewrite, duplicateHeadings, elapsedSince, emptyRecord, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionEventPayloadIssue, evolutionHome, evolutionIoAdapter, evolutionRoot, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurn, frontmatterBlock, frontmatterCatalogInvalid, getRecord, historyIndexFile, historyRoot, identity, idleDays, installParamSection, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, latestActivityAt, latestVersionAt, lifecycleCandidate, listEventArchives, loadMutations, loadRowOverrides, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, neutralizePromptVariables, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramSectionOverrides, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, parseLockBody, partitionVersions, pendingSelfCleanup, persistedWriteSite, persistedWriteSites, planReferenceRewrite, planRehoming, policyStageLimits, probeAbsent, probeList, probeMtime, probePresent, probeReason, probeUnknown, projectionText, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readNumberParam, readParam, recordMutation, recordVersions, redactSecrets, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, retainEventArchives, retirementReport, reviewPrompt, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopedProbeReport, sessionAudited, sessionReadSkillNames, sessionSeesFamilyTools, skillReadNameOf, skillsRoot, supportFileReadOf, suppressedFile, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, unhookedSupportPointers, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, validateRestructureTarget, valueOr, verifyPromptBundle, versionActionKind, versionSummaryPrompt, versionTarget, vocabulary, writeDurableTmp, yamlPlainScalarNeedsQuotes };
|
|
@@ -54,6 +54,13 @@ export interface SkillVersion {
|
|
|
54
54
|
* (registry `skillVersionSummary`). Absent is a first-class state: the faces say so instead of
|
|
55
55
|
* inventing a sentence, and a version recorded before the feature existed simply has none. */
|
|
56
56
|
summary?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Which support file these bytes came from, RELATIVE to the skill directory (`references/foo.md`),
|
|
59
|
+
* when this entry records a support-file write or remove. Absent is a first-class state: content
|
|
60
|
+
* versions never carry it, and every entry recorded before this field existed has none — the bytes
|
|
61
|
+
* in the blob store do not carry the name, so a legacy entry stays nameless rather than guessed.
|
|
62
|
+
*/
|
|
63
|
+
path?: string;
|
|
57
64
|
}
|
|
58
65
|
/** One history write, carrying the content the caller already holds. */
|
|
59
66
|
export interface VersionRecordInput {
|
|
@@ -66,6 +73,8 @@ export interface VersionRecordInput {
|
|
|
66
73
|
at: string;
|
|
67
74
|
/** The one-line summary of THIS write, or undefined when the deployment does not summarize. */
|
|
68
75
|
summary?: string;
|
|
76
|
+
/** The support file this write touched, relative to the skill directory; undefined for content. */
|
|
77
|
+
path?: string;
|
|
69
78
|
}
|
|
70
79
|
/** The version numbers one write produced; a side with no content contributes nothing. */
|
|
71
80
|
export interface RecordedVersions {
|
|
@@ -108,9 +117,31 @@ export type VersionTarget = 'content' | 'support' | 'other';
|
|
|
108
117
|
* @returns the artifact class; `other` when the label does not say.
|
|
109
118
|
*/
|
|
110
119
|
export declare function versionTarget(action: string): VersionTarget;
|
|
120
|
+
/**
|
|
121
|
+
* Which artifact one INDEX ENTRY holds.
|
|
122
|
+
*
|
|
123
|
+
* {@link versionTarget} reads the ACTION, which is enough for the entries a write mints under its own
|
|
124
|
+
* label and is NOT enough for a {@link BASELINE_ACTION}: a baseline minted for a support write holds
|
|
125
|
+
* that FILE's previous bytes while its action says only "this is what was there". Two facts recover
|
|
126
|
+
* the artifact:
|
|
127
|
+
*
|
|
128
|
+
* - `path` is written exactly when the bytes come from a support file, on BOTH entries one support
|
|
129
|
+
* write can mint, so it decides on its own;
|
|
130
|
+
* - an entry recorded before `path` existed has none, and the link is the evidence left: a support
|
|
131
|
+
* write names the content it replaced through `beforeHash`, so a baseline that a support write
|
|
132
|
+
* names as its predecessor holds that file's bytes.
|
|
133
|
+
*
|
|
134
|
+
* The inference runs only for a baseline. Every other entry keeps the action's verdict, which is also
|
|
135
|
+
* the fail-closed one for an action this module does not know.
|
|
136
|
+
* @param entry - one entry of a skill's index.
|
|
137
|
+
* @param index - the index the entry came from: the legacy link is only readable across the whole
|
|
138
|
+
* index. Omitting it answers from `path` and the action alone.
|
|
139
|
+
* @returns the artifact class; `other` when nothing attributes the bytes.
|
|
140
|
+
*/
|
|
141
|
+
export declare function entryTarget(entry: SkillVersion, index?: readonly SkillVersion[]): VersionTarget;
|
|
111
142
|
/** The versions of one skill, split by the artifact they hold. */
|
|
112
143
|
export interface VersionGroups {
|
|
113
|
-
/** The body's versions, plus predecessors
|
|
144
|
+
/** The body's versions, plus predecessors no evidence attributes to a support file. */
|
|
114
145
|
readonly content: SkillVersion[];
|
|
115
146
|
/** Support-file versions: real history, but not restorable over SKILL.md. */
|
|
116
147
|
readonly support: SkillVersion[];
|
|
@@ -121,11 +152,23 @@ export interface VersionGroups {
|
|
|
121
152
|
* Both share ONE index, so a skill that ever wrote a support file has two chains and
|
|
122
153
|
* {@link orderVersions} cannot account for every entry (it falls back to the stored order). Splitting
|
|
123
154
|
* first lets each group rebuild its own order, and keeps the body's chain intact by leaving every
|
|
124
|
-
* entry
|
|
155
|
+
* entry whose artifact nothing attributes in it — a `baseline` predecessor is usually the body's
|
|
156
|
+
* first link, and only the support-file baselines {@link entryTarget} recovers leave it.
|
|
125
157
|
* @param versions - the stored index, oldest first as recorded.
|
|
126
158
|
* @returns the two groups, each in content order when its chain is complete.
|
|
127
159
|
*/
|
|
128
160
|
export declare function partitionVersions(versions: readonly SkillVersion[]): VersionGroups;
|
|
161
|
+
/**
|
|
162
|
+
* When this skill's content last changed: the newest `at` across BOTH chains, or null when the index
|
|
163
|
+
* holds nothing.
|
|
164
|
+
*
|
|
165
|
+
* The stored array is APPEND order and two writers of one skill can interleave, so the answer is the
|
|
166
|
+
* maximum timestamp rather than the tail. Every `at` this family writes is the same ISO-8601 UTC
|
|
167
|
+
* form, so comparing the strings is comparing the instants.
|
|
168
|
+
* @param versions - every entry the index holds, in any order.
|
|
169
|
+
* @returns the newest timestamp, or null when there is none to report.
|
|
170
|
+
*/
|
|
171
|
+
export declare function latestVersionAt(versions: readonly SkillVersion[]): string | null;
|
|
129
172
|
/** What one index file's bytes said. `absent` (no file yet) and `unreadable` (bytes that cannot be
|
|
130
173
|
* understood: malformed JSON, a foreign shape, an entry this reader would have to drop, or a writer
|
|
131
174
|
* NEWER than this reader) are DIFFERENT facts — the recorder must never replace the second with an
|
package/package.json
CHANGED