sneakoscope 10.3.6 → 10.3.7
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/doctor/command-alias-cleanup.js +2 -0
- package/dist/core/doctor/skill-legacy-surface.js +46 -1
- package/dist/core/update/registry-availability.js +58 -0
- package/dist/core/update-check.js +8 -26
- 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.7**. 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.7**. 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
|
|
|
@@ -302,6 +302,7 @@ function emptySkillLegacySurface(fix) {
|
|
|
302
302
|
removed_other_harness_skill_count: 0,
|
|
303
303
|
preserved_other_harness_skill_count: 0,
|
|
304
304
|
preserved_user_skill_count: 0,
|
|
305
|
+
quarantined_sks_residue_count: 0,
|
|
305
306
|
remaining_count: 0,
|
|
306
307
|
preserved_clean_count: 0,
|
|
307
308
|
error_count: 0,
|
|
@@ -309,6 +310,7 @@ function emptySkillLegacySurface(fix) {
|
|
|
309
310
|
removed_other_harness_skills: [],
|
|
310
311
|
preserved_other_harness_skills: [],
|
|
311
312
|
preserved_user_skills: [],
|
|
313
|
+
quarantined_sks_residue: [],
|
|
312
314
|
remaining: [],
|
|
313
315
|
errors: [],
|
|
314
316
|
cleanup_prompt_command: 'sks conflicts cleanup --yes'
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import fsp from 'node:fs/promises';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { LEGACY_DOLLAR_SKILL_NAMES } from '../routes.js';
|
|
4
|
+
import { LEGACY_DOLLAR_SKILL_NAMES, routeByDollarCommand } from '../routes.js';
|
|
5
5
|
import { legacyCoreSkillNames } from '../codex-native/core-skill-manifest.js';
|
|
6
6
|
import { prefixKnownSksDollarReferences } from '../routes/dollar-prefix.js';
|
|
7
7
|
import { inspectConfinedPath } from '../managed-path-safety.js';
|
|
8
8
|
import { messageOf as errorMessage } from '../errors/message.js';
|
|
9
9
|
import { collectNestedProjectRoots } from './current-project-guidance-nested.js';
|
|
10
10
|
import { containsRetiredPublicSurface } from './current-project-guidance.js';
|
|
11
|
+
import { quarantineUserPath } from './retired-managed-residue-private.js';
|
|
11
12
|
export const SKILL_LEGACY_SURFACE_SCHEMA = 'sks.skill-legacy-surface.v1';
|
|
12
13
|
export const OTHER_HARNESS_SKILL_DIR_NAMES = ['omx', 'dcodex', 'omx-codex', 'dcodex-codex'];
|
|
13
14
|
const TOKEN = 'A-Za-z0-9_.\\-';
|
|
@@ -111,6 +112,32 @@ const PREFIX_LEGACY_NAMES = Array.from(new Set([
|
|
|
111
112
|
'prompt-pipeline',
|
|
112
113
|
'pipeline-runner'
|
|
113
114
|
]));
|
|
115
|
+
async function isSksRouteSkillResidue(dir, name, text) {
|
|
116
|
+
if (!routeByDollarCommand(name) && !PREFIX_LEGACY_NAMES.includes(name))
|
|
117
|
+
return false;
|
|
118
|
+
const frontmatterName = /^---\n[\s\S]*?^name:\s*(.+?)\s*$[\s\S]*?^---/m.exec(text)?.[1];
|
|
119
|
+
if (frontmatterName !== name)
|
|
120
|
+
return false;
|
|
121
|
+
const files = [];
|
|
122
|
+
const walk = async (current, relative) => {
|
|
123
|
+
for (const entry of await fsp.readdir(current, { withFileTypes: true })) {
|
|
124
|
+
const rel = relative ? `${relative}/${entry.name}` : entry.name;
|
|
125
|
+
if (entry.isSymbolicLink())
|
|
126
|
+
return false;
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
if (!await walk(path.join(current, entry.name), rel))
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
files.push(rel);
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
};
|
|
136
|
+
if (!await walk(dir, ''))
|
|
137
|
+
return false;
|
|
138
|
+
return files.every((file) => SKS_SKILL_LAYOUT_FILES.has(file));
|
|
139
|
+
}
|
|
140
|
+
const SKS_SKILL_LAYOUT_FILES = new Set(['SKILL.md', 'agents/openai.yaml']);
|
|
114
141
|
export function rewriteSkillLegacySurface(input) {
|
|
115
142
|
let text = String(input || '');
|
|
116
143
|
const hits = [];
|
|
@@ -173,6 +200,7 @@ export async function reconcileSkillLegacySurface(opts) {
|
|
|
173
200
|
const removedOtherHarness = [];
|
|
174
201
|
const preservedOtherHarness = [];
|
|
175
202
|
const preservedUserSkills = [];
|
|
203
|
+
const quarantinedResidue = [];
|
|
176
204
|
const remaining = [];
|
|
177
205
|
const errors = [];
|
|
178
206
|
let scanned = 0;
|
|
@@ -262,6 +290,21 @@ export async function reconcileSkillLegacySurface(opts) {
|
|
|
262
290
|
remaining.push(display);
|
|
263
291
|
continue;
|
|
264
292
|
}
|
|
293
|
+
if (await isSksRouteSkillResidue(dir, row.name, before).catch(() => false)) {
|
|
294
|
+
if (!fix) {
|
|
295
|
+
remaining.push(display);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
await quarantineUserPath(ownerRoot, dir, path.join(ownerRoot, '.sneakoscope', 'quarantine', 'skill-legacy-surface'));
|
|
300
|
+
quarantinedResidue.push(display);
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
errors.push(`${display}:${errorMessage(error)}`);
|
|
304
|
+
remaining.push(display);
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
265
308
|
preservedUserSkills.push(display);
|
|
266
309
|
remaining.push(display);
|
|
267
310
|
}
|
|
@@ -275,6 +318,7 @@ export async function reconcileSkillLegacySurface(opts) {
|
|
|
275
318
|
removed_other_harness_skill_count: removedOtherHarness.length,
|
|
276
319
|
preserved_other_harness_skill_count: preservedOtherHarness.length,
|
|
277
320
|
preserved_user_skill_count: preservedUserSkills.length,
|
|
321
|
+
quarantined_sks_residue_count: quarantinedResidue.length,
|
|
278
322
|
remaining_count: remaining.length,
|
|
279
323
|
preserved_clean_count: preservedClean,
|
|
280
324
|
error_count: errors.length,
|
|
@@ -282,6 +326,7 @@ export async function reconcileSkillLegacySurface(opts) {
|
|
|
282
326
|
removed_other_harness_skills: Array.from(new Set(removedOtherHarness)).sort(),
|
|
283
327
|
preserved_other_harness_skills: Array.from(new Set(preservedOtherHarness)).sort(),
|
|
284
328
|
preserved_user_skills: Array.from(new Set(preservedUserSkills)).sort(),
|
|
329
|
+
quarantined_sks_residue: Array.from(new Set(quarantinedResidue)).sort(),
|
|
285
330
|
remaining: Array.from(new Set(remaining)).sort(),
|
|
286
331
|
errors: Array.from(new Set(errors)).sort(),
|
|
287
332
|
cleanup_prompt_command: 'sks conflicts cleanup --yes'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { compareSemVer } from './semver.js';
|
|
2
|
+
export async function versionDownloadability(input) {
|
|
3
|
+
const env = input.env || process.env;
|
|
4
|
+
if (!probeEnabled(env))
|
|
5
|
+
return 'unknown';
|
|
6
|
+
const fetchImpl = input.fetchImpl || fetch;
|
|
7
|
+
const timeoutMs = input.timeoutMs ?? 4000;
|
|
8
|
+
const base = input.registry.replace(/\/+$/, '');
|
|
9
|
+
const name = input.packageName.replace('/', '%2F');
|
|
10
|
+
try {
|
|
11
|
+
const doc = await timed(fetchImpl, `${base}/${name}/${encodeURIComponent(input.version)}`, { headers: { accept: 'application/json' } }, timeoutMs);
|
|
12
|
+
if (doc.status === 404)
|
|
13
|
+
return 'not_yet_downloadable';
|
|
14
|
+
if (!doc.ok)
|
|
15
|
+
return 'unknown';
|
|
16
|
+
const tarball = (await doc.json().catch(() => null))?.dist?.tarball;
|
|
17
|
+
if (typeof tarball !== 'string' || !/^https?:\/\//.test(tarball))
|
|
18
|
+
return 'unknown';
|
|
19
|
+
const head = await timed(fetchImpl, tarball, { method: 'HEAD' }, timeoutMs);
|
|
20
|
+
if (head.ok)
|
|
21
|
+
return 'downloadable';
|
|
22
|
+
return head.status === 404 ? 'not_yet_downloadable' : 'unknown';
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return 'unknown';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function offeredUpdateVersion(input) {
|
|
29
|
+
const { listed, current } = input;
|
|
30
|
+
if (!listed || (compareSemVer(listed, current) ?? 0) <= 0)
|
|
31
|
+
return { latest: listed, pending: null };
|
|
32
|
+
const state = await versionDownloadability({
|
|
33
|
+
registry: input.registry,
|
|
34
|
+
packageName: input.packageName,
|
|
35
|
+
version: listed,
|
|
36
|
+
...(input.env ? { env: input.env } : {}),
|
|
37
|
+
...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {})
|
|
38
|
+
});
|
|
39
|
+
return state === 'not_yet_downloadable' ? { latest: current, pending: listed } : { latest: listed, pending: null };
|
|
40
|
+
}
|
|
41
|
+
function probeEnabled(env) {
|
|
42
|
+
const flag = env.SKS_UPDATE_TARBALL_PROBE;
|
|
43
|
+
if (flag === '0')
|
|
44
|
+
return false;
|
|
45
|
+
if (flag === '1')
|
|
46
|
+
return true;
|
|
47
|
+
return !(env.NODE_TEST_CONTEXT || env.SKS_TEST_ISOLATION === '1');
|
|
48
|
+
}
|
|
49
|
+
async function timed(fetchImpl, url, init, timeoutMs) {
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
52
|
+
try {
|
|
53
|
+
return await fetchImpl(url, { ...init, signal: controller.signal });
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -12,6 +12,7 @@ import { compareSemVer, extractSemVer, parseSemVer } from './update/semver.js';
|
|
|
12
12
|
import { countUpdates, emptyUpdateStatus, resolveSksUpdateStatus, UpdateStatusRefreshError } from './update/update-status.js';
|
|
13
13
|
import { acquireUpdateOperationLock, authorizeUpdateRollback, buildUpdateNowCommand, buildUpdateRollbackCommand, canonicalUpdateRegistry, UpdateOperationRecorder, updateOperationLastInstallPath, updateReceiptHasConfirmedGlobalInstall } from './update/update-operation.js';
|
|
14
14
|
import { runTemporaryInstallSmoke } from './update/temporary-install-smoke.js';
|
|
15
|
+
import { offeredUpdateVersion } from './update/registry-availability.js';
|
|
15
16
|
import { npmGlobalInstallTargets, repairManagedPermissions } from './update/managed-permission-repair.js';
|
|
16
17
|
import { updateStageFailureDiagnostics } from './update/update-stage-diagnostics.js';
|
|
17
18
|
import { executableOnInjectedPath, inspectInstalledCliResolution } from './update/installed-cli-resolution.js';
|
|
@@ -150,7 +151,7 @@ async function runSksUpdateCheckLive(options = {}) {
|
|
|
150
151
|
});
|
|
151
152
|
}
|
|
152
153
|
const result = await latestPromise;
|
|
153
|
-
if (!result) {
|
|
154
|
+
if (!result || result.code !== 0) {
|
|
154
155
|
return buildResult({
|
|
155
156
|
packageName,
|
|
156
157
|
current,
|
|
@@ -160,33 +161,14 @@ async function runSksUpdateCheckLive(options = {}) {
|
|
|
160
161
|
npmBin,
|
|
161
162
|
projectRoot: options.projectRoot,
|
|
162
163
|
commandRegistry: options.registry,
|
|
163
|
-
error: 'npm view failed'
|
|
164
|
+
error: result ? `${result.stderr || result.stdout || 'npm view failed'}`.trim() : 'npm view failed'
|
|
164
165
|
});
|
|
165
166
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
latest: null,
|
|
172
|
-
registry,
|
|
173
|
-
npmBin,
|
|
174
|
-
projectRoot: options.projectRoot,
|
|
175
|
-
commandRegistry: options.registry,
|
|
176
|
-
error: `${result.stderr || result.stdout || 'npm view failed'}`.trim()
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
const latest = extractSemVer(String(result.stdout || '').trim().split(/\s+/).pop() || '');
|
|
180
|
-
return buildResult({
|
|
181
|
-
packageName,
|
|
182
|
-
current,
|
|
183
|
-
effective,
|
|
184
|
-
latest,
|
|
185
|
-
registry,
|
|
186
|
-
npmBin,
|
|
187
|
-
projectRoot: options.projectRoot,
|
|
188
|
-
commandRegistry: options.registry
|
|
189
|
-
});
|
|
167
|
+
const offered = await offeredUpdateVersion({ listed: extractSemVer(String(result.stdout || '').trim().split(/\s+/).pop() || ''), current, registry, packageName, env });
|
|
168
|
+
return {
|
|
169
|
+
...buildResult({ packageName, current, effective, latest: offered.latest, registry, npmBin, projectRoot: options.projectRoot, commandRegistry: options.registry }),
|
|
170
|
+
pending_latest: offered.pending
|
|
171
|
+
};
|
|
190
172
|
}
|
|
191
173
|
function buildUpdateStatusSnapshot(input) {
|
|
192
174
|
const currentParsed = parseSemVer(input.check.current);
|
package/dist/core/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '10.3.
|
|
1
|
+
export const PACKAGE_VERSION = '10.3.7';
|
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.7",
|
|
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",
|