sneakoscope 1.0.9 → 1.10.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/README.md +12 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +3 -1
- package/dist/core/commands/basic-cli.js +4 -36
- package/dist/core/fsx.d.ts +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +3 -9
- package/dist/core/update-check.d.ts +29 -0
- package/dist/core/update-check.js +97 -0
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Fast legacy-free proof-first Codex trust layer with image-based Voxel TriWiki.
|
|
|
4
4
|
|
|
5
5
|
Sneakoscope Codex (`sks`) is a Codex CLI/App harness that makes repeatable Codex work auditable.
|
|
6
6
|
|
|
7
|
+
SKS **1.10.0** is the Function-Only Update Check release: `sks update-check` and the pre-work update gate now share a lightweight npm freshness function that reports `route_required: false` and `pipeline_required: false`, so checking for a newer SKS package never starts Team, setup, doctor, or any execution pipeline.
|
|
8
|
+
|
|
7
9
|
SKS **1.0.9** is the Official Docs Ultimate Kernel: Codex CLI `rust-v0.132.0` structured resume output is now an actual runner, `gpt-image-2` review generation uses Codex App `$imagegen` evidence or an optional OpenAI Images API fallback, Structured Outputs strict schemas are the extraction fallback, and `$UX-Review this screenshot with gpt-image-2 callouts, then fix the issues` blocks fake callouts until generated image pixels are schema-extracted, patched, recaptured, and re-reviewed.
|
|
8
10
|
|
|
9
11
|
SKS **1.0.8** is the Codex 0.132 UX-Review Seal: Codex CLI `rust-v0.132.0` compatibility is explicit, `codex exec resume --output-schema` is the preferred structured-output path, and `$UX-Review this screenshot with gpt-image-2 callouts, then fix the issues` is a real visual trust loop from source screenshot fidelity to generated callout ingestion, issue ledger extraction, bounded safe fixes, recapture/re-review, Image Voxel relations, Wrongness, Completion Proof, and Trust Report gates.
|
|
@@ -29,6 +31,16 @@ SKS does not try to clone every other harness. It focuses on one thing: making C
|
|
|
29
31
|

|
|
30
32
|
|
|
31
33
|
|
|
34
|
+
## 1.10.0 Function-Only Update Check
|
|
35
|
+
|
|
36
|
+
1.10.0 keeps the update freshness check out of the SKS mission pipeline. The shared `runSksUpdateCheck` function performs only an npm `view sneakoscope version` lookup, honors `SKS_NPM_VIEW_SNEAKOSCOPE_VERSION` for hermetic tests, and returns explicit `mode: "function"`, `route_required: false`, and `pipeline_required: false` evidence for CLI JSON output and hook-gate reuse.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
sks update-check --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Release checks now write `.sneakoscope/reports/official-docs-compat-1.10.0.json` plus `.sneakoscope/reports/release-readiness-1.10.0.json`.
|
|
43
|
+
|
|
32
44
|
## 1.0.9 Official Docs Ultimate Kernel
|
|
33
45
|
|
|
34
46
|
1.0.9 closes the remaining policy-vs-run-path gap. Attached generated images are recorded with `callout_extraction_status: pending` and empty callouts until `codex exec resume --output-schema` or the OpenAI Structured Outputs fallback returns a schema-valid issue ledger. Real `gpt-image-2` generation records request/response artifacts, source SHA-256, high-fidelity automatic input metadata, output hashes, local-only privacy, and blockers instead of substituting prose or generic callouts.
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 1.0
|
|
7
|
+
Some("--version") => println!("sks-rs 1.10.0"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
package/dist/bin/sks.js
CHANGED
package/dist/build-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"typescript": true,
|
|
5
5
|
"mjs_runtime_files": 0,
|
|
6
6
|
"files": [
|
|
@@ -617,6 +617,8 @@
|
|
|
617
617
|
"core/trust-kernel/trust-report.js",
|
|
618
618
|
"core/trust-kernel/trust-status.d.ts",
|
|
619
619
|
"core/trust-kernel/trust-status.js",
|
|
620
|
+
"core/update-check.d.ts",
|
|
621
|
+
"core/update-check.js",
|
|
620
622
|
"core/validators/completion-proof-validator.d.ts",
|
|
621
623
|
"core/validators/completion-proof-validator.js",
|
|
622
624
|
"core/validators/evidence-validator.d.ts",
|
|
@@ -3,13 +3,14 @@ import { spawnSync } from 'node:child_process';
|
|
|
3
3
|
import { COMMANDS } from '../../cli/command-registry.js';
|
|
4
4
|
import { flag } from '../../cli/args.js';
|
|
5
5
|
import { printJson, sksTextLogo } from '../../cli/output.js';
|
|
6
|
-
import { PACKAGE_VERSION, ensureDir, exists, nowIso, projectRoot, readJson,
|
|
6
|
+
import { PACKAGE_VERSION, ensureDir, exists, nowIso, projectRoot, readJson, sksRoot, tmpdir, writeJsonAtomic } from '../fsx.js';
|
|
7
7
|
import { COMMAND_CATALOG, DOLLAR_COMMAND_ALIASES, DOLLAR_COMMANDS, USAGE_TOPICS, routePrompt, routeReasoning, reasoningInstruction } from '../routes.js';
|
|
8
8
|
import { initProject, normalizeInstallScope, sksCommandPrefix } from '../init.js';
|
|
9
9
|
import { buildFeatureRegistry, validateFeatureRegistry } from '../feature-registry.js';
|
|
10
10
|
import { hooksExplainReport } from '../../cli/feature-commands.js';
|
|
11
11
|
import { writeSelftestRouteProof } from '../proof/selftest-proof-fixtures.js';
|
|
12
12
|
import { createMission } from '../mission.js';
|
|
13
|
+
import { formatSksUpdateCheckText, runSksUpdateCheck } from '../update-check.js';
|
|
13
14
|
export async function helpCommand(args = []) {
|
|
14
15
|
const topic = args[0];
|
|
15
16
|
if (topic)
|
|
@@ -103,25 +104,10 @@ export function quickstartCommand() {
|
|
|
103
104
|
For implementation work, use Codex App prompt routes such as $Team, $Goal, $QA-LOOP, $Image-UX-Review, and $Computer-Use.`);
|
|
104
105
|
}
|
|
105
106
|
export async function updateCheckCommand(args = []) {
|
|
106
|
-
const
|
|
107
|
-
const result = {
|
|
108
|
-
package: 'sneakoscope',
|
|
109
|
-
current: PACKAGE_VERSION,
|
|
110
|
-
runtime_current: PACKAGE_VERSION,
|
|
111
|
-
latest: latest.version,
|
|
112
|
-
update_available: latest.version ? compareVersions(latest.version, PACKAGE_VERSION) > 0 : false,
|
|
113
|
-
error: latest.error || null
|
|
114
|
-
};
|
|
107
|
+
const result = await runSksUpdateCheck();
|
|
115
108
|
if (flag(args, '--json'))
|
|
116
109
|
return printJson(result);
|
|
117
|
-
console.log(`${sksTextLogo()}\n\
|
|
118
|
-
console.log(`Current: ${result.current}`);
|
|
119
|
-
console.log(`Latest: ${result.latest || 'unknown'}`);
|
|
120
|
-
console.log(`Update: ${result.update_available ? 'available' : 'not needed'}`);
|
|
121
|
-
if (result.error)
|
|
122
|
-
console.log(`Error: ${result.error}`);
|
|
123
|
-
if (result.update_available)
|
|
124
|
-
console.log(`Run: npm i -g sneakoscope@${result.latest}`);
|
|
110
|
+
console.log(`${sksTextLogo()}\n\n${formatSksUpdateCheckText(result)}`);
|
|
125
111
|
}
|
|
126
112
|
export async function setupCommand(args = []) {
|
|
127
113
|
const root = await projectRoot();
|
|
@@ -292,24 +278,6 @@ function installScopeFromArgs(args = [], fallback = 'global') {
|
|
|
292
278
|
const index = args.indexOf('--install-scope');
|
|
293
279
|
return normalizeInstallScope(index >= 0 && args[index + 1] ? args[index + 1] : fallback);
|
|
294
280
|
}
|
|
295
|
-
async function npmViewVersion(name) {
|
|
296
|
-
const npm = whichSync('npm');
|
|
297
|
-
if (!npm)
|
|
298
|
-
return { version: null, error: 'npm not found on PATH' };
|
|
299
|
-
const result = await runProcess(npm, ['view', name, 'version', '--silent'], { timeoutMs: 15000, maxOutputBytes: 4096 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
|
|
300
|
-
if (result.code !== 0)
|
|
301
|
-
return { version: null, error: (result.stderr || result.stdout || 'npm view failed').trim() };
|
|
302
|
-
return { version: String(result.stdout || '').trim().split(/\s+/).pop() || null };
|
|
303
|
-
}
|
|
304
|
-
function compareVersions(a, b) {
|
|
305
|
-
const pa = String(a || '').split('.').map((x) => Number.parseInt(x, 10) || 0);
|
|
306
|
-
const pb = String(b || '').split('.').map((x) => Number.parseInt(x, 10) || 0);
|
|
307
|
-
for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
|
|
308
|
-
if ((pa[i] || 0) !== (pb[i] || 0))
|
|
309
|
-
return (pa[i] || 0) - (pb[i] || 0);
|
|
310
|
-
}
|
|
311
|
-
return 0;
|
|
312
|
-
}
|
|
313
281
|
function whichSync(command) {
|
|
314
282
|
const result = spawnSync(process.platform === 'win32' ? 'where' : 'command', process.platform === 'win32' ? [command] : ['-v', command], {
|
|
315
283
|
encoding: 'utf8',
|
package/dist/core/fsx.d.ts
CHANGED
package/dist/core/fsx.js
CHANGED
|
@@ -5,7 +5,7 @@ import os from 'node:os';
|
|
|
5
5
|
import crypto from 'node:crypto';
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
-
export const PACKAGE_VERSION = '1.0
|
|
8
|
+
export const PACKAGE_VERSION = '1.10.0';
|
|
9
9
|
export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
|
|
10
10
|
export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
|
|
11
11
|
export function nowIso() {
|
|
@@ -10,6 +10,7 @@ import { classifyToolError } from './evaluation.js';
|
|
|
10
10
|
import { REQUIRED_CODEX_MODEL, isForbiddenCodexModel } from './codex-model-guard.js';
|
|
11
11
|
import { dollarCommand, stripVisibleDecisionAnswerBlocks } from './routes.js';
|
|
12
12
|
import { appendMissionStatus } from './recallpulse.js';
|
|
13
|
+
import { runSksUpdateCheck } from './update-check.js';
|
|
13
14
|
import { buildPermissionRequestAllow, buildPermissionRequestDeny, buildPostToolUseBlock, buildPostToolUseContinue, buildPreToolUseContinue, buildPreToolUseDeny, buildStopBlock, buildStopContinue, buildUserPromptSubmitBlock, buildUserPromptSubmitContinue } from './codex-compat/codex-hook-output-builders.js';
|
|
14
15
|
const TEAM_DIGEST_MAX_EVENTS = 4;
|
|
15
16
|
const TEAM_DIGEST_MESSAGE_CHARS = 180;
|
|
@@ -876,15 +877,8 @@ function sksUpdateInstallCommand(version) {
|
|
|
876
877
|
return `npm i -g sneakoscope@${version} --registry https://registry.npmjs.org/`;
|
|
877
878
|
}
|
|
878
879
|
async function checkLatestVersion() {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
const npm = await which('npm').catch(() => null);
|
|
882
|
-
if (!npm)
|
|
883
|
-
return { error: 'npm not found' };
|
|
884
|
-
const result = await runProcess(npm, ['view', 'sneakoscope', 'version'], { timeoutMs: 3500, maxOutputBytes: 4096 });
|
|
885
|
-
if (result.code !== 0)
|
|
886
|
-
return { error: `${result.stderr || result.stdout || 'npm view failed'}`.trim() };
|
|
887
|
-
return { latest: result.stdout.trim().split(/\s+/).pop() };
|
|
880
|
+
const check = await runSksUpdateCheck({ timeoutMs: 3500 });
|
|
881
|
+
return { latest: check.latest, error: check.error || undefined };
|
|
888
882
|
}
|
|
889
883
|
async function detectInstalledSksVersion() {
|
|
890
884
|
const override = parseVersionText(process.env.SKS_INSTALLED_SKS_VERSION || '');
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface SksUpdateCheckOptions {
|
|
2
|
+
packageName?: string;
|
|
3
|
+
currentVersion?: string;
|
|
4
|
+
registry?: string;
|
|
5
|
+
npmBin?: string | null;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
maxOutputBytes?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SksUpdateCheckResult {
|
|
11
|
+
schema: 'sks.update-check.v2';
|
|
12
|
+
package: string;
|
|
13
|
+
current: string;
|
|
14
|
+
runtime_current: string;
|
|
15
|
+
latest: string | null;
|
|
16
|
+
update_available: boolean;
|
|
17
|
+
status: 'current' | 'available' | 'unavailable';
|
|
18
|
+
mode: 'function';
|
|
19
|
+
route_required: false;
|
|
20
|
+
pipeline_required: false;
|
|
21
|
+
command: string | null;
|
|
22
|
+
npm_bin: string | null;
|
|
23
|
+
registry: string;
|
|
24
|
+
error: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function runSksUpdateCheck(options?: SksUpdateCheckOptions): Promise<SksUpdateCheckResult>;
|
|
27
|
+
export declare function formatSksUpdateCheckText(result: SksUpdateCheckResult): string;
|
|
28
|
+
export declare function comparePackageVersions(a: string | null | undefined, b: string | null | undefined): number;
|
|
29
|
+
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { PACKAGE_VERSION, runProcess, which } from './fsx.js';
|
|
2
|
+
const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';
|
|
3
|
+
export async function runSksUpdateCheck(options = {}) {
|
|
4
|
+
const packageName = options.packageName || 'sneakoscope';
|
|
5
|
+
const current = options.currentVersion || PACKAGE_VERSION;
|
|
6
|
+
const registry = options.registry || DEFAULT_REGISTRY;
|
|
7
|
+
const env = options.env || process.env;
|
|
8
|
+
const override = env[versionOverrideEnvName(packageName)];
|
|
9
|
+
if (override)
|
|
10
|
+
return buildResult({ packageName, current, latest: override, registry, npmBin: null });
|
|
11
|
+
const npmBin = options.npmBin === undefined ? await which('npm') : options.npmBin;
|
|
12
|
+
if (!npmBin) {
|
|
13
|
+
return buildResult({
|
|
14
|
+
packageName,
|
|
15
|
+
current,
|
|
16
|
+
latest: null,
|
|
17
|
+
registry,
|
|
18
|
+
npmBin: null,
|
|
19
|
+
error: 'npm not found on PATH'
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const args = ['view', packageName, 'version', '--silent', '--registry', registry];
|
|
23
|
+
const result = await runProcess(npmBin, args, {
|
|
24
|
+
env,
|
|
25
|
+
timeoutMs: options.timeoutMs ?? 5000,
|
|
26
|
+
maxOutputBytes: options.maxOutputBytes ?? 4096
|
|
27
|
+
}).catch((err) => ({
|
|
28
|
+
code: 1,
|
|
29
|
+
stdout: '',
|
|
30
|
+
stderr: err instanceof Error ? err.message : String(err)
|
|
31
|
+
}));
|
|
32
|
+
if (result.code !== 0) {
|
|
33
|
+
return buildResult({
|
|
34
|
+
packageName,
|
|
35
|
+
current,
|
|
36
|
+
latest: null,
|
|
37
|
+
registry,
|
|
38
|
+
npmBin,
|
|
39
|
+
error: `${result.stderr || result.stdout || 'npm view failed'}`.trim()
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return buildResult({
|
|
43
|
+
packageName,
|
|
44
|
+
current,
|
|
45
|
+
latest: String(result.stdout || '').trim().split(/\s+/).pop() || null,
|
|
46
|
+
registry,
|
|
47
|
+
npmBin
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function formatSksUpdateCheckText(result) {
|
|
51
|
+
const lines = [
|
|
52
|
+
'Update Check',
|
|
53
|
+
`Current: ${result.current}`,
|
|
54
|
+
`Latest: ${result.latest || 'unknown'}`,
|
|
55
|
+
`Update: ${result.update_available ? 'available' : 'not needed'}`
|
|
56
|
+
];
|
|
57
|
+
if (result.error)
|
|
58
|
+
lines.push(`Error: ${result.error}`);
|
|
59
|
+
if (result.command)
|
|
60
|
+
lines.push(`Run: ${result.command}`);
|
|
61
|
+
lines.push('Mode: function-only');
|
|
62
|
+
return lines.join('\n');
|
|
63
|
+
}
|
|
64
|
+
export function comparePackageVersions(a, b) {
|
|
65
|
+
const pa = String(a || '').split(/[.-]/).map((x) => Number.parseInt(x, 10) || 0);
|
|
66
|
+
const pb = String(b || '').split(/[.-]/).map((x) => Number.parseInt(x, 10) || 0);
|
|
67
|
+
for (let i = 0; i < Math.max(pa.length, pb.length, 3); i += 1) {
|
|
68
|
+
if ((pa[i] || 0) > (pb[i] || 0))
|
|
69
|
+
return 1;
|
|
70
|
+
if ((pa[i] || 0) < (pb[i] || 0))
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
function buildResult(input) {
|
|
76
|
+
const updateAvailable = Boolean(input.latest && comparePackageVersions(input.latest, input.current) > 0);
|
|
77
|
+
return {
|
|
78
|
+
schema: 'sks.update-check.v2',
|
|
79
|
+
package: input.packageName,
|
|
80
|
+
current: input.current,
|
|
81
|
+
runtime_current: PACKAGE_VERSION,
|
|
82
|
+
latest: input.latest,
|
|
83
|
+
update_available: updateAvailable,
|
|
84
|
+
status: input.error ? 'unavailable' : updateAvailable ? 'available' : 'current',
|
|
85
|
+
mode: 'function',
|
|
86
|
+
route_required: false,
|
|
87
|
+
pipeline_required: false,
|
|
88
|
+
command: updateAvailable ? `npm i -g ${input.packageName}@${input.latest} --registry ${input.registry}` : null,
|
|
89
|
+
npm_bin: input.npmBin,
|
|
90
|
+
registry: input.registry,
|
|
91
|
+
error: input.error || null
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function versionOverrideEnvName(packageName) {
|
|
95
|
+
return `SKS_NPM_VIEW_${packageName.replace(/[^A-Za-z0-9]+/g, '_').toUpperCase()}_VERSION`;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=update-check.js.map
|
package/dist/core/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "1.0
|
|
1
|
+
export declare const PACKAGE_VERSION = "1.10.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '1.0
|
|
1
|
+
export const PACKAGE_VERSION = '1.10.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.10.0",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|