scene-capability-engine 3.5.2 → 3.6.2

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.
@@ -0,0 +1,139 @@
1
+ const path = require('path');
2
+ const fs = require('fs-extra');
3
+ const {
4
+ DEFAULT_DB_RELATIVE_PATH,
5
+ getSceStateStore,
6
+ buildTaskRef,
7
+ formatSegment
8
+ } = require('../state/sce-state-store');
9
+
10
+ const TASK_REF_PATTERN = /^\d{2,}\.\d{2,}\.\d{2,}$/;
11
+
12
+ function normalizeId(value) {
13
+ if (typeof value !== 'string') {
14
+ return '';
15
+ }
16
+ return value.trim();
17
+ }
18
+
19
+ function parseTaskRef(taskRef) {
20
+ const normalized = normalizeId(taskRef);
21
+ if (!TASK_REF_PATTERN.test(normalized)) {
22
+ return null;
23
+ }
24
+
25
+ const [sceneSegment, specSegment, taskSegment] = normalized.split('.');
26
+ return {
27
+ task_ref: normalized,
28
+ scene_no: Number.parseInt(sceneSegment, 10),
29
+ spec_no: Number.parseInt(specSegment, 10),
30
+ task_no: Number.parseInt(taskSegment, 10)
31
+ };
32
+ }
33
+
34
+ class TaskRefRegistry {
35
+ constructor(projectPath = process.cwd(), options = {}) {
36
+ this.projectPath = projectPath;
37
+ this.fileSystem = options.fileSystem || fs;
38
+ this.stateStore = options.stateStore || getSceStateStore(projectPath, {
39
+ fileSystem: this.fileSystem,
40
+ env: options.env,
41
+ backend: options.backend
42
+ });
43
+ }
44
+
45
+ getRegistryPath() {
46
+ return this.stateStore.dbPath || path.join(this.projectPath, DEFAULT_DB_RELATIVE_PATH);
47
+ }
48
+
49
+ getRegistryRelativePath() {
50
+ const storeRelativePath = this.stateStore.getStoreRelativePath
51
+ ? this.stateStore.getStoreRelativePath()
52
+ : null;
53
+ if (storeRelativePath) {
54
+ return storeRelativePath;
55
+ }
56
+ return DEFAULT_DB_RELATIVE_PATH.replace(/\\/g, '/');
57
+ }
58
+
59
+ async resolveOrCreateRef(options = {}) {
60
+ const sceneId = normalizeId(options.sceneId);
61
+ const specId = normalizeId(options.specId);
62
+ const taskKey = normalizeId(options.taskKey);
63
+ if (!sceneId || !specId || !taskKey) {
64
+ throw new Error('sceneId/specId/taskKey are required for task reference assignment');
65
+ }
66
+
67
+ const source = normalizeId(options.source) || 'unknown';
68
+ const metadata = options.metadata && typeof options.metadata === 'object'
69
+ ? { ...options.metadata }
70
+ : {};
71
+
72
+ const result = await this.stateStore.resolveOrCreateTaskRef({
73
+ sceneId,
74
+ specId,
75
+ taskKey,
76
+ source,
77
+ metadata
78
+ });
79
+
80
+ if (!result) {
81
+ throw new Error('SQLite state backend is unavailable. task_ref assignment requires sqlite support.');
82
+ }
83
+
84
+ return {
85
+ ...result,
86
+ registry_path: this.getRegistryRelativePath()
87
+ };
88
+ }
89
+
90
+ async lookupByRef(taskRef) {
91
+ const parsed = parseTaskRef(taskRef);
92
+ if (!parsed) {
93
+ return null;
94
+ }
95
+
96
+ const result = await this.stateStore.lookupTaskRef(parsed.task_ref);
97
+ if (!result) {
98
+ return null;
99
+ }
100
+
101
+ return {
102
+ ...result,
103
+ registry_path: this.getRegistryRelativePath()
104
+ };
105
+ }
106
+
107
+ async lookupByTuple(options = {}) {
108
+ const sceneId = normalizeId(options.sceneId);
109
+ const specId = normalizeId(options.specId);
110
+ const taskKey = normalizeId(options.taskKey);
111
+ if (!sceneId || !specId || !taskKey) {
112
+ return null;
113
+ }
114
+
115
+ const result = await this.stateStore.lookupTaskTuple({
116
+ sceneId,
117
+ specId,
118
+ taskKey
119
+ });
120
+
121
+ if (!result) {
122
+ return null;
123
+ }
124
+
125
+ return {
126
+ ...result,
127
+ registry_path: this.getRegistryRelativePath()
128
+ };
129
+ }
130
+ }
131
+
132
+ module.exports = {
133
+ DEFAULT_REGISTRY_RELATIVE_PATH: DEFAULT_DB_RELATIVE_PATH,
134
+ TASK_REF_PATTERN,
135
+ parseTaskRef,
136
+ buildTaskRef,
137
+ formatSegment,
138
+ TaskRefRegistry
139
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scene-capability-engine",
3
- "version": "3.5.2",
3
+ "version": "3.6.2",
4
4
  "description": "SCE (Scene Capability Engine) - A CLI tool and npm package for spec-driven development with AI coding assistants.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -29,6 +29,7 @@
29
29
  "test:ci": "npx jest --config=jest.config.ci.js",
30
30
  "test:unit": "npx jest tests/unit",
31
31
  "test:integration": "npx jest tests/integration",
32
+ "test:release": "npm run test:integration -- --runInBand",
32
33
  "test:properties": "npx jest tests/properties",
33
34
  "test:orchestrator-429": "npx jest tests/orchestrator/orchestration-engine.test.js tests/orchestrator/orchestrate-command.status-events.test.js --runInBand",
34
35
  "test:handles": "npx jest --config=jest.config.js --runInBand --detectOpenHandles",
@@ -74,7 +75,7 @@
74
75
  "gate:release-asset-integrity": "node scripts/release-asset-integrity-check.js",
75
76
  "report:release-risk-remediation": "node scripts/release-risk-remediation-bundle.js --json",
76
77
  "report:moqui-core-regression": "node scripts/moqui-core-regression-suite.js --json",
77
- "prepublishOnly": "npm run test:full && npm run test:skip-audit && npm run test:sce-tracking && npm run test:brand-consistency && npm run gate:git-managed && npm run gate:errorbook-registry-health && npm run gate:errorbook-release && npm run report:interactive-governance -- --fail-on-alert",
78
+ "prepublishOnly": "npm run test:release && npm run test:skip-audit && npm run test:sce-tracking && npm run test:brand-consistency && npm run gate:git-managed && npm run gate:errorbook-registry-health && npm run gate:errorbook-release && npm run report:interactive-governance -- --fail-on-alert",
78
79
  "publish:manual": "npm publish --access public",
79
80
  "install-global": "npm install -g .",
80
81
  "uninstall-global": "npm uninstall -g scene-capability-engine"