sneakoscope 10.3.5 → 10.3.6
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 +2 -2
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/init/skills.js +34 -4
- package/dist/core/update/temporary-install-smoke.js +42 -13
- package/dist/core/update-check.js +2 -2
- package/dist/core/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.
|
|
17
17
|
<!-- END SKS SEARCH VISIBILITY MARKETING -->
|
|
18
18
|
|
|
19
|
-
Current package: **SKS 10.3.
|
|
19
|
+
Current package: **SKS 10.3.6**. Install the latest stable release from npm.
|
|
20
20
|
|
|
21
21
|
[Quick start](#install-in-one-command) · [Commands](#everyday-commands) · [SKS Center](#sks-center-macos) · [Documentation](#documentation) · [Changelog](CHANGELOG.md)
|
|
22
22
|
|
|
@@ -195,7 +195,7 @@ also picks the pipeline for each prompt; an explicit SKS `<div align="center">
|
|
|
195
195
|
Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.
|
|
196
196
|
<!-- END SKS SEARCH VISIBILITY MARKETING -->
|
|
197
197
|
|
|
198
|
-
Current package: **SKS 10.3.
|
|
198
|
+
Current package: **SKS 10.3.6**. Install the latest stable release from npm.
|
|
199
199
|
|
|
200
200
|
[Quick start](#install-in-one-command) · [Commands](#everyday-commands) · [SKS Center](#sks-center-macos) · [Documentation](#documentation) · [Changelog](CHANGELOG.md)
|
|
201
201
|
|
package/dist/core/init/skills.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fsp from 'node:fs/promises';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import { exists, nowIso, PACKAGE_VERSION, readJson, readText, sha256, withScratchDir, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
4
|
+
import { exists, nowIso, PACKAGE_VERSION, packageRoot, readJson, readText, sha256, which, withScratchDir, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
5
5
|
import { buildSksCoreSkillManifest, isCoreSkillName, legacyCoreSkillNames } from '../codex-native/core-skill-manifest.js';
|
|
6
6
|
import { syncCoreSkillsIntegrity } from '../codex-native/core-skill-integrity.js';
|
|
7
7
|
import { managedSkillGenerationLockPath, withManagedSkillGenerationLock } from '../codex-native/managed-skill-generation-lock.js';
|
|
@@ -682,11 +682,14 @@ async function reconcileSkillsUnlocked(opts) {
|
|
|
682
682
|
if (installedMarker?.generated_by === 'sneakoscope') {
|
|
683
683
|
const installedVersion = String(installedMarker?.version || '').trim();
|
|
684
684
|
const versionOrder = compareSemVer(installedVersion, PACKAGE_VERSION);
|
|
685
|
-
|
|
685
|
+
const activeNewer = versionOrder === 1 ? await activeNewerSksOnPath(PACKAGE_VERSION) : null;
|
|
686
|
+
if (activeNewer) {
|
|
686
687
|
report.ok = false;
|
|
687
|
-
report.warnings.push(`managed_skill_generation_downgrade_refused:${installedVersion}:runtime_${PACKAGE_VERSION}`);
|
|
688
|
+
report.warnings.push(`managed_skill_generation_downgrade_refused:${installedVersion}:runtime_${PACKAGE_VERSION}:path_${activeNewer}`);
|
|
688
689
|
return report;
|
|
689
690
|
}
|
|
691
|
+
if (versionOrder === 1)
|
|
692
|
+
report.warnings.push(`managed_skill_generation_reclaimed_from_${installedVersion}`);
|
|
690
693
|
const installedBuildTime = Number(installedMarker?.runtime_build_source_time);
|
|
691
694
|
const currentBuildTime = await runtimeBuildSourceTime();
|
|
692
695
|
const installedGeneration = String(installedMarker?.skill_generation_sha256 || '');
|
|
@@ -697,7 +700,8 @@ async function reconcileSkillsUnlocked(opts) {
|
|
|
697
700
|
&& Number.isFinite(installedBuildTime)
|
|
698
701
|
&& installedBuildTime > 0
|
|
699
702
|
&& currentBuildTime !== null
|
|
700
|
-
&& installedBuildTime > currentBuildTime
|
|
703
|
+
&& installedBuildTime > currentBuildTime
|
|
704
|
+
&& await activeNewerSksOnPath(PACKAGE_VERSION, installedBuildTime)) {
|
|
701
705
|
report.ok = false;
|
|
702
706
|
report.warnings.push(`managed_skill_same_version_older_build_refused:${currentBuildTime}:installed_${installedBuildTime}`);
|
|
703
707
|
return report;
|
|
@@ -1384,3 +1388,29 @@ async function removeEmptyGeneratedParents(root, rel) {
|
|
|
1384
1388
|
if (rel.startsWith('.codex/skills/'))
|
|
1385
1389
|
await removeDirIfEmpty(path.join(root, '.codex', 'skills'));
|
|
1386
1390
|
}
|
|
1391
|
+
async function activeNewerSksOnPath(runtimeVersion, sameVersionBuildTime = null) {
|
|
1392
|
+
const bin = await which('sks').catch(() => null);
|
|
1393
|
+
if (!bin)
|
|
1394
|
+
return null;
|
|
1395
|
+
let dir = path.dirname(await fsp.realpath(bin).catch(() => bin));
|
|
1396
|
+
for (let depth = 0; depth < 5; depth += 1) {
|
|
1397
|
+
const manifest = await readJson(path.join(dir, 'package.json'), null).catch(() => null);
|
|
1398
|
+
if (manifest?.name === 'sneakoscope' && typeof manifest.version === 'string') {
|
|
1399
|
+
const order = compareSemVer(manifest.version, runtimeVersion);
|
|
1400
|
+
if (order === 1)
|
|
1401
|
+
return manifest.version;
|
|
1402
|
+
if (order === 0 && sameVersionBuildTime !== null && path.resolve(dir) !== path.resolve(packageRoot())) {
|
|
1403
|
+
const stamp = await readJson(path.join(dir, 'dist', '.sks-build-stamp.json'), null).catch(() => null);
|
|
1404
|
+
const built = Number(stamp?.built_at_source_time);
|
|
1405
|
+
if (Number.isFinite(built) && built >= sameVersionBuildTime)
|
|
1406
|
+
return manifest.version;
|
|
1407
|
+
}
|
|
1408
|
+
return null;
|
|
1409
|
+
}
|
|
1410
|
+
const parent = path.dirname(dir);
|
|
1411
|
+
if (parent === dir)
|
|
1412
|
+
break;
|
|
1413
|
+
dir = parent;
|
|
1414
|
+
}
|
|
1415
|
+
return null;
|
|
1416
|
+
}
|
|
@@ -4,6 +4,11 @@ import path from 'node:path';
|
|
|
4
4
|
import { readJson, runProcess } from '../fsx.js';
|
|
5
5
|
import { runPackageLocalDoctor } from './update-migration-state.js';
|
|
6
6
|
import { compareSemVer, extractSemVer } from './semver.js';
|
|
7
|
+
export function isPublishPropagationError(text) {
|
|
8
|
+
return /\bE404\b|\bETARGET\b|No matching version found|404 Not Found - GET [^\s]+\.tgz/i.test(text);
|
|
9
|
+
}
|
|
10
|
+
export const PUBLISH_PROPAGATION_WAIT_MS = 6 * 60 * 1000;
|
|
11
|
+
const PUBLISH_PROPAGATION_RETRY_MS = 20 * 1000;
|
|
7
12
|
export async function runTemporaryInstallSmoke(input) {
|
|
8
13
|
const npmArgs = [];
|
|
9
14
|
if (input.env.SKS_UPDATE_SKIP_TEMP_INSTALL_SMOKE === '1') {
|
|
@@ -19,21 +24,38 @@ export async function runTemporaryInstallSmoke(input) {
|
|
|
19
24
|
entrypoint = path.resolve(fixtureEntrypoint);
|
|
20
25
|
}
|
|
21
26
|
else {
|
|
22
|
-
npmArgs.push('install', '--prefix', temp, `${input.packageName}@${input.version}`, '--registry', input.registry, '--ignore-scripts', '--no-audit', '--no-fund');
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
npmArgs.push('install', '--prefix', temp, `${input.packageName}@${input.version}`, '--registry', input.registry, '--ignore-scripts', '--no-audit', '--no-fund', '--prefer-online');
|
|
28
|
+
const waitBudget = publishWaitBudgetMs(input.env);
|
|
29
|
+
const sleep = input.sleep || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
30
|
+
const started = Date.now();
|
|
31
|
+
let install;
|
|
32
|
+
for (;;) {
|
|
33
|
+
install = await runProcess(input.npmBin, npmArgs, {
|
|
34
|
+
cwd: temp,
|
|
35
|
+
env: input.env,
|
|
36
|
+
timeoutMs: input.timeoutMs ?? 3 * 60 * 1000,
|
|
37
|
+
maxOutputBytes: input.maxOutputBytes ?? 128 * 1024
|
|
38
|
+
}).catch((error) => ({
|
|
39
|
+
code: 1,
|
|
40
|
+
stdout: '',
|
|
41
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
42
|
+
timedOut: false
|
|
43
|
+
}));
|
|
44
|
+
const output = `${install.stderr || ''}\n${install.stdout || ''}`;
|
|
45
|
+
const waited = Date.now() - started;
|
|
46
|
+
if (install.code === 0 || !isPublishPropagationError(output) || waited >= waitBudget)
|
|
47
|
+
break;
|
|
48
|
+
input.onPublishWait?.(waited);
|
|
49
|
+
await sleep(Math.min(PUBLISH_PROPAGATION_RETRY_MS, waitBudget - waited));
|
|
50
|
+
}
|
|
34
51
|
installCode = install.code;
|
|
52
|
+
const waitedMs = Date.now() - started;
|
|
35
53
|
if (install.code !== 0) {
|
|
36
|
-
|
|
54
|
+
const output = String(install.stderr || install.stdout || 'temporary npm install failed').trim();
|
|
55
|
+
const pendingMessage = `${input.packageName}@${input.version} is published but npm has not finished distributing it (waited ${Math.round(waitedMs / 1000)}s). Your current version keeps working; run sks update again in a few minutes.`;
|
|
56
|
+
return isPublishPropagationError(output)
|
|
57
|
+
? { ...result(input, npmArgs, false, 'not_yet_downloadable', installCode, null, null, null, null, pendingMessage), publish_wait_ms: waitedMs }
|
|
58
|
+
: { ...result(input, npmArgs, false, 'install_failed', installCode, null, null, null, null, output), publish_wait_ms: waitedMs };
|
|
37
59
|
}
|
|
38
60
|
const packageRoot = path.join(temp, 'node_modules', input.packageName);
|
|
39
61
|
const manifest = await readJson(path.join(packageRoot, 'package.json'), null).catch(() => null);
|
|
@@ -89,6 +111,13 @@ function result(input, npmArgs, ok, status, installCode, entrypoint, manifestVer
|
|
|
89
111
|
error
|
|
90
112
|
};
|
|
91
113
|
}
|
|
114
|
+
function publishWaitBudgetMs(env) {
|
|
115
|
+
const raw = env.SKS_UPDATE_PUBLISH_WAIT_MS;
|
|
116
|
+
if (raw === undefined || raw === '')
|
|
117
|
+
return PUBLISH_PROPAGATION_WAIT_MS;
|
|
118
|
+
const value = Number(raw);
|
|
119
|
+
return Number.isFinite(value) && value >= 0 ? value : PUBLISH_PROPAGATION_WAIT_MS;
|
|
120
|
+
}
|
|
92
121
|
async function regularFile(file) {
|
|
93
122
|
const stat = await fs.stat(file).catch(() => null);
|
|
94
123
|
return Boolean(stat?.isFile());
|
|
@@ -823,7 +823,7 @@ async function runSksUpdateNowInternal(options, rollbackAuthorization) {
|
|
|
823
823
|
registry,
|
|
824
824
|
env: nestedProcessEnv,
|
|
825
825
|
...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
|
|
826
|
-
...(options.maxOutputBytes === undefined ? {} : { maxOutputBytes: options.maxOutputBytes })
|
|
826
|
+
...(options.maxOutputBytes === undefined ? {} : { maxOutputBytes: options.maxOutputBytes }), ...(machineOutput ? {} : { onPublishWait: (waited) => process.stderr.write(` npm is still publishing ${packageName}@${installVersion}; waiting (${Math.round(waited / 1000)}s)...\n`) })
|
|
827
827
|
});
|
|
828
828
|
stage('temporary_install_smoke', temporaryInstallSmoke.ok, temporaryInstallSmoke.status, {
|
|
829
829
|
install_code: temporaryInstallSmoke.install_code,
|
|
@@ -846,7 +846,7 @@ async function runSksUpdateNowInternal(options, rollbackAuthorization) {
|
|
|
846
846
|
projectRoot: projectReceiptRoot,
|
|
847
847
|
registry,
|
|
848
848
|
globalRoot,
|
|
849
|
-
status: 'failed',
|
|
849
|
+
status: temporaryInstallSmoke.status === 'not_yet_downloadable' ? 'unavailable' : 'failed',
|
|
850
850
|
ok: false,
|
|
851
851
|
installCode: null,
|
|
852
852
|
oldVersionDoctor,
|
package/dist/core/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '10.3.
|
|
1
|
+
export const PACKAGE_VERSION = '10.3.6';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "10.3.
|
|
4
|
+
"version": "10.3.6",
|
|
5
5
|
"description": "Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|