sneakoscope 3.1.7 → 3.1.9
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 +9 -2
- 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/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/cli/args.js +17 -0
- package/dist/cli/command-registry.js +16 -13
- package/dist/cli/router.js +8 -5
- package/dist/commands/doctor.js +97 -2
- package/dist/core/codex-app/codex-skill-sync.js +80 -154
- package/dist/core/codex-native/core-skill-integrity.js +89 -0
- package/dist/core/codex-native/core-skill-manifest.js +156 -0
- package/dist/core/codex-native/native-capability-postcheck.js +35 -0
- package/dist/core/codex-native/native-capability-repair-matrix.js +210 -0
- package/dist/core/codex-native/native-capability-repair.js +47 -0
- package/dist/core/codex-native/native-media-computer-repair.js +5 -0
- package/dist/core/codex-native/project-skill-dedupe.js +109 -0
- package/dist/core/codex-native/skill-name-canonicalizer.js +21 -0
- package/dist/core/codex-native/skill-registry-ledger.js +85 -0
- package/dist/core/commands/basic-cli.js +19 -10
- package/dist/core/commands/mad-sks-command.js +36 -13
- package/dist/core/commands/naruto-command.js +4 -1
- package/dist/core/commands/pipeline-command.js +3 -4
- package/dist/core/commands/qa-loop-command.js +36 -1
- package/dist/core/commands/research-command.js +61 -1
- package/dist/core/commands/team-command.js +63 -3
- package/dist/core/config/config-migration-journal.js +27 -0
- package/dist/core/config/managed-config-merge.js +105 -0
- package/dist/core/config/secret-preservation.js +169 -0
- package/dist/core/config/supabase-secret-preservation.js +29 -0
- package/dist/core/decision-contract.js +28 -4
- package/dist/core/doctor/command-alias-cleanup.js +64 -0
- package/dist/core/doctor/doctor-native-capability-repair.js +48 -0
- package/dist/core/feature-fixtures.js +2 -0
- package/dist/core/feature-registry.js +2 -2
- package/dist/core/fsx.js +1 -1
- package/dist/core/init.js +5 -1
- package/dist/core/naruto/naruto-work-graph.js +4 -1
- package/dist/core/pipeline-internals/runtime-core.js +50 -4
- package/dist/core/pipeline-internals/runtime-gates.js +10 -1
- package/dist/core/proof/route-proof-gate.js +1 -1
- package/dist/core/qa-loop.js +227 -11
- package/dist/core/questions.js +239 -2
- package/dist/core/routes.js +3 -4
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-native-release-gate.js +13 -4
- package/dist/scripts/sizecheck.js +8 -2
- package/dist/scripts/sks-3-1-8-check-lib.js +30 -0
- package/package.json +27 -1
package/dist/core/questions.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { writeJsonAtomic, writeTextAtomic } from './fsx.js';
|
|
2
|
+
import { nowIso, sha256, writeJsonAtomic, writeTextAtomic } from './fsx.js';
|
|
3
3
|
import { buildQaLoopQuestionSchema } from './qa-loop.js';
|
|
4
4
|
import { CODEX_COMPUTER_USE_ONLY_POLICY, CODEX_WEB_VERIFICATION_POLICY, FROM_CHAT_IMG_CHECKLIST_ARTIFACT, FROM_CHAT_IMG_COVERAGE_ARTIFACT, FROM_CHAT_IMG_QA_LOOP_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT, hasFromChatImgSignal } from './routes.js';
|
|
5
|
+
export const REQUEST_INTAKE_ARTIFACT = 'request-intake.json';
|
|
5
6
|
export function buildQuestionSchemaForRoute(route, prompt) {
|
|
6
7
|
if (String(route?.id || '') === 'QALoop')
|
|
7
8
|
return buildQaLoopQuestionSchema(prompt);
|
|
@@ -222,6 +223,8 @@ export function inferAnswersForPrompt(prompt, explicitAnswers = {}) {
|
|
|
222
223
|
const versionWork = /버전|version|bump|release|publish:dry|npm\s+pack/.test(lower);
|
|
223
224
|
const installWork = /bootstrap|postinstall|doctor|deps|tmux|homebrew|first install|최초\s*설치|설치\s*ux|셋업|setup/.test(lower);
|
|
224
225
|
const questionGateWork = /모호|ambiguity|clarification|질문|triwiki|추론|infer|predict|예측|answers?\.json|decision-contract/.test(lower);
|
|
226
|
+
const requestIntakeWork = /(모호|ambiguity|ambiguous|vague|rough|의도|intent|요청사항|requirements?|프롬프트|prompt|triwiki|위키|wiki)/.test(lower)
|
|
227
|
+
&& /(파이프라인|pipeline|변환|transform|rewrite|compile|리스트|list|누락|missing|의도|intent|request[- ]?intake|intake)/.test(lower);
|
|
225
228
|
const uiuxWork = /\b(ui|modal|screen|button|visual|design|layout|component|prototype|frontend)\b|화면|버튼|모달|디자인|레이아웃|컴포넌트|프론트|시각|발표자료|디자인\s*시스템/.test(lower);
|
|
226
229
|
const presentationWork = looksLikePresentationArtifactPrompt(lower);
|
|
227
230
|
const dbWork = new RegExp(["\\bdb\\b", "database", "schema", "migration", "tab" + "le", "col" + "umn", "rls", "supabase", "postgres", "sql", "테이블", "마이그레이션", "스키마", "컬럼", "열", "행", "데이터베이스"].join("|")).test(lower);
|
|
@@ -247,12 +250,13 @@ export function inferAnswersForPrompt(prompt, explicitAnswers = {}) {
|
|
|
247
250
|
&& !versionWork
|
|
248
251
|
&& !presentationWork
|
|
249
252
|
&& !chatCaptureWork;
|
|
250
|
-
const kind = versionWork ? 'version' : chatCaptureWork ? 'chat_capture' : triwikiAuditWork ? 'triwiki_audit' : effectivePrioritySignalWork ? 'priority' : questionGateWork ? 'questions' : installWork ? 'install' : null;
|
|
253
|
+
const kind = versionWork ? 'version' : chatCaptureWork ? 'chat_capture' : triwikiAuditWork ? 'triwiki_audit' : effectivePrioritySignalWork ? 'priority' : requestIntakeWork ? 'request_intake' : questionGateWork ? 'questions' : installWork ? 'install' : null;
|
|
251
254
|
const goals = {
|
|
252
255
|
version: version ? `sneakoscope 버전을 ${version}로 올린다` : 'sneakoscope 버전을 다음 patch 버전으로 올린다',
|
|
253
256
|
chat_capture: 'From-Chat-IMG로 채팅 요구사항과 첨부 원본 이미지를 매칭해 고객사 작업 지시서를 만들고 반영한다',
|
|
254
257
|
triwiki_audit: 'TriWiki가 반복 실수를 막는지 검수하고, 실패 경로를 코드와 검증으로 개선한다',
|
|
255
258
|
priority: '강한 불만과 반복 요청을 TriWiki 우선순위 신호로 기록한다',
|
|
259
|
+
request_intake: '모호한 사용자 요청을 TriWiki 기반 request-intake로 해석하고, 누락 없는 요구사항 목록과 실행용 변환 프롬프트를 pipeline에 전달한다',
|
|
256
260
|
questions: '예측 가능한 답은 추론하고 실제 모호한 항목만 질문한다',
|
|
257
261
|
presentation: '청중과 STP 전략에 맞는 HTML 기반 발표자료/PDF 산출물을 만든다',
|
|
258
262
|
install: 'SKS 최초 설치와 bootstrap을 한 번에 준비 상태까지 연결한다'
|
|
@@ -262,6 +266,7 @@ export function inferAnswersForPrompt(prompt, explicitAnswers = {}) {
|
|
|
262
266
|
chat_capture: ['From-Chat-IMG activates chat-image intake only here', 'all visible chat requirements are listed before implementation', `${FROM_CHAT_IMG_COVERAGE_ARTIFACT} maps every customer request, screenshot region, and attachment to work-order item(s)`, `${FROM_CHAT_IMG_CHECKLIST_ARTIFACT} is updated as each request, image match, work item, scoped QA-LOOP, and verification step is completed`, `${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT} records temporary TriWiki-backed session context with retention metadata`, `${FROM_CHAT_IMG_QA_LOOP_ARTIFACT} proves QA-LOOP ran over the exact customer-request work-order range after implementation`, 'unresolved_items is empty before Team completion', 'scoped_qa_loop_completed is true with zero unresolved QA findings', 'Web/browser visual inspection uses Codex Chrome Extension readiness first; native Mac/non-web visual inspection uses Codex Computer Use when available', CODEX_WEB_VERIFICATION_POLICY, CODEX_COMPUTER_USE_ONLY_POLICY, 'client requests follow normal SKS gates and verification'],
|
|
263
267
|
triwiki_audit: ['TriWiki ingestion, voxel attention, and contract consumption paths are inspected against current code', 'repeat-mistake prevention gaps are fixed in the relevant code path or blocked with evidence', 'regression coverage proves fresh/high-weight mistake memory can influence future missions', 'final status separates supported behavior from anything still unverified'],
|
|
264
268
|
priority: ['strong feedback raises required_weight', 'request topics are counted in wiki packs', 'future inference uses priority signals'],
|
|
269
|
+
request_intake: ['request-intake.json records original prompt, interpreted intent, source-order requirements, wiki context used, and transformed prompt', 'pipeline-plan.json attaches request_intake metadata and execution_prompt from request-intake.transformed_prompt', 'decision-contract.json preserves the same request-intake artifact when a contract is sealed'],
|
|
265
270
|
questions: ['predictable answers are inferred', 'partial answers can seal contracts', 'only unresolved changing slots remain visible'],
|
|
266
271
|
presentation: ['audience profile and STP strategy are explicit before artifact creation', 'target pain points map to proposed solution moments', 'decision context and likely objections are sealed before storyboarding', 'presentation format, device, and delivery context are fixed before design work'],
|
|
267
272
|
install: ['bootstrap/deps initialize readiness', 'missing runtime deps show repair actions', 'readiness output is concrete']
|
|
@@ -381,6 +386,222 @@ export function inferAnswersForPrompt(prompt, explicitAnswers = {}) {
|
|
|
381
386
|
}
|
|
382
387
|
return { answers: inferred, notes };
|
|
383
388
|
}
|
|
389
|
+
export function buildRequestIntake(prompt, explicitAnswers = {}, opts = {}) {
|
|
390
|
+
const originalPrompt = String(prompt || '').trim();
|
|
391
|
+
const inferred = inferAnswersForPrompt(originalPrompt, explicitAnswers);
|
|
392
|
+
const answers = { ...(inferred.answers || {}), ...(explicitAnswers || {}) };
|
|
393
|
+
const ambiguity = buildAmbiguityAssessment(originalPrompt, explicitAnswers);
|
|
394
|
+
const wikiContext = summarizeWikiContext(opts.wikiContext);
|
|
395
|
+
const promptRequirements = promptRequirementItems(originalPrompt);
|
|
396
|
+
const semanticRequirements = semanticRequirementItems(originalPrompt);
|
|
397
|
+
const acceptance = toStringList(answers.ACCEPTANCE_CRITERIA);
|
|
398
|
+
const constraints = toStringList(answers.RISK_BOUNDARY);
|
|
399
|
+
const nonGoals = toStringList(answers.NON_GOALS);
|
|
400
|
+
const requirements = dedupeRequirementItems([
|
|
401
|
+
...promptRequirements,
|
|
402
|
+
...semanticRequirements,
|
|
403
|
+
...acceptance.map((text, index) => requirementItem('acceptance', index + 1, text, 'inferred_acceptance_criteria')),
|
|
404
|
+
...constraints.map((text, index) => requirementItem('constraint', index + 1, text, 'inferred_safety_constraint'))
|
|
405
|
+
]);
|
|
406
|
+
const goal = String(answers.GOAL_PRECISE || originalPrompt || '사용자 요청을 현재 코드 기준으로 구현한다').trim();
|
|
407
|
+
const targetSignals = extractTargetSignals(originalPrompt);
|
|
408
|
+
const riskSignals = extractRiskSignals(originalPrompt, constraints);
|
|
409
|
+
const transformedPrompt = buildTransformedPrompt({
|
|
410
|
+
originalPrompt,
|
|
411
|
+
goal,
|
|
412
|
+
wikiContext,
|
|
413
|
+
requirements,
|
|
414
|
+
constraints,
|
|
415
|
+
acceptance,
|
|
416
|
+
nonGoals,
|
|
417
|
+
targetSignals,
|
|
418
|
+
riskSignals,
|
|
419
|
+
ambiguity
|
|
420
|
+
});
|
|
421
|
+
return {
|
|
422
|
+
schema: 'sks.request-intake.v1',
|
|
423
|
+
generated_at: nowIso(),
|
|
424
|
+
prompt_hash: sha256(originalPrompt).slice(0, 16),
|
|
425
|
+
original_prompt: originalPrompt,
|
|
426
|
+
interpreted_intent: {
|
|
427
|
+
goal,
|
|
428
|
+
source: 'prompt_plus_triwiki_current_code_defaults',
|
|
429
|
+
confidence: ambiguity.ready_for_contract ? 'high' : ambiguity.overall_score <= 0.35 ? 'medium' : 'needs_human_only_if_scope_changes'
|
|
430
|
+
},
|
|
431
|
+
ambiguity_assessment: ambiguity,
|
|
432
|
+
wiki_context_used: wikiContext,
|
|
433
|
+
request_items: requirements,
|
|
434
|
+
requirements,
|
|
435
|
+
constraints,
|
|
436
|
+
acceptance_criteria: acceptance,
|
|
437
|
+
non_goals: nonGoals,
|
|
438
|
+
target_signals: targetSignals,
|
|
439
|
+
risk_signals: riskSignals,
|
|
440
|
+
transformed_prompt: transformedPrompt,
|
|
441
|
+
pipeline_usage: {
|
|
442
|
+
artifact: REQUEST_INTAKE_ARTIFACT,
|
|
443
|
+
read_before_pipeline_stage: true,
|
|
444
|
+
use_transformed_prompt_for_execution: true,
|
|
445
|
+
preserve_original_prompt: true,
|
|
446
|
+
ask_user_only_for_scope_safety_behavior_or_acceptance_changes: true
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function summarizeWikiContext(wikiContext = null) {
|
|
451
|
+
const claims = Array.isArray(wikiContext?.claims) ? wikiContext.claims : [];
|
|
452
|
+
const useFirstIds = new Set((wikiContext?.attention?.use_first || []).map((row) => Array.isArray(row) ? row[0] : row?.id).filter(Boolean));
|
|
453
|
+
const hydrateFirstIds = new Set((wikiContext?.attention?.hydrate_first || []).map((row) => Array.isArray(row) ? row[0] : row?.id).filter(Boolean));
|
|
454
|
+
return {
|
|
455
|
+
source: wikiContext ? '.sneakoscope/wiki/context-pack.json' : 'unavailable',
|
|
456
|
+
attention_mode: wikiContext?.attention?.mode || null,
|
|
457
|
+
use_first_ids: [...useFirstIds].slice(0, 8),
|
|
458
|
+
hydrate_first_ids: [...hydrateFirstIds].slice(0, 8),
|
|
459
|
+
claims: claims.slice(0, 8).map((claim) => ({
|
|
460
|
+
id: claim.id || claim.claim_id || null,
|
|
461
|
+
trust: claim.trust_score || claim.trust || null,
|
|
462
|
+
source: claim.source || claim.source_path || null,
|
|
463
|
+
summary: String(claim.claim || claim.summary || claim.text || '').slice(0, 320)
|
|
464
|
+
}))
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function promptRequirementItems(prompt) {
|
|
468
|
+
const cleaned = prompt
|
|
469
|
+
.replace(/(?:^|\s)\$[A-Za-z0-9_-]+(?:\s|$)/g, ' ')
|
|
470
|
+
.replace(/\s+/g, ' ')
|
|
471
|
+
.trim();
|
|
472
|
+
if (!cleaned)
|
|
473
|
+
return [];
|
|
474
|
+
const sourceChunks = cleaned
|
|
475
|
+
.split(/\n+|(?:^|\s)[-*]\s+/)
|
|
476
|
+
.flatMap((chunk) => splitLooseClauses(chunk))
|
|
477
|
+
.map((chunk) => chunk.trim())
|
|
478
|
+
.filter(Boolean);
|
|
479
|
+
const chunks = sourceChunks.length ? sourceChunks : [cleaned];
|
|
480
|
+
return chunks.slice(0, 12).map((text, index) => requirementItem('prompt', index + 1, text, 'source_prompt_order'));
|
|
481
|
+
}
|
|
482
|
+
function splitLooseClauses(text) {
|
|
483
|
+
const compact = String(text || '').trim();
|
|
484
|
+
if (compact.length < 80)
|
|
485
|
+
return [compact].filter(Boolean);
|
|
486
|
+
const pieces = compact.split(/\s+(?=(?:그리고|또|또한|그걸로|해당|이거는|이건|너가|우리|다음|then|and)\b)/i);
|
|
487
|
+
return pieces.length > 1 ? pieces : [compact];
|
|
488
|
+
}
|
|
489
|
+
function semanticRequirementItems(prompt) {
|
|
490
|
+
const text = String(prompt || '');
|
|
491
|
+
const lower = text.toLowerCase();
|
|
492
|
+
const items = [];
|
|
493
|
+
const add = (text, confidence = 0.88) => items.push({
|
|
494
|
+
id: `REQ-S${String(items.length + 1).padStart(2, '0')}`,
|
|
495
|
+
kind: 'semantic_requirement',
|
|
496
|
+
source: 'semantic_prompt_signal',
|
|
497
|
+
text,
|
|
498
|
+
required: true,
|
|
499
|
+
confidence
|
|
500
|
+
});
|
|
501
|
+
if (/모호|ambiguous|rough|대충|애매/.test(lower))
|
|
502
|
+
add('모호한 사용자 입력을 그대로 실행하지 말고 intent intake 단계에서 명확한 실행 요청으로 해석한다.');
|
|
503
|
+
if (/위키|triwiki|wiki|memory|기억/.test(lower))
|
|
504
|
+
add('TriWiki/context-pack과 현재 코드 기본값을 참고해 사용자 의도와 반복 선호를 보강한다.');
|
|
505
|
+
if (/의도|intent|목적/.test(lower) && /명확|파악|extract|understand/.test(lower))
|
|
506
|
+
add('사용자 의도를 Goal, Context, Constraints, Done-when 형태로 명확히 정리한다.');
|
|
507
|
+
if (/리스트|list|누락|빠짐|requirements?|요청사항/.test(lower))
|
|
508
|
+
add('요청사항을 source order 기준으로 누락 없이 리스트업하고 각 항목을 실행 작업으로 매핑한다.');
|
|
509
|
+
if (/프롬프트|prompt/.test(lower) && /변환|바꿔|rewrite|transform|compile|최적/.test(lower))
|
|
510
|
+
add('원문 요청을 파이프라인 실행에 적합한 transformed prompt로 변환한다.');
|
|
511
|
+
if (/파이프라인|pipeline/.test(lower) && /(태워|전달|route|run|execute|투입)/.test(lower))
|
|
512
|
+
add('변환된 prompt와 request-intake artifact를 실제 route pipeline에 전달한다.');
|
|
513
|
+
return items;
|
|
514
|
+
}
|
|
515
|
+
function requirementItem(kind, index, text, source) {
|
|
516
|
+
return {
|
|
517
|
+
id: `REQ-${String(index).padStart(3, '0')}`,
|
|
518
|
+
kind,
|
|
519
|
+
source,
|
|
520
|
+
text: String(text || '').trim(),
|
|
521
|
+
required: true,
|
|
522
|
+
confidence: source === 'source_prompt_order' ? 1 : 0.86
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
function dedupeRequirementItems(items = []) {
|
|
526
|
+
const seen = new Set();
|
|
527
|
+
const out = [];
|
|
528
|
+
for (const item of items) {
|
|
529
|
+
const text = String(item.text || '').replace(/\s+/g, ' ').trim();
|
|
530
|
+
if (!text)
|
|
531
|
+
continue;
|
|
532
|
+
const key = text.toLowerCase();
|
|
533
|
+
if (seen.has(key))
|
|
534
|
+
continue;
|
|
535
|
+
seen.add(key);
|
|
536
|
+
out.push({ ...item, id: `REQ-${String(out.length + 1).padStart(3, '0')}`, text });
|
|
537
|
+
}
|
|
538
|
+
return out;
|
|
539
|
+
}
|
|
540
|
+
function toStringList(value) {
|
|
541
|
+
if (Array.isArray(value))
|
|
542
|
+
return value.map((item) => String(item || '').trim()).filter(Boolean);
|
|
543
|
+
const text = String(value || '').trim();
|
|
544
|
+
if (!text)
|
|
545
|
+
return [];
|
|
546
|
+
return text.split(/\n+/).map((item) => item.trim()).filter(Boolean);
|
|
547
|
+
}
|
|
548
|
+
function extractTargetSignals(prompt) {
|
|
549
|
+
const text = String(prompt || '');
|
|
550
|
+
const paths = [...text.matchAll(/(?:src|test|tests|scripts|docs|README|CHANGELOG|package\.json|\.sneakoscope|\.agents|\.codex)\/?[A-Za-z0-9._/\-]*/g)].map((m) => m[0]);
|
|
551
|
+
const commands = [...text.matchAll(/\$[A-Za-z0-9_-]+/g)].map((m) => m[0]);
|
|
552
|
+
const urls = [...text.matchAll(/https?:\/\/[^\s)\]}>,]+/g)].map((m) => m[0]);
|
|
553
|
+
return {
|
|
554
|
+
paths: [...new Set(paths)].slice(0, 12),
|
|
555
|
+
dollar_commands: [...new Set(commands)].slice(0, 12),
|
|
556
|
+
urls: [...new Set(urls)].slice(0, 8)
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
function extractRiskSignals(prompt, constraints = []) {
|
|
560
|
+
const lower = String(prompt || '').toLowerCase();
|
|
561
|
+
const risks = [];
|
|
562
|
+
if (promptHasRisk(lower))
|
|
563
|
+
risks.push('high_risk_surface_detected');
|
|
564
|
+
if (promptNeedsExplicitRiskBoundary(lower))
|
|
565
|
+
risks.push('explicit_risk_boundary_required');
|
|
566
|
+
if (/db|database|supabase|postgres|sql|schema|migration|데이터베이스|스키마|마이그레이션/.test(lower))
|
|
567
|
+
risks.push('database_safety');
|
|
568
|
+
if (/browser|webapp|localhost|chrome|스크린샷|화면|ui|ux|visual|웹/.test(lower))
|
|
569
|
+
risks.push('visual_or_browser_evidence');
|
|
570
|
+
if (/publish|release|version|배포|릴리즈|버전/.test(lower))
|
|
571
|
+
risks.push('release_surface');
|
|
572
|
+
return {
|
|
573
|
+
risks: [...new Set(risks)],
|
|
574
|
+
constraints
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function buildTransformedPrompt(input) {
|
|
578
|
+
const requirementLines = (input.requirements || []).map((item, index) => `${index + 1}. ${item.text}`);
|
|
579
|
+
const wikiLines = (input.wikiContext?.claims || []).slice(0, 5).map((claim) => `- ${claim.id || 'wiki-claim'}: ${claim.summary}`);
|
|
580
|
+
return [
|
|
581
|
+
'# SKS Wiki-Informed Execution Prompt',
|
|
582
|
+
'',
|
|
583
|
+
'## Goal',
|
|
584
|
+
input.goal,
|
|
585
|
+
'',
|
|
586
|
+
'## Original Prompt',
|
|
587
|
+
input.originalPrompt || '(empty)',
|
|
588
|
+
'',
|
|
589
|
+
'## Wiki Context To Use First',
|
|
590
|
+
...(wikiLines.length ? wikiLines : ['- No current TriWiki claims were available; rely on current code and conservative SKS defaults.']),
|
|
591
|
+
'',
|
|
592
|
+
'## Requirements',
|
|
593
|
+
...(requirementLines.length ? requirementLines : ['1. Implement the user request using current code context.']),
|
|
594
|
+
'',
|
|
595
|
+
'## Constraints',
|
|
596
|
+
...((input.constraints || []).length ? input.constraints.map((row) => `- ${row}`) : ['- Preserve existing behavior unless the request explicitly changes it.', '- Do not create unrequested fallback implementation code.', '- Do not run destructive or live-data mutation commands.']),
|
|
597
|
+
'',
|
|
598
|
+
'## Done When',
|
|
599
|
+
...((input.acceptance || []).length ? input.acceptance.map((row) => `- ${row}`) : ['- Relevant implementation is complete.', '- Focused verification passes or unavailable checks are explicitly justified.', '- Final response states changed, verified, and unverified items.']),
|
|
600
|
+
'',
|
|
601
|
+
'## Pipeline Instruction',
|
|
602
|
+
'Read request-intake.json first, execute this transformed prompt through the selected SKS route, refresh/validate TriWiki after findings or artifact changes, and finish with SKS Honest Mode.'
|
|
603
|
+
].join('\n');
|
|
604
|
+
}
|
|
384
605
|
export function buildQuestionSchema(prompt) {
|
|
385
606
|
const lower = String(prompt || '').toLowerCase();
|
|
386
607
|
const domainHints = [];
|
|
@@ -438,6 +659,7 @@ export function buildQuestionSchema(prompt) {
|
|
|
438
659
|
slots.push({ id: 'DB_MIGRATION_APPLY_ALLOWED', question: 'migration 적용이 필요할 경우 어디까지 허용하나요?', required: true, type: 'enum', options: ['no', 'local_only', 'preview_branch_only'] }, { id: 'DB_READ_ONLY_QUERY_LIMIT', question: 'MCP/SQL read-only 조회 시 기본 LIMIT를 몇으로 둘까요?', required: true, type: 'string' });
|
|
439
660
|
}
|
|
440
661
|
const inferred = inferAnswersForPrompt(prompt);
|
|
662
|
+
const requestIntake = buildRequestIntake(prompt, inferred.answers);
|
|
441
663
|
const inferredSlots = new Set(Object.keys(inferred.answers));
|
|
442
664
|
const askedSlots = [];
|
|
443
665
|
return {
|
|
@@ -446,6 +668,7 @@ export function buildQuestionSchema(prompt) {
|
|
|
446
668
|
prompt,
|
|
447
669
|
domain_hints: domainHints,
|
|
448
670
|
ambiguity_assessment: ambiguity,
|
|
671
|
+
request_intake: requestIntake,
|
|
449
672
|
inferred_answers: inferred.answers,
|
|
450
673
|
inference_notes: inferred.notes,
|
|
451
674
|
slots: askedSlots
|
|
@@ -478,6 +701,20 @@ export function questionsMarkdown(schema) {
|
|
|
478
701
|
lines.push(`- unresolved dimensions: ${(schema.ambiguity_assessment.unresolved_dimensions || []).join(', ') || 'none'}`);
|
|
479
702
|
lines.push(`- legacy question budget ignored: ${schema.ambiguity_assessment.question_budget}`);
|
|
480
703
|
}
|
|
704
|
+
if (schema.request_intake) {
|
|
705
|
+
const intake = schema.request_intake;
|
|
706
|
+
lines.push('');
|
|
707
|
+
lines.push('## Request Intake');
|
|
708
|
+
lines.push('');
|
|
709
|
+
lines.push(`- artifact: ${REQUEST_INTAKE_ARTIFACT}`);
|
|
710
|
+
lines.push(`- interpreted goal: ${intake.interpreted_intent?.goal || '(none)'}`);
|
|
711
|
+
lines.push(`- requirement count: ${(intake.requirements || []).length}`);
|
|
712
|
+
lines.push(`- wiki context: ${intake.wiki_context_used?.source || 'unavailable'}`);
|
|
713
|
+
lines.push('');
|
|
714
|
+
lines.push('```markdown');
|
|
715
|
+
lines.push(intake.transformed_prompt || '');
|
|
716
|
+
lines.push('```');
|
|
717
|
+
}
|
|
481
718
|
if (schema.inferred_answers && Object.keys(schema.inferred_answers).length) {
|
|
482
719
|
lines.push('');
|
|
483
720
|
lines.push('## Inferred Answers');
|
package/dist/core/routes.js
CHANGED
|
@@ -30,7 +30,7 @@ export const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = 'from-chat-img-checklist.md';
|
|
|
30
30
|
export const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = 'from-chat-img-temp-triwiki.json';
|
|
31
31
|
export const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = 'from-chat-img-qa-loop.json';
|
|
32
32
|
export const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
|
|
33
|
-
export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|goal|fast-mode|research|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
|
|
33
|
+
export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|computer-use|goal|fast-mode|research|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
|
|
34
34
|
export const CODEX_COMPUTER_USE_EVIDENCE_SOURCE = 'codex_computer_use';
|
|
35
35
|
export const CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE = 'codex_chrome_extension';
|
|
36
36
|
export const CODEX_IMAGEGEN_EVIDENCE_SOURCE = 'codex_app_imagegen_gpt_image_2';
|
|
@@ -636,10 +636,9 @@ export const COMMAND_CATALOG = [
|
|
|
636
636
|
{ name: 'codex-native', usage: 'sks codex-native status|feature-broker|invocation-plan|init-deep [--json]', description: 'Inspect Codex Native feature broker readiness, invocation routing, pattern evidence, and managed memory setup.' },
|
|
637
637
|
{ name: 'hooks', usage: 'sks hooks explain|status|trust-report|replay|codex-validate|warning-check ... [--json]', description: 'Explain Codex hook events, validate vendored latest 10-event output schemas, replay fixtures, and enforce warning-zero SKS hook policies under the 0.134 compatibility matrix.' },
|
|
638
638
|
{ name: 'codex-lb', usage: 'sks codex-lb status|health|metrics|doctor|circuit|repair|setup ...', description: 'Configure, health-check, repair, and record circuit evidence for codex-lb provider auth without confusing ChatGPT OAuth and proxy keys.' },
|
|
639
|
-
{ name: 'auth', usage: 'sks auth status|health|repair|setup --host <domain> --api-key <key>', description: 'Shortcut for codex-lb provider auth status, health, repair, and setup commands.' },
|
|
640
639
|
{ name: 'zellij', usage: 'sks zellij status|repair [--json] | sks naruto dashboard latest | sks --mad', description: 'Inspect Zellij runtime status, explain repair (no auto-install), and open the SKS Zellij runtime used by MAD and Naruto lane UI.' },
|
|
641
640
|
{ name: 'tmux', usage: 'sks tmux [--json]', description: 'Show the removed-runtime migration notice and point operators to Zellij.' },
|
|
642
|
-
{ name: 'mad', usage: 'sks --mad [--high]', description: 'Open
|
|
641
|
+
{ name: 'mad-sks', usage: 'sks mad-sks plan|run|status|proof ... | sks --mad [--high]', description: 'Open or inspect MAD-SKS scoped permission workflows and the Zellij permission launcher.' },
|
|
643
642
|
{ name: 'auto-review', usage: 'sks auto-review status|enable|start [--high] | sks --Auto-review --high', description: 'Enable Codex automatic approval review and launch SKS Zellij with the auto-review profile.' },
|
|
644
643
|
{ name: 'dollar-commands', usage: 'sks dollar-commands [--json]', description: 'List Codex App $ commands such as $DFix and $Naruto.' },
|
|
645
644
|
{ name: 'fast-mode', usage: 'sks fast-mode on|off|status|clear [--json]', description: 'Toggle the project-local Fast mode default used by $Fast-On, $Fast-Off, and native-agent routes.' },
|
|
@@ -650,6 +649,7 @@ export const COMMAND_CATALOG = [
|
|
|
650
649
|
{ name: 'qa-loop', usage: 'sks qa-loop prepare|answer|run|status ...', description: 'Dogfood UI/API as human proxy with safety gates, safe fixes, rechecks, Codex Chrome Extension-first web UI evidence, report.' },
|
|
651
650
|
{ name: 'ppt', usage: 'sks ppt build|status <mission-id|latest> [--json]', description: 'Build or inspect $PPT HTML/PDF artifacts from a sealed presentation decision contract.' },
|
|
652
651
|
{ name: 'image-ux-review', usage: 'sks ux-review run --image <path> --fix --json | sks image-ux-review status <mission-id|latest> [--json]', description: 'Run or inspect $Image-UX-Review gpt-image-2/imagegen annotated UI/UX review artifacts, issue ledgers, safe fix loops, recapture, and proof gates.' },
|
|
652
|
+
{ name: 'computer-use', usage: 'sks computer-use import|status|smoke|require ... [--json]', description: 'Record native Mac/non-web Computer Use visual evidence while keeping web verification on the Chrome Extension path.' },
|
|
653
653
|
{ name: 'context7', usage: 'sks context7 check|setup|tools|resolve|docs|evidence ...', description: 'Check, configure, and call the local Context7 MCP requirement.' },
|
|
654
654
|
{ name: 'xai', usage: 'sks xai check|setup|status|docs [--scope project|global] [--url <u>|--command <c>] ...', description: 'Set up and check the optional xAI/Grok Live Search MCP provider for source intelligence.' },
|
|
655
655
|
{ name: 'recallpulse', usage: 'sks recallpulse run|status|eval|governance|checklist <mission-id|latest>', description: 'Run report-only RecallPulse active recall, durable status, proof capsule, evidence envelope, and governance checks.' },
|
|
@@ -691,7 +691,6 @@ export const COMMAND_CATALOG = [
|
|
|
691
691
|
{ name: 'gx', usage: 'sks gx init|render|validate|drift|snapshot [name]', description: 'Create and verify deterministic SVG/HTML visual context cartridges.' },
|
|
692
692
|
{ name: 'profile', usage: 'sks profile show|set <model>', description: 'Inspect or set the current SKS model profile metadata.' },
|
|
693
693
|
{ name: 'gc', usage: 'sks gc [--dry-run] [--json]', description: 'Compact oversized logs and prune stale runtime artifacts.' },
|
|
694
|
-
{ name: 'memory', usage: 'sks memory [--dry-run] [--json]', description: 'Alias for SKS garbage collection and retention handling.' },
|
|
695
694
|
{ name: 'stats', usage: 'sks stats [--json]', description: 'Show package and .sneakoscope storage size.' }
|
|
696
695
|
];
|
|
697
696
|
export function routeById(id) {
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '3.1.
|
|
1
|
+
export const PACKAGE_VERSION = '3.1.9';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -206,25 +206,34 @@ function assertReleaseScripts() {
|
|
|
206
206
|
for (const name of required) {
|
|
207
207
|
assertGate(Boolean(pkg.scripts?.[name]), `package script missing ${name}`);
|
|
208
208
|
}
|
|
209
|
-
|
|
209
|
+
const releaseCheck = String(pkg.scripts?.['release:check'] || '');
|
|
210
|
+
const affectedReleaseCheck = String(pkg.scripts?.['release:check:affected'] || '');
|
|
211
|
+
const delegatesToParallel = releaseCheck.includes('release:check:parallel');
|
|
212
|
+
const delegatesToAffectedDag = releaseCheck.includes('release:check:affected')
|
|
213
|
+
&& affectedReleaseCheck.includes('release-gate-dag-runner')
|
|
214
|
+
&& /--preset\s+affected/.test(affectedReleaseCheck);
|
|
215
|
+
const delegatesDirectlyToDag = releaseCheck.includes('release-gate-dag-runner')
|
|
216
|
+
&& /--preset\s+(?:release|affected)/.test(releaseCheck);
|
|
217
|
+
assertGate(delegatesToParallel || delegatesToAffectedDag || delegatesDirectlyToDag, 'release:check must delegate to the parallel P0 DAG or v2 affected/release DAG', { release_check: releaseCheck, release_check_affected: affectedReleaseCheck });
|
|
210
218
|
}
|
|
211
219
|
function assertRouteNativeBlackbox(routeName) {
|
|
220
|
+
const routeFixtureArgs = ['--agents', '5', '--work-items', '8', '--target-active-slots', '5', '--minimum-work-items', '5', '--max-queue-expansion', '10', '--mock', '--json'];
|
|
212
221
|
if (routeName === 'team') {
|
|
213
|
-
const result = runSksJson(['team', 'native backend fixture',
|
|
222
|
+
const result = runSksJson(['team', 'native backend fixture', ...routeFixtureArgs, '--no-open-zellij']);
|
|
214
223
|
assertGate(result.mock === true, 'Team mock blackbox did not execute', result);
|
|
215
224
|
assertGate(result.native_agent_run?.proof?.ok === true, 'Team blackbox missing native agent proof', result.native_agent_run?.proof);
|
|
216
225
|
assertGate(!JSON.stringify(result).includes('analysis_scout'), 'Team runtime artifact leaked legacy analysis_scout');
|
|
217
226
|
}
|
|
218
227
|
if (routeName === 'research') {
|
|
219
228
|
const prepared = runSksJson(['research', 'prepare', 'native backend fixture', '--json']);
|
|
220
|
-
const result = runSksJson(['research', 'run', prepared.mission_id,
|
|
229
|
+
const result = runSksJson(['research', 'run', prepared.mission_id, ...routeFixtureArgs, '--native-proof-only']);
|
|
221
230
|
assertGate(result.ok === true, 'Research mock blackbox did not pass', result);
|
|
222
231
|
assertGate(result.gate?.gate?.native_agent_proof === true || result.gate?.native_agent_proof === true || result.proof?.ok === true, 'Research proof missing native agent evidence artifact', result);
|
|
223
232
|
assertGate(!JSON.stringify(result).includes('scout-ledger'), 'Research runtime artifact leaked scout-ledger as SSOT');
|
|
224
233
|
}
|
|
225
234
|
if (routeName === 'qa') {
|
|
226
235
|
const prepared = runSksJson(['qa-loop', 'prepare', 'native backend API fixture', '--json']);
|
|
227
|
-
const result = runSksJson(['qa-loop', 'run', prepared.mission_id,
|
|
236
|
+
const result = runSksJson(['qa-loop', 'run', prepared.mission_id, ...routeFixtureArgs, '--native-proof-only']);
|
|
228
237
|
assertGate(result.ok === true, 'QA mock blackbox did not pass', result);
|
|
229
238
|
assertGate(result.gate?.gate?.native_agent_proof === true || result.gate?.native_agent_proof === true || result.proof?.ok === true, 'QA proof missing native agent evidence artifact', result);
|
|
230
239
|
}
|
|
@@ -7,11 +7,15 @@ import path from 'node:path';
|
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
9
9
|
const limits = {
|
|
10
|
-
packedBytes: Number(process.env.SKS_MAX_PACK_BYTES ||
|
|
11
|
-
unpackedBytes: Number(process.env.SKS_MAX_UNPACKED_BYTES ||
|
|
10
|
+
packedBytes: Number(process.env.SKS_MAX_PACK_BYTES || 1536 * 1024),
|
|
11
|
+
unpackedBytes: Number(process.env.SKS_MAX_UNPACKED_BYTES || 6 * 1024 * 1024),
|
|
12
12
|
packFiles: Number(process.env.SKS_MAX_PACK_FILES || 1200),
|
|
13
13
|
trackedFileBytes: Number(process.env.SKS_MAX_TRACKED_FILE_BYTES || 384 * 1024)
|
|
14
14
|
};
|
|
15
|
+
const trackedFileSizeAllowlist = new Set([
|
|
16
|
+
// Historical source documentation export; not included in the npm package payload.
|
|
17
|
+
'docs/sks-local-llm-mode/exports/sks-local-llm-mode-deck.pdf'
|
|
18
|
+
]);
|
|
15
19
|
const npmBin = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
16
20
|
function fail(message, detail = '') {
|
|
17
21
|
console.error(`Size check failed: ${message}`);
|
|
@@ -40,6 +44,8 @@ function checkTrackedFiles() {
|
|
|
40
44
|
const files = result.stdout.toString('utf8').split('\0').filter(Boolean);
|
|
41
45
|
const oversized = [];
|
|
42
46
|
for (const file of files) {
|
|
47
|
+
if (trackedFileSizeAllowlist.has(file))
|
|
48
|
+
continue;
|
|
43
49
|
let stat;
|
|
44
50
|
try {
|
|
45
51
|
stat = fs.statSync(path.join(root, file));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
|
|
5
|
+
import { renderCoreSkillTemplate } from '../core/codex-native/core-skill-manifest.js';
|
|
6
|
+
export { assertGate, emitGate };
|
|
7
|
+
export async function makeTempRoot(prefix) {
|
|
8
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
9
|
+
await fs.mkdir(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
|
|
10
|
+
await fs.mkdir(path.join(root, '.sneakoscope', 'locks'), { recursive: true });
|
|
11
|
+
return root;
|
|
12
|
+
}
|
|
13
|
+
export async function writeText(file, text) {
|
|
14
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
15
|
+
await fs.writeFile(file, text, 'utf8');
|
|
16
|
+
}
|
|
17
|
+
export async function readJson(file) {
|
|
18
|
+
return JSON.parse(await fs.readFile(file, 'utf8'));
|
|
19
|
+
}
|
|
20
|
+
export async function writeManagedCoreSkill(root, relRoot, name) {
|
|
21
|
+
const file = path.join(root, relRoot, name, 'SKILL.md');
|
|
22
|
+
await writeText(file, renderCoreSkillTemplate(name));
|
|
23
|
+
return file;
|
|
24
|
+
}
|
|
25
|
+
export async function writeUserSkill(root, relRoot, name, display = name) {
|
|
26
|
+
const file = path.join(root, relRoot, name, 'SKILL.md');
|
|
27
|
+
await writeText(file, `---\nname: ${display}\ndescription: user-authored fixture\n---\n\nUser skill fixture.\n`);
|
|
28
|
+
return file;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=sks-3-1-8-check-lib.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.9",
|
|
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",
|
|
@@ -617,6 +617,32 @@
|
|
|
617
617
|
"naruto:zellij-dynamic-right-column": "node ./dist/scripts/naruto-zellij-dynamic-right-column-check.js",
|
|
618
618
|
"git:worktree-integration-primary-runtime": "node ./dist/scripts/git-worktree-integration-primary-runtime-check.js",
|
|
619
619
|
"agent:role-config-repair": "node ./dist/scripts/agent-role-config-repair-check.js",
|
|
620
|
+
"core-skill:manifest": "node ./dist/scripts/core-skill-manifest-check.js",
|
|
621
|
+
"core-skill:immutable-sync": "node ./dist/scripts/core-skill-immutable-sync-check.js",
|
|
622
|
+
"core-skill:no-drift": "node ./dist/scripts/core-skill-no-drift-check.js",
|
|
623
|
+
"core-skill:integrity-blackbox": "node ./dist/scripts/core-skill-integrity-blackbox.js",
|
|
624
|
+
"skill:name-canonicalizer": "node ./dist/scripts/skill-name-canonicalizer-check.js",
|
|
625
|
+
"skill:registry-ledger": "node ./dist/scripts/skill-registry-ledger-check.js",
|
|
626
|
+
"skill:dedupe": "node ./dist/scripts/project-skill-dedupe-check.js",
|
|
627
|
+
"skill:sync-atomic": "node ./dist/scripts/skill-sync-atomic-check.js",
|
|
628
|
+
"skill:dedupe-blackbox": "node ./dist/scripts/project-skill-dedupe-blackbox.js",
|
|
629
|
+
"native-capability:repair-matrix": "node ./dist/scripts/native-capability-repair-matrix-check.js",
|
|
630
|
+
"native-capability:repair": "node ./dist/scripts/native-capability-repair-check.js",
|
|
631
|
+
"native-capability:postcheck": "node ./dist/scripts/native-capability-postcheck-check.js",
|
|
632
|
+
"native:image-generation-repair": "node ./dist/scripts/native-image-generation-repair-check.js",
|
|
633
|
+
"native:computer-use-repair": "node ./dist/scripts/native-computer-use-repair-check.js",
|
|
634
|
+
"native:chrome-web-review-repair": "node ./dist/scripts/native-chrome-web-review-repair-check.js",
|
|
635
|
+
"native:app-screenshot-repair": "node ./dist/scripts/native-app-screenshot-repair-check.js",
|
|
636
|
+
"doctor:native-capability-repair": "node ./dist/scripts/doctor-native-capability-repair-check.js",
|
|
637
|
+
"doctor:native-repair-output": "node ./dist/scripts/doctor-native-repair-output-check.js",
|
|
638
|
+
"doctor:native-capability-repair-blackbox": "node ./dist/scripts/doctor-native-capability-repair-blackbox.js",
|
|
639
|
+
"secret:preservation": "node ./dist/scripts/secret-preservation-check.js",
|
|
640
|
+
"config:managed-merge": "node ./dist/scripts/managed-config-merge-check.js",
|
|
641
|
+
"secret:preservation-guard": "node ./dist/scripts/secret-preservation-guard-check.js",
|
|
642
|
+
"secret:supabase-preservation-blackbox": "node ./dist/scripts/supabase-secret-preservation-blackbox.js",
|
|
643
|
+
"update:preserves-supabase-keys": "node ./dist/scripts/update-preserves-supabase-keys-blackbox.js",
|
|
644
|
+
"update:secret-preservation-guard": "node ./dist/scripts/update-secret-preservation-guard-check.js",
|
|
645
|
+
"update:secret-migration-journal": "node ./dist/scripts/update-secret-migration-journal-check.js",
|
|
620
646
|
"release:dag-full-coverage": "node ./dist/scripts/release-dag-full-coverage-check.js",
|
|
621
647
|
"release:cache-glob-hashing": "node ./dist/scripts/release-cache-glob-hashing-check.js",
|
|
622
648
|
"release:check:affected": "npm run build --silent && node ./dist/scripts/release-gate-dag-runner.js --preset affected --changed-since auto",
|