scene-capability-engine 3.3.4 → 3.3.10
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/CHANGELOG.md +151 -78
- package/README.md +6 -6
- package/README.zh.md +6 -6
- package/bin/scene-capability-engine.js +129 -7
- package/docs/331-poc-adaptation-roadmap.md +3 -3
- package/docs/331-poc-dual-track-integration-guide.md +8 -8
- package/docs/331-poc-weekly-delivery-checklist.md +6 -6
- package/docs/README.md +6 -0
- package/docs/adopt-migration-guide.md +13 -13
- package/docs/adoption-guide.md +28 -28
- package/docs/agent-hooks-analysis.md +10 -10
- package/docs/agent-runtime/agent-result-summary-contract.schema.json +50 -0
- package/docs/agent-runtime/agent-result-summary.sample.json +11 -0
- package/docs/agent-runtime/capability-mapping-report.sample.json +42 -0
- package/docs/agent-runtime/capability-mapping-report.schema.json +136 -0
- package/docs/agent-runtime/failure-taxonomy-baseline.json +99 -0
- package/docs/agent-runtime/multi-agent-coordination-policy-baseline.json +38 -0
- package/docs/agent-runtime/strategy-routing-policy-baseline.json +24 -0
- package/docs/agent-runtime/symbol-evidence.sample.json +34 -0
- package/docs/agent-runtime/symbol-evidence.schema.json +128 -0
- package/docs/architecture.md +13 -13
- package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +3 -3
- package/docs/articles/ai-driven-development-philosophy-and-practice.md +3 -3
- package/docs/autonomous-control-guide.md +35 -35
- package/docs/command-reference.md +254 -151
- package/docs/cross-tool-guide.md +7 -7
- package/docs/developer-guide.md +8 -8
- package/docs/document-governance.md +15 -15
- package/docs/environment-management-guide.md +6 -6
- package/docs/examples/add-export-command/design.md +1 -1
- package/docs/faq.md +13 -13
- package/docs/handoff-profile-integration-guide.md +3 -3
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +7 -7
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +1 -1
- package/docs/integration-modes.md +12 -12
- package/docs/integration-philosophy.md +11 -11
- package/docs/interactive-customization/331-poc-sce-integration-checklist.md +24 -24
- package/docs/interactive-customization/README.md +43 -43
- package/docs/interactive-customization/business-mode-policy-baseline.json +33 -0
- package/docs/interactive-customization/dual-ui-mode-integration-guide.md +1 -1
- package/docs/interactive-customization/moqui-adapter-interface.md +2 -2
- package/docs/interactive-customization/moqui-copilot-integration-guide.md +1 -1
- package/docs/interactive-customization/moqui-interactive-template-playbook.md +4 -4
- package/docs/interactive-customization/phase-acceptance-evidence.md +2 -2
- package/docs/knowledge-management-guide.md +6 -6
- package/docs/manual-workflows-guide.md +4 -4
- package/docs/moqui-capability-matrix.md +3 -3
- package/docs/moqui-standard-rebuild-guide.md +8 -8
- package/docs/moqui-template-core-library-playbook.md +27 -27
- package/docs/multi-agent-coordination-guide.md +19 -19
- package/docs/multi-repo-management-guide.md +17 -17
- package/docs/quick-start-with-ai-tools.md +7 -7
- package/docs/quick-start.md +2 -2
- package/docs/release-checklist.md +4 -4
- package/docs/sce-business-mode-map.md +103 -0
- package/docs/sce-capability-matrix-e2e-example.md +94 -0
- package/docs/sce-capability-matrix-roadmap.md +48 -0
- package/docs/security-governance-default-baseline.md +12 -12
- package/docs/spec-collaboration-guide.md +3 -3
- package/docs/spec-locking-guide.md +2 -2
- package/docs/spec-workflow.md +3 -3
- package/docs/starter-kit/README.md +4 -4
- package/docs/starter-kit/handoff-manifest.starter.json +2 -2
- package/docs/starter-kit/release.workflow.sample.yml +1 -1
- package/docs/steering-strategy-guide.md +15 -15
- package/docs/team-collaboration-guide.md +69 -69
- package/docs/testing-strategy.md +2 -2
- package/docs/tools/claude-guide.md +14 -4
- package/docs/tools/cursor-guide.md +14 -14
- package/docs/tools/generic-guide.md +9 -9
- package/docs/tools/kiro-guide.md +4 -4
- package/docs/tools/vscode-guide.md +13 -13
- package/docs/tools/windsurf-guide.md +6 -6
- package/docs/troubleshooting.md +22 -22
- package/docs/upgrade-guide.md +8 -8
- package/docs/value-observability-guide.md +3 -3
- package/docs/zh/README.md +15 -0
- package/docs/zh/quick-start.md +15 -15
- package/docs/zh/release-checklist.md +3 -3
- package/docs/zh/tools/claude-guide.md +16 -6
- package/docs/zh/tools/cursor-guide.md +11 -11
- package/docs/zh/tools/generic-guide.md +13 -13
- package/docs/zh/tools/kiro-guide.md +2 -2
- package/docs/zh/tools/vscode-guide.md +11 -11
- package/docs/zh/tools/windsurf-guide.md +11 -11
- package/docs/zh/value-observability-guide.md +3 -3
- package/lib/adoption/adoption-logger.js +1 -1
- package/lib/adoption/adoption-strategy.js +28 -28
- package/lib/adoption/backup-manager.js +3 -3
- package/lib/adoption/conflict-resolver.js +2 -2
- package/lib/adoption/detection-engine.js +8 -8
- package/lib/adoption/error-formatter.js +4 -4
- package/lib/adoption/file-classifier.js +6 -6
- package/lib/adoption/progress-reporter.js +1 -1
- package/lib/adoption/smart-orchestrator.js +10 -10
- package/lib/adoption/strategy-selector.js +6 -6
- package/lib/adoption/summary-generator.js +1 -1
- package/lib/adoption/template-sync.js +8 -8
- package/lib/auto/autonomous-engine.js +7 -7
- package/lib/auto/checkpoint-manager.js +1 -1
- package/lib/auto/close-loop-runner.js +12 -12
- package/lib/auto/error-recovery-manager.js +1 -1
- package/lib/auto/goal-decomposer.js +1 -1
- package/lib/auto/moqui-recovery-sequence.js +2 -2
- package/lib/auto/progress-tracker.js +1 -1
- package/lib/auto/state-manager.js +1 -1
- package/lib/backup/backup-system.js +10 -10
- package/lib/backup/selective-backup.js +4 -4
- package/lib/collab/agent-registry.js +2 -2
- package/lib/collab/contract-manager.js +1 -1
- package/lib/collab/coordinator.js +2 -2
- package/lib/collab/dependency-manager.js +1 -1
- package/lib/collab/integration-manager.js +1 -1
- package/lib/collab/metadata-manager.js +1 -1
- package/lib/collab/multi-agent-config.js +2 -2
- package/lib/collab/spec-lifecycle-manager.js +2 -2
- package/lib/collab/visualizer.js +1 -1
- package/lib/commands/adopt.js +6 -6
- package/lib/commands/auto.js +56 -56
- package/lib/commands/collab.js +2 -2
- package/lib/commands/docs.js +3 -3
- package/lib/commands/doctor.js +1 -1
- package/lib/commands/knowledge.js +2 -2
- package/lib/commands/lock.js +1 -1
- package/lib/commands/ops.js +1 -1
- package/lib/commands/orchestrate.js +3 -3
- package/lib/commands/rollback.js +1 -1
- package/lib/commands/scene.js +135 -93
- package/lib/commands/session.js +139 -0
- package/lib/commands/spec-bootstrap.js +1 -1
- package/lib/commands/spec-gate.js +2 -2
- package/lib/commands/spec-pipeline.js +1 -1
- package/lib/commands/status.js +4 -4
- package/lib/commands/steering.js +119 -0
- package/lib/commands/value.js +1 -1
- package/lib/commands/watch.js +9 -9
- package/lib/commands/workspace-multi.js +1 -1
- package/lib/context/context-exporter.js +5 -7
- package/lib/context/prompt-generator.js +2 -2
- package/lib/environment/backup-system.js +1 -1
- package/lib/environment/environment-manager.js +2 -2
- package/lib/gitignore/gitignore-backup.js +3 -3
- package/lib/gitignore/gitignore-detector.js +13 -13
- package/lib/gitignore/gitignore-integration.js +3 -3
- package/lib/gitignore/gitignore-transformer.js +4 -4
- package/lib/gitignore/layered-rules-template.js +16 -16
- package/lib/governance/config-manager.js +1 -1
- package/lib/governance/doc-reference-checker.js +4 -4
- package/lib/governance/execution-logger.js +1 -1
- package/lib/governance/file-scanner.js +3 -3
- package/lib/interactive-customization/moqui-interactive-adapter.js +2 -2
- package/lib/knowledge/knowledge-manager.js +1 -1
- package/lib/lock/lock-manager.js +2 -2
- package/lib/lock/steering-file-lock.js +5 -5
- package/lib/lock/task-lock-manager.js +3 -3
- package/lib/operations/audit-logger.js +1 -1
- package/lib/operations/feedback-manager.js +1 -1
- package/lib/operations/operations-manager.js +3 -3
- package/lib/operations/permission-manager.js +2 -2
- package/lib/operations/template-loader.js +1 -1
- package/lib/orchestrator/agent-spawner.js +180 -2
- package/lib/orchestrator/bootstrap-prompt-builder.js +9 -6
- package/lib/orchestrator/orchestration-engine.js +346 -2
- package/lib/orchestrator/orchestrator-config.js +2 -2
- package/lib/repo/config-manager.js +3 -3
- package/lib/repo/handlers/init-handler.js +1 -1
- package/lib/repo/repo-manager.js +2 -2
- package/lib/runtime/business-mode-resolver.js +240 -0
- package/lib/runtime/session-store.js +207 -0
- package/lib/runtime/steering-contract.js +338 -0
- package/lib/scene-runtime/audit-emitter.js +1 -1
- package/lib/scene-runtime/binding-plugin-loader.js +3 -3
- package/lib/scene-runtime/eval-bridge.js +1 -1
- package/lib/scene-runtime/index.js +1 -1
- package/lib/scene-runtime/moqui-extractor.js +1 -1
- package/lib/scene-runtime/plan-compiler.js +1 -1
- package/lib/scene-runtime/policy-gate.js +1 -1
- package/lib/scene-runtime/runtime-executor.js +1 -1
- package/lib/scene-runtime/scene-loader.js +1 -1
- package/lib/spec/bootstrap/context-collector.js +1 -1
- package/lib/spec/pipeline/stage-adapters.js +3 -3
- package/lib/spec/pipeline/state-store.js +1 -1
- package/lib/spec-gate/policy/policy-loader.js +1 -1
- package/lib/spec-gate/rules/default-rules.js +6 -6
- package/lib/steering/adoption-config.js +1 -1
- package/lib/steering/compliance-error-reporter.js +3 -3
- package/lib/steering/context-sync-manager.js +2 -2
- package/lib/steering/index.js +1 -1
- package/lib/steering/spec-steering.js +2 -2
- package/lib/steering/steering-compliance-checker.js +1 -1
- package/lib/steering/steering-loader.js +4 -5
- package/lib/steering/steering-manager.js +4 -4
- package/lib/task/task-claimer.js +5 -5
- package/lib/task/task-status-store.js +2 -2
- package/lib/templates/content-generalizer.js +1 -1
- package/lib/templates/spec-reader.js +2 -2
- package/lib/templates/template-creator.js +1 -1
- package/lib/templates/template-exporter.js +3 -3
- package/lib/templates/template-manager.js +1 -1
- package/lib/upgrade/migration-engine.js +3 -3
- package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +1 -1
- package/lib/utils/file-diff.js +6 -6
- package/lib/utils/tool-detector.js +10 -10
- package/lib/utils/validation.js +5 -5
- package/lib/value/metric-contract-loader.js +1 -1
- package/lib/version/version-manager.js +1 -1
- package/lib/watch/execution-logger.js +1 -1
- package/lib/watch/presets.js +8 -8
- package/lib/watch/watch-manager.js +2 -2
- package/lib/workspace/legacy-kiro-migrator.js +275 -0
- package/lib/workspace/multi/workspace-context-resolver.js +2 -2
- package/lib/workspace/multi/workspace-registry.js +2 -2
- package/lib/workspace/multi/workspace-state-manager.js +3 -3
- package/lib/workspace/workspace-manager.js +1 -1
- package/lib/workspace/workspace-sync.js +2 -2
- package/locales/en.json +4 -4
- package/locales/zh.json +4 -4
- package/package.json +12 -9
- package/template/{.kiro → .sce}/README.md +15 -15
- package/template/{.kiro → .sce}/hooks/check-spec-on-create.kiro.hook +2 -2
- package/template/{.kiro → .sce}/steering/CORE_PRINCIPLES.md +4 -4
- package/template/{.kiro → .sce}/steering/CURRENT_CONTEXT.md +1 -1
- package/template/{.kiro → .sce}/steering/ENVIRONMENT.md +3 -3
- package/template/{.kiro → .sce}/tools/backup_manager.py +3 -3
- package/template/{.kiro → .sce}/tools/configuration_manager.py +1 -1
- package/template/README.md +12 -12
- /package/template/{.kiro → .sce}/hooks/run-tests-on-save.kiro.hook +0 -0
- /package/template/{.kiro → .sce}/hooks/sync-tasks-on-edit.kiro.hook +0 -0
- /package/template/{.kiro → .sce}/specs/SPEC_WORKFLOW_GUIDE.md +0 -0
- /package/template/{.kiro → .sce}/steering/RULES_GUIDE.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/change-impact.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/deployment.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/feedback-response.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/migration-plan.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/monitoring.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/operations.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/rollback.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/tools.yaml +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/troubleshooting.md +0 -0
- /package/template/{.kiro → .sce}/tools/document_evaluator.py +0 -0
- /package/template/{.kiro → .sce}/tools/enhancement_logger.py +0 -0
- /package/template/{.kiro → .sce}/tools/error_handler.py +0 -0
- /package/template/{.kiro → .sce}/tools/improvement_identifier.py +0 -0
- /package/template/{.kiro → .sce}/tools/modification_applicator.py +0 -0
- /package/template/{.kiro → .sce}/tools/quality_gate_enforcer.py +0 -0
- /package/template/{.kiro → .sce}/tools/quality_scorer.py +0 -0
- /package/template/{.kiro → .sce}/tools/report_generator.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_refactored.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_v2.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_v3.py +0 -0
- /package/template/{.kiro → .sce}/tools/workflow_quality_gate.py +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { SessionStore } = require('../runtime/session-store');
|
|
3
|
+
|
|
4
|
+
function registerSessionCommands(program) {
|
|
5
|
+
const session = program
|
|
6
|
+
.command('session')
|
|
7
|
+
.description('Manage universal runtime sessions (start/resume/snapshot)');
|
|
8
|
+
|
|
9
|
+
session
|
|
10
|
+
.command('start [objective]')
|
|
11
|
+
.description('Start a new SCE runtime session')
|
|
12
|
+
.option('--tool <tool>', 'Target tool (codex|claude|cursor|generic)', 'generic')
|
|
13
|
+
.option('--agent-version <version>', 'Target agent version for compatibility tracking')
|
|
14
|
+
.option('--id <id>', 'Custom session id')
|
|
15
|
+
.option('--json', 'Output as JSON')
|
|
16
|
+
.action(async (objective, options) => {
|
|
17
|
+
try {
|
|
18
|
+
const store = new SessionStore(process.cwd());
|
|
19
|
+
const created = await store.startSession({
|
|
20
|
+
tool: options.tool,
|
|
21
|
+
agentVersion: options.agentVersion,
|
|
22
|
+
objective: objective || '',
|
|
23
|
+
sessionId: options.id,
|
|
24
|
+
});
|
|
25
|
+
_printSessionResult('session_start', created, options.json);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
_exitWithError(error, options.json);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
session
|
|
32
|
+
.command('resume [sessionRef]')
|
|
33
|
+
.description('Resume a session by id, or use latest by default')
|
|
34
|
+
.option('--status <status>', 'Status to set after resume', 'active')
|
|
35
|
+
.option('--json', 'Output as JSON')
|
|
36
|
+
.action(async (sessionRef, options) => {
|
|
37
|
+
try {
|
|
38
|
+
const store = new SessionStore(process.cwd());
|
|
39
|
+
const resumed = await store.resumeSession(sessionRef || 'latest', {
|
|
40
|
+
status: options.status,
|
|
41
|
+
});
|
|
42
|
+
_printSessionResult('session_resume', resumed, options.json);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
_exitWithError(error, options.json);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
session
|
|
49
|
+
.command('snapshot [sessionRef]')
|
|
50
|
+
.description('Create a session snapshot by id, or use latest by default')
|
|
51
|
+
.option('--summary <summary>', 'Snapshot summary text', '')
|
|
52
|
+
.option('--status <status>', 'Session status after snapshot')
|
|
53
|
+
.option('--payload <json>', 'Optional JSON payload')
|
|
54
|
+
.option('--json', 'Output as JSON')
|
|
55
|
+
.action(async (sessionRef, options) => {
|
|
56
|
+
try {
|
|
57
|
+
const store = new SessionStore(process.cwd());
|
|
58
|
+
const payload = _parsePayload(options.payload);
|
|
59
|
+
const snapshotted = await store.snapshotSession(sessionRef || 'latest', {
|
|
60
|
+
summary: options.summary,
|
|
61
|
+
status: options.status,
|
|
62
|
+
payload,
|
|
63
|
+
});
|
|
64
|
+
_printSessionResult('session_snapshot', snapshotted, options.json);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
_exitWithError(error, options.json);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
session
|
|
71
|
+
.command('show [sessionRef]')
|
|
72
|
+
.description('Show a session by id, or latest by default')
|
|
73
|
+
.option('--json', 'Output as JSON')
|
|
74
|
+
.action(async (sessionRef, options) => {
|
|
75
|
+
try {
|
|
76
|
+
const store = new SessionStore(process.cwd());
|
|
77
|
+
const current = await store.getSession(sessionRef || 'latest');
|
|
78
|
+
_printSessionResult('session_show', current, options.json);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
_exitWithError(error, options.json);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function _parsePayload(raw) {
|
|
86
|
+
if (raw == null || `${raw}`.trim() === '') {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(raw);
|
|
91
|
+
} catch (_error) {
|
|
92
|
+
throw new Error('Invalid --payload JSON');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function _printSessionResult(action, session, asJson = false) {
|
|
97
|
+
if (asJson) {
|
|
98
|
+
console.log(JSON.stringify({
|
|
99
|
+
success: true,
|
|
100
|
+
action,
|
|
101
|
+
session,
|
|
102
|
+
}, null, 2));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const snapshots = Array.isArray(session.snapshots) ? session.snapshots.length : 0;
|
|
107
|
+
console.log(chalk.green('✓ Session updated'));
|
|
108
|
+
console.log(chalk.gray(`Session: ${session.session_id}`));
|
|
109
|
+
console.log(chalk.gray(`Tool: ${session.tool}`));
|
|
110
|
+
if (session.agent_version) {
|
|
111
|
+
console.log(chalk.gray(`Agent version: ${session.agent_version}`));
|
|
112
|
+
}
|
|
113
|
+
console.log(chalk.gray(`Status: ${session.status}`));
|
|
114
|
+
console.log(chalk.gray(`Snapshots: ${snapshots}`));
|
|
115
|
+
if (session.steering && session.steering.compatibility) {
|
|
116
|
+
const supported = session.steering.compatibility.supported;
|
|
117
|
+
const label = supported === null ? 'unknown' : supported;
|
|
118
|
+
console.log(chalk.gray(`Compatibility: ${label} (${session.steering.compatibility.rule})`));
|
|
119
|
+
}
|
|
120
|
+
if (session.objective) {
|
|
121
|
+
console.log(chalk.gray(`Objective: ${session.objective}`));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function _exitWithError(error, asJson = false) {
|
|
126
|
+
if (asJson) {
|
|
127
|
+
console.log(JSON.stringify({
|
|
128
|
+
success: false,
|
|
129
|
+
error: error.message,
|
|
130
|
+
}, null, 2));
|
|
131
|
+
} else {
|
|
132
|
+
console.error(chalk.red('Error:'), error.message);
|
|
133
|
+
}
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = {
|
|
138
|
+
registerSessionCommands,
|
|
139
|
+
};
|
|
@@ -65,7 +65,7 @@ async function runSpecBootstrap(options = {}, dependencies = {}) {
|
|
|
65
65
|
answers
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
const specPath = path.join(projectPath, '.
|
|
68
|
+
const specPath = path.join(projectPath, '.sce', 'specs', specName);
|
|
69
69
|
const files = {
|
|
70
70
|
requirements: path.join(specPath, 'requirements.md'),
|
|
71
71
|
design: path.join(specPath, 'design.md'),
|
|
@@ -35,7 +35,7 @@ async function runSpecGate(options = {}, dependencies = {}) {
|
|
|
35
35
|
|
|
36
36
|
const specId = specTargets[0];
|
|
37
37
|
|
|
38
|
-
const specPath = path.join(projectPath, '.
|
|
38
|
+
const specPath = path.join(projectPath, '.sce', 'specs', specId);
|
|
39
39
|
if (!await fs.pathExists(specPath)) {
|
|
40
40
|
throw new Error(`Spec not found: ${specId}`);
|
|
41
41
|
}
|
|
@@ -73,7 +73,7 @@ async function generateSpecGatePolicyTemplate(options = {}, dependencies = {}) {
|
|
|
73
73
|
|
|
74
74
|
const outputPath = options.out
|
|
75
75
|
? (path.isAbsolute(options.out) ? options.out : path.join(projectPath, options.out))
|
|
76
|
-
: path.join(projectPath, '.
|
|
76
|
+
: path.join(projectPath, '.sce', 'config', 'spec-gate-policy.template.json');
|
|
77
77
|
|
|
78
78
|
await fs.ensureDir(path.dirname(outputPath));
|
|
79
79
|
await fs.writeJson(outputPath, template, { spaces: 2 });
|
|
@@ -32,7 +32,7 @@ async function runSpecPipeline(options = {}, dependencies = {}) {
|
|
|
32
32
|
|
|
33
33
|
const specId = specTargets[0];
|
|
34
34
|
|
|
35
|
-
const specPath = path.join(projectPath, '.
|
|
35
|
+
const specPath = path.join(projectPath, '.sce', 'specs', specId);
|
|
36
36
|
if (!await fs.pathExists(specPath)) {
|
|
37
37
|
throw new Error(`Spec not found: ${specId}`);
|
|
38
38
|
}
|
package/lib/commands/status.js
CHANGED
|
@@ -29,12 +29,12 @@ async function statusCommand(options = {}) {
|
|
|
29
29
|
console.log();
|
|
30
30
|
|
|
31
31
|
try {
|
|
32
|
-
// 1. Check if .
|
|
33
|
-
const kiroPath = path.join(projectPath, '.
|
|
32
|
+
// 1. Check if .sce/ exists
|
|
33
|
+
const kiroPath = path.join(projectPath, '.sce');
|
|
34
34
|
const kiroExists = await fs.pathExists(kiroPath);
|
|
35
35
|
|
|
36
36
|
if (!kiroExists) {
|
|
37
|
-
console.log(chalk.yellow('⚠️ No .
|
|
37
|
+
console.log(chalk.yellow('⚠️ No .sce/ directory found'));
|
|
38
38
|
console.log();
|
|
39
39
|
console.log('This project has not been adopted yet.');
|
|
40
40
|
console.log('Run ' + chalk.cyan('sce adopt') + ' to get started.');
|
|
@@ -64,7 +64,7 @@ async function statusCommand(options = {}) {
|
|
|
64
64
|
await displayDocumentCompliance(projectPath);
|
|
65
65
|
|
|
66
66
|
// 4. List specs
|
|
67
|
-
const specsPath = path.join(projectPath, '.
|
|
67
|
+
const specsPath = path.join(projectPath, '.sce/specs');
|
|
68
68
|
const specsExist = await fs.pathExists(specsPath);
|
|
69
69
|
|
|
70
70
|
if (!specsExist) {
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { SteeringContract, normalizeToolName } = require('../runtime/steering-contract');
|
|
5
|
+
|
|
6
|
+
function registerSteeringCommands(program) {
|
|
7
|
+
const steering = program
|
|
8
|
+
.command('steering')
|
|
9
|
+
.description('Manage universal steering contract for cross-agent runtime');
|
|
10
|
+
|
|
11
|
+
steering
|
|
12
|
+
.command('init')
|
|
13
|
+
.description('Initialize .sce steering contract')
|
|
14
|
+
.option('--json', 'Output as JSON')
|
|
15
|
+
.action(async (options) => {
|
|
16
|
+
try {
|
|
17
|
+
const contract = new SteeringContract(process.cwd());
|
|
18
|
+
const result = await contract.ensureContract();
|
|
19
|
+
if (options.json) {
|
|
20
|
+
console.log(JSON.stringify({
|
|
21
|
+
success: true,
|
|
22
|
+
action: 'steering_init',
|
|
23
|
+
...result,
|
|
24
|
+
}, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log(chalk.green('✓ Steering contract initialized'));
|
|
29
|
+
console.log(chalk.gray(`Manifest: ${result.manifestPath}`));
|
|
30
|
+
if (result.preparedLayers.length > 0) {
|
|
31
|
+
console.log(chalk.gray('Layers:'));
|
|
32
|
+
for (const layer of result.preparedLayers) {
|
|
33
|
+
console.log(chalk.gray(` - ${layer.layer} (${layer.file}) <= ${layer.source}`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
_exitWithError(error, options.json);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
steering
|
|
42
|
+
.command('compile')
|
|
43
|
+
.description('Compile steering contract into an agent-specific runtime bundle')
|
|
44
|
+
.option('--tool <tool>', 'Target tool (codex|claude|cursor|generic)', 'codex')
|
|
45
|
+
.option('--agent-version <version>', 'Target agent version for compatibility check')
|
|
46
|
+
.option('--format <format>', 'Output format (markdown|json)', 'markdown')
|
|
47
|
+
.option('--out <path>', 'Output file path (default under .sce/steering/compiled)')
|
|
48
|
+
.option('--json', 'Output command result as JSON')
|
|
49
|
+
.action(async (options) => {
|
|
50
|
+
try {
|
|
51
|
+
const workspaceRoot = process.cwd();
|
|
52
|
+
const tool = normalizeToolName(options.tool || 'codex');
|
|
53
|
+
const format = _normalizeFormat(options.format);
|
|
54
|
+
const contract = new SteeringContract(workspaceRoot);
|
|
55
|
+
await contract.ensureContract();
|
|
56
|
+
const payload = await contract.buildCompilePayload(tool, options.agentVersion);
|
|
57
|
+
|
|
58
|
+
const outputPath = options.out
|
|
59
|
+
? path.resolve(workspaceRoot, options.out)
|
|
60
|
+
: path.join(workspaceRoot, '.sce', 'steering', 'compiled', `steering-${tool}.${format === 'json' ? 'json' : 'md'}`);
|
|
61
|
+
await fs.ensureDir(path.dirname(outputPath));
|
|
62
|
+
|
|
63
|
+
if (format === 'json') {
|
|
64
|
+
await fs.writeJson(outputPath, payload, { spaces: 2 });
|
|
65
|
+
} else {
|
|
66
|
+
await fs.writeFile(outputPath, contract.renderMarkdown(payload), 'utf8');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const response = {
|
|
70
|
+
success: true,
|
|
71
|
+
action: 'steering_compile',
|
|
72
|
+
tool,
|
|
73
|
+
format,
|
|
74
|
+
agent_version: payload.agent_version,
|
|
75
|
+
source_mode: payload.source_mode,
|
|
76
|
+
compatibility: payload.compatibility,
|
|
77
|
+
output: path.relative(workspaceRoot, outputPath).replace(/\\/g, '/'),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (options.json) {
|
|
81
|
+
console.log(JSON.stringify(response, null, 2));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log(chalk.green('✓ Steering compiled'));
|
|
86
|
+
console.log(chalk.gray(`Tool: ${tool}`));
|
|
87
|
+
console.log(chalk.gray(`Format: ${format}`));
|
|
88
|
+
console.log(chalk.gray(`Source mode: ${payload.source_mode}`));
|
|
89
|
+
console.log(chalk.gray(`Compatibility: ${payload.compatibility.supported === null ? 'unknown' : payload.compatibility.supported} (${payload.compatibility.rule})`));
|
|
90
|
+
console.log(chalk.gray(`Output: ${response.output}`));
|
|
91
|
+
} catch (error) {
|
|
92
|
+
_exitWithError(error, options.json);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function _normalizeFormat(format) {
|
|
98
|
+
const normalized = `${format || 'markdown'}`.trim().toLowerCase();
|
|
99
|
+
if (normalized === 'json') {
|
|
100
|
+
return 'json';
|
|
101
|
+
}
|
|
102
|
+
return 'markdown';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function _exitWithError(error, asJson = false) {
|
|
106
|
+
if (asJson) {
|
|
107
|
+
console.log(JSON.stringify({
|
|
108
|
+
success: false,
|
|
109
|
+
error: error.message,
|
|
110
|
+
}, null, 2));
|
|
111
|
+
} else {
|
|
112
|
+
console.error(chalk.red('Error:'), error.message);
|
|
113
|
+
}
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
registerSteeringCommands,
|
|
119
|
+
};
|
package/lib/commands/value.js
CHANGED
package/lib/commands/watch.js
CHANGED
|
@@ -21,7 +21,7 @@ const { listPresets, getPreset, mergePreset, validatePreset } = require('../watc
|
|
|
21
21
|
*/
|
|
22
22
|
async function startWatch(options = {}) {
|
|
23
23
|
const projectPath = process.cwd();
|
|
24
|
-
const configPath = options.config || path.join(projectPath, '.
|
|
24
|
+
const configPath = options.config || path.join(projectPath, '.sce/watch-config.json');
|
|
25
25
|
|
|
26
26
|
console.log(chalk.red('🔥') + ' Starting Watch Mode');
|
|
27
27
|
console.log();
|
|
@@ -87,7 +87,7 @@ async function startWatch(options = {}) {
|
|
|
87
87
|
*/
|
|
88
88
|
async function stopWatch(options = {}) {
|
|
89
89
|
const projectPath = process.cwd();
|
|
90
|
-
const configPath = path.join(projectPath, '.
|
|
90
|
+
const configPath = path.join(projectPath, '.sce/watch-config.json');
|
|
91
91
|
|
|
92
92
|
console.log(chalk.red('🔥') + ' Stopping Watch Mode');
|
|
93
93
|
console.log();
|
|
@@ -114,7 +114,7 @@ async function stopWatch(options = {}) {
|
|
|
114
114
|
*/
|
|
115
115
|
async function statusWatch(options = {}) {
|
|
116
116
|
const projectPath = process.cwd();
|
|
117
|
-
const configPath = path.join(projectPath, '.
|
|
117
|
+
const configPath = path.join(projectPath, '.sce/watch-config.json');
|
|
118
118
|
|
|
119
119
|
console.log(chalk.red('🔥') + ' Watch Mode Status');
|
|
120
120
|
console.log();
|
|
@@ -244,7 +244,7 @@ function resolveWatchLogPath(projectPath, options = {}) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
const logFile = options.logFile || 'execution.log';
|
|
247
|
-
return path.join(projectPath, '.
|
|
247
|
+
return path.join(projectPath, '.sce', 'watch', 'logs', logFile);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
async function readRawLogLines(logPath) {
|
|
@@ -345,7 +345,7 @@ async function followLogStream(logPath, options = {}) {
|
|
|
345
345
|
*/
|
|
346
346
|
async function metricsWatch(options = {}) {
|
|
347
347
|
const projectPath = process.cwd();
|
|
348
|
-
const configPath = path.join(projectPath, '.
|
|
348
|
+
const configPath = path.join(projectPath, '.sce/watch-config.json');
|
|
349
349
|
|
|
350
350
|
console.log(chalk.red('🔥') + ' Watch Mode Metrics');
|
|
351
351
|
console.log();
|
|
@@ -405,7 +405,7 @@ async function metricsWatch(options = {}) {
|
|
|
405
405
|
*/
|
|
406
406
|
async function initWatch(options = {}) {
|
|
407
407
|
const projectPath = process.cwd();
|
|
408
|
-
const configPath = path.join(projectPath, '.
|
|
408
|
+
const configPath = path.join(projectPath, '.sce/watch-config.json');
|
|
409
409
|
|
|
410
410
|
console.log(chalk.red('🔥') + ' Initialize Watch Configuration');
|
|
411
411
|
console.log();
|
|
@@ -426,8 +426,8 @@ async function initWatch(options = {}) {
|
|
|
426
426
|
enabled: true,
|
|
427
427
|
patterns: [
|
|
428
428
|
'**/tasks.md',
|
|
429
|
-
'**/.
|
|
430
|
-
'**/.
|
|
429
|
+
'**/.sce/specs/*/requirements.md',
|
|
430
|
+
'**/.sce/specs/*/design.md'
|
|
431
431
|
],
|
|
432
432
|
ignored: [
|
|
433
433
|
'**/node_modules/**',
|
|
@@ -550,7 +550,7 @@ async function listPresetsWatch(options = {}) {
|
|
|
550
550
|
*/
|
|
551
551
|
async function installPresetWatch(presetName, options = {}) {
|
|
552
552
|
const projectPath = process.cwd();
|
|
553
|
-
const configPath = path.join(projectPath, '.
|
|
553
|
+
const configPath = path.join(projectPath, '.sce/watch-config.json');
|
|
554
554
|
|
|
555
555
|
console.log(chalk.red('🔥') + ` Installing Preset: ${chalk.cyan(presetName)}`);
|
|
556
556
|
console.log();
|
|
@@ -274,7 +274,7 @@ async function infoWorkspace(name = null, options = {}) {
|
|
|
274
274
|
// Count Specs in workspace
|
|
275
275
|
let specCount = 0;
|
|
276
276
|
try {
|
|
277
|
-
const specsPath = path.join(workspace.getPlatformPath(), '.
|
|
277
|
+
const specsPath = path.join(workspace.getPlatformPath(), '.sce', 'specs');
|
|
278
278
|
const exists = await fs.pathExists(specsPath);
|
|
279
279
|
|
|
280
280
|
if (exists) {
|
|
@@ -29,7 +29,7 @@ class ContextExporter {
|
|
|
29
29
|
} = options;
|
|
30
30
|
|
|
31
31
|
try {
|
|
32
|
-
const specPath = path.join(projectPath, '.
|
|
32
|
+
const specPath = path.join(projectPath, '.sce/specs', specName);
|
|
33
33
|
|
|
34
34
|
// 检查 Spec 是否存在
|
|
35
35
|
const specExists = await fs.pathExists(specPath);
|
|
@@ -183,15 +183,13 @@ ${content}`;
|
|
|
183
183
|
* @returns {Promise<string>} Steering 内容
|
|
184
184
|
*/
|
|
185
185
|
async includeSteeringRules(projectPath, steeringFiles) {
|
|
186
|
-
const
|
|
186
|
+
const steeringRoot = path.join(projectPath, '.sce/steering');
|
|
187
187
|
const sections = ['## Steering Rules\n'];
|
|
188
188
|
|
|
189
189
|
for (const fileName of steeringFiles) {
|
|
190
|
-
const filePath = path.join(steeringPath, fileName);
|
|
191
|
-
|
|
192
190
|
try {
|
|
193
|
-
const
|
|
194
|
-
if (!
|
|
191
|
+
const filePath = path.join(steeringRoot, fileName);
|
|
192
|
+
if (!await fs.pathExists(filePath)) {
|
|
195
193
|
continue;
|
|
196
194
|
}
|
|
197
195
|
|
|
@@ -264,7 +262,7 @@ If you encounter issues:
|
|
|
264
262
|
*/
|
|
265
263
|
async generateTaskContext(projectPath, specName, taskId) {
|
|
266
264
|
try {
|
|
267
|
-
const specPath = path.join(projectPath, '.
|
|
265
|
+
const specPath = path.join(projectPath, '.sce/specs', specName);
|
|
268
266
|
|
|
269
267
|
// 读取所有文件
|
|
270
268
|
const requirements = await this.readSpecFile(specPath, 'requirements.md');
|
|
@@ -28,7 +28,7 @@ class PromptGenerator {
|
|
|
28
28
|
} = options;
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
const specPath = path.join(projectPath, '.
|
|
31
|
+
const specPath = path.join(projectPath, '.sce/specs', specName);
|
|
32
32
|
|
|
33
33
|
// 检查 Spec 是否存在
|
|
34
34
|
const specExists = await fs.pathExists(specPath);
|
|
@@ -449,7 +449,7 @@ class PromptGenerator {
|
|
|
449
449
|
getToolSpecificNotes(targetTool) {
|
|
450
450
|
const notes = {
|
|
451
451
|
'generic': 'This prompt is compatible with any AI coding assistant.',
|
|
452
|
-
'claude-code': 'Use this prompt with Claude Code by copying it into the chat.',
|
|
452
|
+
'claude-code': 'Use this prompt with Claude Code by copying it into the chat (recommended launch: claude --dangerously-skip-permission).',
|
|
453
453
|
'cursor': 'Use this prompt with Cursor by pasting it into the composer.',
|
|
454
454
|
'codex': 'Use this prompt with GitHub Copilot by including it in your code comments.',
|
|
455
455
|
'SCE': 'This prompt is optimized for AI IDE with automatic steering loading.'
|
|
@@ -30,13 +30,13 @@ class EnvironmentManager {
|
|
|
30
30
|
if (this.workspaceContext) {
|
|
31
31
|
return path.join(
|
|
32
32
|
this.projectRoot,
|
|
33
|
-
'.
|
|
33
|
+
'.sce',
|
|
34
34
|
'workspaces',
|
|
35
35
|
this.workspaceContext,
|
|
36
36
|
'environments.json'
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
|
-
return path.join(this.projectRoot, '.
|
|
39
|
+
return path.join(this.projectRoot, '.sce', 'environments.json');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -51,7 +51,7 @@ class GitignoreBackup {
|
|
|
51
51
|
const backupId = `gitignore-${timestamp}`;
|
|
52
52
|
|
|
53
53
|
// Create backup directory
|
|
54
|
-
const backupDir = path.join(projectPath, '.
|
|
54
|
+
const backupDir = path.join(projectPath, '.sce', 'backups');
|
|
55
55
|
await fs.ensureDir(backupDir);
|
|
56
56
|
|
|
57
57
|
// Write backup file
|
|
@@ -90,7 +90,7 @@ class GitignoreBackup {
|
|
|
90
90
|
* @returns {Promise<RestoreResult>}
|
|
91
91
|
*/
|
|
92
92
|
async restore(projectPath, backupId) {
|
|
93
|
-
const backupDir = path.join(projectPath, '.
|
|
93
|
+
const backupDir = path.join(projectPath, '.sce', 'backups');
|
|
94
94
|
const backupPath = path.join(backupDir, backupId);
|
|
95
95
|
const metaPath = path.join(backupDir, `${backupId}.meta.json`);
|
|
96
96
|
|
|
@@ -135,7 +135,7 @@ class GitignoreBackup {
|
|
|
135
135
|
* @returns {Promise<BackupInfo[]>}
|
|
136
136
|
*/
|
|
137
137
|
async listBackups(projectPath) {
|
|
138
|
-
const backupDir = path.join(projectPath, '.
|
|
138
|
+
const backupDir = path.join(projectPath, '.sce', 'backups');
|
|
139
139
|
|
|
140
140
|
if (!await fs.pathExists(backupDir)) {
|
|
141
141
|
return [];
|
|
@@ -10,10 +10,10 @@ const path = require('path');
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {Object} GitignoreRule
|
|
13
|
-
* @property {string} pattern - Rule pattern (e.g., '.
|
|
13
|
+
* @property {string} pattern - Rule pattern (e.g., '.sce/backups/')
|
|
14
14
|
* @property {string} type - 'exclusion' | 'negation' | 'comment'
|
|
15
15
|
* @property {number} line - Line number in file
|
|
16
|
-
* @property {boolean} isKiroRelated - Rule relates to .
|
|
16
|
+
* @property {boolean} isKiroRelated - Rule relates to .sce/
|
|
17
17
|
* @property {boolean} isManaged - Rule is in sce-managed section
|
|
18
18
|
*/
|
|
19
19
|
|
|
@@ -31,19 +31,19 @@ class GitignoreDetector {
|
|
|
31
31
|
constructor() {
|
|
32
32
|
// Old patterns that indicate blanket exclusion
|
|
33
33
|
this.OLD_PATTERNS = [
|
|
34
|
-
/^\.
|
|
35
|
-
/^\.
|
|
36
|
-
/^\.
|
|
34
|
+
/^\.sce\/?\s*$/, // .sce/ or .sce
|
|
35
|
+
/^\.sce\/\*\s*$/, // .sce/*
|
|
36
|
+
/^\.sce\/\*\*\s*$/ // .sce/**
|
|
37
37
|
];
|
|
38
38
|
|
|
39
39
|
// Required layered rules (key patterns to check)
|
|
40
40
|
this.REQUIRED_RULES = [
|
|
41
|
-
'.
|
|
42
|
-
'.
|
|
43
|
-
'.
|
|
44
|
-
'.
|
|
45
|
-
'.
|
|
46
|
-
'.
|
|
41
|
+
'.sce/steering/CURRENT_CONTEXT.md',
|
|
42
|
+
'.sce/contexts/.active',
|
|
43
|
+
'.sce/environments.json',
|
|
44
|
+
'.sce/backups/',
|
|
45
|
+
'.sce/logs/',
|
|
46
|
+
'.sce/reports/'
|
|
47
47
|
];
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -151,8 +151,8 @@ class GitignoreDetector {
|
|
|
151
151
|
return; // Skip blank lines
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
// Check if .
|
|
155
|
-
const isKiroRelated = pattern.includes('.
|
|
154
|
+
// Check if .sce-related
|
|
155
|
+
const isKiroRelated = pattern.includes('.sce');
|
|
156
156
|
|
|
157
157
|
rules.push({
|
|
158
158
|
pattern: trimmed,
|
|
@@ -167,7 +167,7 @@ class GitignoreIntegration {
|
|
|
167
167
|
if (result.action === 'skipped') {
|
|
168
168
|
console.log(chalk.green('✅ .gitignore is already optimal'));
|
|
169
169
|
console.log();
|
|
170
|
-
console.log(chalk.gray(' Current strategy: Layered .
|
|
170
|
+
console.log(chalk.gray(' Current strategy: Layered .sce/ management'));
|
|
171
171
|
console.log(chalk.gray(' - Specs are committable'));
|
|
172
172
|
console.log(chalk.gray(' - Personal state is excluded'));
|
|
173
173
|
console.log();
|
|
@@ -187,7 +187,7 @@ class GitignoreIntegration {
|
|
|
187
187
|
|
|
188
188
|
if (result.backupId) {
|
|
189
189
|
console.log(chalk.blue('📦 Backup created:'), result.backupId);
|
|
190
|
-
console.log(chalk.gray(' Location:'), `.
|
|
190
|
+
console.log(chalk.gray(' Location:'), `.sce/backups/${result.backupId}`);
|
|
191
191
|
console.log();
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -248,7 +248,7 @@ class GitignoreIntegration {
|
|
|
248
248
|
console.log(chalk.yellow(` - Removed ${result.removed.length} old pattern(s)`));
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
console.log(chalk.green(' + Added layered .
|
|
251
|
+
console.log(chalk.green(' + Added layered .sce/ exclusion rules'));
|
|
252
252
|
console.log(chalk.green(' + Specs are now committable'));
|
|
253
253
|
console.log(chalk.green(' + Personal state is excluded'));
|
|
254
254
|
console.log();
|
|
@@ -19,9 +19,9 @@ class GitignoreTransformer {
|
|
|
19
19
|
constructor() {
|
|
20
20
|
// Old patterns to remove
|
|
21
21
|
this.OLD_PATTERNS = [
|
|
22
|
-
/^\.
|
|
23
|
-
/^\.
|
|
24
|
-
/^\.
|
|
22
|
+
/^\.sce\/?\s*$/,
|
|
23
|
+
/^\.sce\/\*\s*$/,
|
|
24
|
+
/^\.sce\/\*\*\s*$/
|
|
25
25
|
];
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -64,7 +64,7 @@ class GitignoreTransformer {
|
|
|
64
64
|
lines.forEach(line => {
|
|
65
65
|
const trimmed = line.trim();
|
|
66
66
|
if (trimmed && !trimmed.startsWith('#') && !this.isOldPattern(trimmed)) {
|
|
67
|
-
if (!trimmed.includes('.
|
|
67
|
+
if (!trimmed.includes('.sce')) {
|
|
68
68
|
result.preserved.push(trimmed);
|
|
69
69
|
}
|
|
70
70
|
}
|