@portel/photon-core 2.17.6 → 2.18.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/dist/audit.d.ts +4 -0
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +107 -36
- package/dist/audit.js.map +1 -1
- package/dist/base.d.ts +81 -12
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +80 -7
- package/dist/base.js.map +1 -1
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +9 -1
- package/dist/compiler.js.map +1 -1
- package/dist/config.d.ts +14 -28
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +48 -46
- package/dist/config.js.map +1 -1
- package/dist/data-paths.d.ts +115 -0
- package/dist/data-paths.d.ts.map +1 -0
- package/dist/data-paths.js +243 -0
- package/dist/data-paths.js.map +1 -0
- package/dist/dependency-manager.d.ts +1 -1
- package/dist/dependency-manager.d.ts.map +1 -1
- package/dist/dependency-manager.js +13 -5
- package/dist/dependency-manager.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/instance-store.d.ts +22 -11
- package/dist/instance-store.d.ts.map +1 -1
- package/dist/instance-store.js +63 -28
- package/dist/instance-store.js.map +1 -1
- package/dist/memory.d.ts +8 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +49 -35
- package/dist/memory.js.map +1 -1
- package/dist/mixins.d.ts.map +1 -1
- package/dist/mixins.js +22 -3
- package/dist/mixins.js.map +1 -1
- package/dist/path-resolver.d.ts +3 -1
- package/dist/path-resolver.d.ts.map +1 -1
- package/dist/path-resolver.js +49 -2
- package/dist/path-resolver.js.map +1 -1
- package/dist/photon-loader-lite.d.ts +2 -0
- package/dist/photon-loader-lite.d.ts.map +1 -1
- package/dist/photon-loader-lite.js +3 -3
- package/dist/photon-loader-lite.js.map +1 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +11 -7
- package/dist/schedule.js.map +1 -1
- package/dist/schema-extractor.js +1 -1
- package/dist/schema-extractor.js.map +1 -1
- package/dist/stateful.d.ts +2 -1
- package/dist/stateful.d.ts.map +1 -1
- package/dist/stateful.js +4 -3
- package/dist/stateful.js.map +1 -1
- package/package.json +1 -1
- package/src/audit.ts +111 -38
- package/src/base.ts +117 -19
- package/src/compiler.ts +10 -1
- package/src/config.ts +59 -46
- package/src/data-paths.ts +289 -0
- package/src/dependency-manager.ts +13 -5
- package/src/index.ts +4 -0
- package/src/instance-store.ts +70 -30
- package/src/memory.ts +60 -38
- package/src/mixins.ts +24 -3
- package/src/path-resolver.ts +52 -2
- package/src/photon-loader-lite.ts +5 -3
- package/src/schedule.ts +11 -7
- package/src/schema-extractor.ts +1 -1
- package/src/stateful.ts +5 -2
package/src/memory.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* boilerplate file I/O. Available as `this.memory` on Photon.
|
|
6
6
|
*
|
|
7
7
|
* Three scopes:
|
|
8
|
-
* | Scope | Meaning | Storage
|
|
9
|
-
*
|
|
10
|
-
* | photon | Private to this photon (default) |
|
|
11
|
-
* | session | Per-user session (Beam sessions) |
|
|
12
|
-
* | global | Shared across all photons |
|
|
8
|
+
* | Scope | Meaning | Storage |
|
|
9
|
+
* |----------|----------------------------------|-----------------------------------------------|
|
|
10
|
+
* | photon | Private to this photon (default) | .data/{namespace}/{photonName}/memory/ |
|
|
11
|
+
* | session | Per-user session (Beam sessions) | .data/_sessions/{sessionId}/{ns}/{photon}/ |
|
|
12
|
+
* | global | Shared across all photons | .data/_global/ |
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```typescript
|
|
@@ -25,42 +25,60 @@
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import * as fs from 'fs/promises';
|
|
28
|
+
import * as fsSync from 'fs';
|
|
28
29
|
import * as path from 'path';
|
|
29
|
-
import * as os from 'os';
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
31
|
+
import {
|
|
32
|
+
getPhotonMemoryDir,
|
|
33
|
+
getGlobalMemoryDir,
|
|
34
|
+
getSessionMemoryDir,
|
|
35
|
+
getLegacyMemoryDir,
|
|
36
|
+
getLegacyGlobalMemoryDir,
|
|
37
|
+
getLegacySessionMemoryDir,
|
|
38
|
+
} from './data-paths.js';
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
* Get the sessions directory
|
|
42
|
-
*/
|
|
43
|
-
function getSessionsDir(): string {
|
|
44
|
-
return process.env.PHOTON_SESSIONS_DIR || path.join(os.homedir(), '.photon', 'sessions');
|
|
45
|
-
}
|
|
40
|
+
export type MemoryScope = 'photon' | 'session' | 'global';
|
|
46
41
|
|
|
47
42
|
/**
|
|
48
|
-
* Resolve storage directory for a given scope
|
|
43
|
+
* Resolve storage directory for a given scope.
|
|
44
|
+
* Uses new .data/ paths with fallback to legacy locations.
|
|
49
45
|
*/
|
|
50
|
-
function resolveDir(
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
function resolveDir(
|
|
47
|
+
photonId: string,
|
|
48
|
+
namespace: string,
|
|
49
|
+
scope: MemoryScope,
|
|
50
|
+
sessionId?: string,
|
|
51
|
+
baseDir?: string
|
|
52
|
+
): string {
|
|
53
53
|
switch (scope) {
|
|
54
|
-
case 'photon':
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
case 'photon': {
|
|
55
|
+
const newDir = getPhotonMemoryDir(namespace, photonId, baseDir);
|
|
56
|
+
// Fallback: check legacy path if new path has no data yet
|
|
57
|
+
if (!fsSync.existsSync(newDir)) {
|
|
58
|
+
const legacyDir = getLegacyMemoryDir(photonId, baseDir);
|
|
59
|
+
if (fsSync.existsSync(legacyDir)) return legacyDir;
|
|
60
|
+
}
|
|
61
|
+
return newDir;
|
|
62
|
+
}
|
|
63
|
+
case 'session': {
|
|
57
64
|
if (!sessionId) {
|
|
58
65
|
throw new Error('Session ID required for session-scoped memory. Set via memory.sessionId.');
|
|
59
66
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
const newDir = getSessionMemoryDir(sessionId, namespace, photonId, baseDir);
|
|
68
|
+
if (!fsSync.existsSync(newDir)) {
|
|
69
|
+
const legacyDir = getLegacySessionMemoryDir(sessionId, photonId, baseDir);
|
|
70
|
+
if (fsSync.existsSync(legacyDir)) return legacyDir;
|
|
71
|
+
}
|
|
72
|
+
return newDir;
|
|
73
|
+
}
|
|
74
|
+
case 'global': {
|
|
75
|
+
const newDir = getGlobalMemoryDir(baseDir);
|
|
76
|
+
if (!fsSync.existsSync(newDir)) {
|
|
77
|
+
const legacyDir = getLegacyGlobalMemoryDir(baseDir);
|
|
78
|
+
if (fsSync.existsSync(legacyDir)) return legacyDir;
|
|
79
|
+
}
|
|
80
|
+
return newDir;
|
|
81
|
+
}
|
|
64
82
|
default:
|
|
65
83
|
throw new Error(`Unknown memory scope: ${scope}`);
|
|
66
84
|
}
|
|
@@ -94,11 +112,15 @@ async function pathExists(p: string): Promise<boolean> {
|
|
|
94
112
|
*/
|
|
95
113
|
export class MemoryProvider {
|
|
96
114
|
private _photonId: string;
|
|
115
|
+
private _namespace: string;
|
|
97
116
|
private _sessionId?: string;
|
|
117
|
+
private _baseDir?: string;
|
|
98
118
|
|
|
99
|
-
constructor(photonId: string, sessionId?: string) {
|
|
119
|
+
constructor(photonId: string, sessionId?: string, namespace?: string, baseDir?: string) {
|
|
100
120
|
this._photonId = photonId;
|
|
121
|
+
this._namespace = namespace || 'local';
|
|
101
122
|
this._sessionId = sessionId;
|
|
123
|
+
this._baseDir = baseDir;
|
|
102
124
|
}
|
|
103
125
|
|
|
104
126
|
/**
|
|
@@ -120,7 +142,7 @@ export class MemoryProvider {
|
|
|
120
142
|
* @returns The stored value, or null if not found
|
|
121
143
|
*/
|
|
122
144
|
async get<T = any>(key: string, scope: MemoryScope = 'photon'): Promise<T | null> {
|
|
123
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
145
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
124
146
|
const filePath = keyPath(dir, key);
|
|
125
147
|
|
|
126
148
|
try {
|
|
@@ -140,7 +162,7 @@ export class MemoryProvider {
|
|
|
140
162
|
* @param scope Storage scope (default: 'photon')
|
|
141
163
|
*/
|
|
142
164
|
async set<T = any>(key: string, value: T, scope: MemoryScope = 'photon'): Promise<void> {
|
|
143
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
165
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
144
166
|
|
|
145
167
|
if (!await pathExists(dir)) {
|
|
146
168
|
await fs.mkdir(dir, { recursive: true });
|
|
@@ -158,7 +180,7 @@ export class MemoryProvider {
|
|
|
158
180
|
* @returns true if the key existed and was deleted
|
|
159
181
|
*/
|
|
160
182
|
async delete(key: string, scope: MemoryScope = 'photon'): Promise<boolean> {
|
|
161
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
183
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
162
184
|
const filePath = keyPath(dir, key);
|
|
163
185
|
|
|
164
186
|
try {
|
|
@@ -177,7 +199,7 @@ export class MemoryProvider {
|
|
|
177
199
|
* @param scope Storage scope (default: 'photon')
|
|
178
200
|
*/
|
|
179
201
|
async has(key: string, scope: MemoryScope = 'photon'): Promise<boolean> {
|
|
180
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
202
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
181
203
|
return pathExists(keyPath(dir, key));
|
|
182
204
|
}
|
|
183
205
|
|
|
@@ -187,7 +209,7 @@ export class MemoryProvider {
|
|
|
187
209
|
* @param scope Storage scope (default: 'photon')
|
|
188
210
|
*/
|
|
189
211
|
async keys(scope: MemoryScope = 'photon'): Promise<string[]> {
|
|
190
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
212
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
191
213
|
|
|
192
214
|
try {
|
|
193
215
|
const files = await fs.readdir(dir);
|
|
@@ -206,7 +228,7 @@ export class MemoryProvider {
|
|
|
206
228
|
* @param scope Storage scope (default: 'photon')
|
|
207
229
|
*/
|
|
208
230
|
async clear(scope: MemoryScope = 'photon'): Promise<void> {
|
|
209
|
-
const dir = resolveDir(this._photonId, scope, this._sessionId);
|
|
231
|
+
const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
|
|
210
232
|
|
|
211
233
|
try {
|
|
212
234
|
const files = await fs.readdir(dir);
|
package/src/mixins.ts
CHANGED
|
@@ -57,6 +57,7 @@ export function withPhotonCapabilities<T extends Constructor>(Base: T): T {
|
|
|
57
57
|
* @internal
|
|
58
58
|
*/
|
|
59
59
|
_photonName?: string;
|
|
60
|
+
_photonNamespace?: string;
|
|
60
61
|
|
|
61
62
|
/**
|
|
62
63
|
* Session ID for session-scoped memory - set by runtime
|
|
@@ -112,7 +113,7 @@ export function withPhotonCapabilities<T extends Constructor>(Base: T): T {
|
|
|
112
113
|
.replace(/([A-Z])/g, '-$1')
|
|
113
114
|
.toLowerCase()
|
|
114
115
|
.replace(/^-/, '');
|
|
115
|
-
this._memory = new MemoryProvider(name, this._sessionId);
|
|
116
|
+
this._memory = new MemoryProvider(name, this._sessionId, this._photonNamespace);
|
|
116
117
|
}
|
|
117
118
|
return this._memory;
|
|
118
119
|
}
|
|
@@ -134,14 +135,34 @@ export function withPhotonCapabilities<T extends Constructor>(Base: T): T {
|
|
|
134
135
|
|
|
135
136
|
/**
|
|
136
137
|
* Render a formatted value as an intermediate result.
|
|
138
|
+
* Supports UI feedback formats (status, progress, toast) and data formats (table, qr, etc.).
|
|
137
139
|
* Each call replaces the previous render. Call with no args to clear.
|
|
138
140
|
*/
|
|
139
141
|
protected render(format?: string, value?: any): void {
|
|
140
142
|
if (format === undefined) {
|
|
141
143
|
this.emit({ emit: 'render:clear' });
|
|
142
|
-
|
|
143
|
-
this.emit({ emit: 'render', format, value });
|
|
144
|
+
return;
|
|
144
145
|
}
|
|
146
|
+
switch (format) {
|
|
147
|
+
case 'status':
|
|
148
|
+
this.emit(typeof value === 'string' ? { emit: 'status', message: value } : { emit: 'status', ...value });
|
|
149
|
+
return;
|
|
150
|
+
case 'progress':
|
|
151
|
+
this.emit(typeof value === 'number' ? { emit: 'progress', value } : { emit: 'progress', ...value });
|
|
152
|
+
return;
|
|
153
|
+
case 'toast':
|
|
154
|
+
this.emit(typeof value === 'string' ? { emit: 'toast', message: value } : { emit: 'toast', ...value });
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.emit({ emit: 'render', format, value });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Create a blocking input request for use in generator methods.
|
|
162
|
+
* Returns a yield object: `const name = yield this.ask('text', 'Name?');`
|
|
163
|
+
*/
|
|
164
|
+
protected ask(type: string, message: string, options?: Record<string, any>): { ask: string; message: string; [key: string]: any } {
|
|
165
|
+
return { ask: type, message, ...options };
|
|
145
166
|
}
|
|
146
167
|
|
|
147
168
|
/**
|
package/src/path-resolver.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import * as fs from 'fs/promises';
|
|
17
|
+
import * as fsSync from 'fs';
|
|
17
18
|
import * as path from 'path';
|
|
18
19
|
import * as os from 'os';
|
|
19
20
|
|
|
@@ -47,7 +48,8 @@ const defaultOptions: Required<ResolverOptions> = {
|
|
|
47
48
|
|
|
48
49
|
/** Directories to skip when scanning for namespace subdirectories */
|
|
49
50
|
const SKIP_DIRS = new Set([
|
|
50
|
-
'
|
|
51
|
+
'.data', '.cache', '.config',
|
|
52
|
+
'state', 'context', 'env', // legacy data dirs (pre-.data/ consolidation)
|
|
51
53
|
'node_modules', 'marketplace', 'photons', 'templates',
|
|
52
54
|
]);
|
|
53
55
|
|
|
@@ -243,12 +245,60 @@ export async function listFilesWithNamespace(
|
|
|
243
245
|
return results;
|
|
244
246
|
}
|
|
245
247
|
|
|
248
|
+
/** Runtime data patterns that should never be committed to a marketplace repo */
|
|
249
|
+
const GITIGNORE_DATA_PATTERNS = [
|
|
250
|
+
'# Photon runtime data (auto-generated)',
|
|
251
|
+
'.data/',
|
|
252
|
+
];
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Check if a directory is inside a git repository
|
|
256
|
+
*/
|
|
257
|
+
function isGitRepo(dir: string): boolean {
|
|
258
|
+
let current = dir;
|
|
259
|
+
while (true) {
|
|
260
|
+
if (fsSync.existsSync(path.join(current, '.git'))) return true;
|
|
261
|
+
const parent = path.dirname(current);
|
|
262
|
+
if (parent === current) return false;
|
|
263
|
+
current = parent;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Ensure .gitignore in a git-tracked photon dir excludes runtime data.
|
|
269
|
+
* Only adds missing patterns — never removes or overwrites existing entries.
|
|
270
|
+
*/
|
|
271
|
+
async function ensureGitignore(dir: string): Promise<void> {
|
|
272
|
+
const gitignorePath = path.join(dir, '.gitignore');
|
|
273
|
+
let existing = '';
|
|
274
|
+
try {
|
|
275
|
+
existing = await fs.readFile(gitignorePath, 'utf-8');
|
|
276
|
+
} catch {
|
|
277
|
+
// No .gitignore yet
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const existingLines = new Set(existing.split('\n').map((l) => l.trim()));
|
|
281
|
+
const missing = GITIGNORE_DATA_PATTERNS.filter((p) => !existingLines.has(p));
|
|
282
|
+
|
|
283
|
+
if (missing.length === 0) return;
|
|
284
|
+
|
|
285
|
+
const append = (existing && !existing.endsWith('\n') ? '\n' : '') + missing.join('\n') + '\n';
|
|
286
|
+
await fs.appendFile(gitignorePath, append);
|
|
287
|
+
}
|
|
288
|
+
|
|
246
289
|
/**
|
|
247
|
-
* Ensure directory exists
|
|
290
|
+
* Ensure directory exists.
|
|
291
|
+
* If the directory is inside a git repo (e.g., a marketplace repo),
|
|
292
|
+
* auto-generates .gitignore entries for runtime data directories.
|
|
248
293
|
*/
|
|
249
294
|
export async function ensureDir(dir?: string): Promise<void> {
|
|
250
295
|
const targetDir = expandTilde(dir || DEFAULT_PHOTON_DIR);
|
|
251
296
|
await fs.mkdir(targetDir, { recursive: true });
|
|
297
|
+
|
|
298
|
+
// Auto-exclude runtime data when developing in a git-tracked marketplace repo
|
|
299
|
+
if (targetDir !== DEFAULT_PHOTON_DIR && isGitRepo(targetDir)) {
|
|
300
|
+
await ensureGitignore(targetDir);
|
|
301
|
+
}
|
|
252
302
|
}
|
|
253
303
|
|
|
254
304
|
// Convenience aliases for photon-specific usage
|
|
@@ -38,6 +38,7 @@ import { ScheduleProvider } from './schedule.js';
|
|
|
38
38
|
import { toEnvVarName, parseEnvValue, type MissingParamInfo } from './env-utils.js';
|
|
39
39
|
import type { ExtractedSchema } from './types.js';
|
|
40
40
|
import type { MCPClientFactory } from '@portel/mcp';
|
|
41
|
+
import { getCacheDir } from './data-paths.js';
|
|
41
42
|
|
|
42
43
|
// ═══════════════════════════════════════════════════════════════════
|
|
43
44
|
// Types
|
|
@@ -54,6 +55,8 @@ export interface PhotonOptions {
|
|
|
54
55
|
onEvent?: (event: PhotonEvent) => void;
|
|
55
56
|
/** Session ID for session-scoped memory */
|
|
56
57
|
sessionId?: string;
|
|
58
|
+
/** Namespace for data path resolution (marketplace owner). Defaults to 'local'. */
|
|
59
|
+
namespace?: string;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
export interface PhotonEvent {
|
|
@@ -154,9 +157,7 @@ async function loadPhotonInternal(
|
|
|
154
157
|
const source = await fs.readFile(absolutePath, 'utf-8');
|
|
155
158
|
|
|
156
159
|
// 2. Compile TypeScript → JavaScript
|
|
157
|
-
const
|
|
158
|
-
const cacheDir = path.join(homeDir, '.photon', 'cache');
|
|
159
|
-
const compiledPath = await compilePhotonTS(absolutePath, { cacheDir });
|
|
160
|
+
const compiledPath = await compilePhotonTS(absolutePath, { cacheDir: getCacheDir() });
|
|
160
161
|
|
|
161
162
|
// 3. Import compiled module
|
|
162
163
|
const moduleUrl = pathToFileURL(compiledPath).href;
|
|
@@ -193,6 +194,7 @@ async function loadPhotonInternal(
|
|
|
193
194
|
|
|
194
195
|
// 10. Set photon identity
|
|
195
196
|
instance._photonName = photonName;
|
|
197
|
+
instance._photonNamespace = options.namespace || 'local';
|
|
196
198
|
if (options.instanceName) {
|
|
197
199
|
instance.instanceName = options.instanceName;
|
|
198
200
|
}
|
package/src/schedule.ts
CHANGED
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
import * as fs from 'fs/promises';
|
|
32
32
|
import * as path from 'path';
|
|
33
33
|
import * as os from 'os';
|
|
34
|
+
import * as fsSync from 'fs';
|
|
35
|
+
|
|
36
|
+
import { getPhotonSchedulesDir, getLegacySchedulesDir } from './data-paths.js';
|
|
34
37
|
import { randomUUID } from 'crypto';
|
|
35
38
|
|
|
36
39
|
// ── Types ──────────────────────────────────────────────────────────────
|
|
@@ -136,13 +139,14 @@ function resolveCron(schedule: string): string {
|
|
|
136
139
|
|
|
137
140
|
// ── Storage Helpers ────────────────────────────────────────────────────
|
|
138
141
|
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
function photonScheduleDir(photonId: string, namespace?: string): string {
|
|
143
|
+
const ns = namespace || 'local';
|
|
144
|
+
const newDir = getPhotonSchedulesDir(ns, photonId);
|
|
145
|
+
if (!fsSync.existsSync(newDir)) {
|
|
146
|
+
const legacyDir = getLegacySchedulesDir(photonId);
|
|
147
|
+
if (fsSync.existsSync(legacyDir)) return legacyDir;
|
|
148
|
+
}
|
|
149
|
+
return newDir;
|
|
146
150
|
}
|
|
147
151
|
|
|
148
152
|
function taskPath(photonId: string, taskId: string): string {
|
package/src/schema-extractor.ts
CHANGED
|
@@ -2365,7 +2365,7 @@ export class SchemaExtractor {
|
|
|
2365
2365
|
if (['metric', 'gauge', 'progress', 'badge', 'timeline', 'dashboard', 'cart', 'qr', 'slides',
|
|
2366
2366
|
'steps', 'stepper', 'log', 'image', 'hero', 'banner', 'quote', 'profile', 'heatmap',
|
|
2367
2367
|
'kanban', 'calendar', 'map', 'cron', 'comparison', 'invoice', 'receipt', 'network', 'graph',
|
|
2368
|
-
'checklist', 'article', 'magazine'].includes(format)) {
|
|
2368
|
+
'checklist', 'article', 'magazine', 'guide'].includes(format)) {
|
|
2369
2369
|
return format as OutputFormat;
|
|
2370
2370
|
}
|
|
2371
2371
|
|
package/src/stateful.ts
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
import * as fs from 'fs/promises';
|
|
55
55
|
import * as path from 'path';
|
|
56
56
|
import * as os from 'os';
|
|
57
|
+
|
|
58
|
+
import { getPhotonRunsDir, getLegacyRunsDir } from './data-paths.js';
|
|
57
59
|
import { createReadStream } from 'fs';
|
|
58
60
|
import { createInterface } from 'readline';
|
|
59
61
|
import { executionContext } from '@portel/cli';
|
|
@@ -85,9 +87,10 @@ import {
|
|
|
85
87
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
86
88
|
|
|
87
89
|
/**
|
|
88
|
-
* Default runs directory (~/.photon/runs)
|
|
90
|
+
* Default runs directory (legacy: ~/.photon/runs)
|
|
91
|
+
* @deprecated Use getPhotonRunsDir(namespace, photonName) from data-paths.ts
|
|
89
92
|
*/
|
|
90
|
-
export const RUNS_DIR =
|
|
93
|
+
export const RUNS_DIR = getLegacyRunsDir();
|
|
91
94
|
|
|
92
95
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
93
96
|
// CHECKPOINT YIELD TYPE
|