@planu/cli 4.1.1 → 4.1.3

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/config/license-plans.json +65 -361
  3. package/dist/engine/core-bridge.js +35 -4
  4. package/dist/engine/hooks/file-watcher.d.ts +6 -0
  5. package/dist/engine/hooks/file-watcher.js +69 -16
  6. package/dist/tools/git/hook-ops.js +23 -9
  7. package/dist/tools/tool-registry/group-infra.js +22 -0
  8. package/package.json +7 -7
  9. package/dist/engine/escalator/index.d.ts +0 -5
  10. package/dist/engine/escalator/index.js +0 -5
  11. package/dist/engine/freeze/retro-audit.d.ts +0 -6
  12. package/dist/engine/freeze/retro-audit.js +0 -24
  13. package/dist/engine/heal/backup.d.ts +0 -9
  14. package/dist/engine/heal/backup.js +0 -21
  15. package/dist/engine/idioma-validator/index.d.ts +0 -17
  16. package/dist/engine/idioma-validator/index.js +0 -89
  17. package/dist/engine/saga/index.d.ts +0 -4
  18. package/dist/engine/saga/index.js +0 -4
  19. package/dist/engine/spec-state-machine/index.d.ts +0 -3
  20. package/dist/engine/spec-state-machine/index.js +0 -2
  21. package/dist/engine/spec-summary-html/dashboard-renderer.d.ts +0 -6
  22. package/dist/engine/spec-summary-html/dashboard-renderer.js +0 -333
  23. package/dist/engine/triagier/index.d.ts +0 -5
  24. package/dist/engine/triagier/index.js +0 -5
  25. package/dist/engine/universal-rules/index.d.ts +0 -5
  26. package/dist/engine/universal-rules/index.js +0 -6
  27. package/dist/testing/cassette/index.d.ts +0 -23
  28. package/dist/testing/cassette/index.js +0 -26
  29. package/dist/tools/domain-bundle-handler.d.ts +0 -37
  30. package/dist/tools/domain-bundle-handler.js +0 -71
  31. package/dist/tools/figma/rules-file.d.ts +0 -5
  32. package/dist/tools/figma/rules-file.js +0 -45
  33. package/dist/tools/heal-planu-root.d.ts +0 -8
  34. package/dist/tools/heal-planu-root.js +0 -144
  35. package/dist/tools/opencode-host-adapter.d.ts +0 -3
  36. package/dist/tools/opencode-host-adapter.js +0 -33
  37. package/dist/tools/plan-team-distribution.d.ts +0 -3
  38. package/dist/tools/plan-team-distribution.js +0 -71
  39. package/dist/tools/reconcile-status-json.d.ts +0 -4
  40. package/dist/tools/reconcile-status-json.js +0 -209
  41. package/dist/tools/register-all-tools.d.ts +0 -8
  42. package/dist/tools/register-all-tools.js +0 -239
  43. package/dist/tools/tool-registry/group-analysis-monitoring.d.ts +0 -3
  44. package/dist/tools/tool-registry/group-analysis-monitoring.js +0 -942
  45. package/dist/tools/tool-registry/group-integrations.d.ts +0 -3
  46. package/dist/tools/tool-registry/group-integrations.js +0 -1046
  47. package/dist/tools/tool-registry/group-misc.d.ts +0 -3
  48. package/dist/tools/tool-registry/group-misc.js +0 -1367
  49. package/dist/tools/tool-registry/group-platform.d.ts +0 -3
  50. package/dist/tools/tool-registry/group-platform.js +0 -1681
  51. package/dist/tools/tool-registry/group-session-knowledge.d.ts +0 -3
  52. package/dist/tools/tool-registry/group-session-knowledge.js +0 -1416
  53. package/dist/tools/tool-registry/group-spec-ops.d.ts +0 -3
  54. package/dist/tools/tool-registry/group-spec-ops.js +0 -917
  55. package/dist/tools/workspace-overview.d.ts +0 -4
  56. package/dist/tools/workspace-overview.js +0 -316
  57. package/dist/transports/middleware/index.d.ts +0 -9
  58. package/dist/transports/middleware/index.js +0 -7
  59. package/dist/transports/middleware/with-sandbox.d.ts +0 -21
  60. package/dist/transports/middleware/with-sandbox.js +0 -68
  61. package/dist/types/heal.d.ts +0 -18
  62. package/dist/types/heal.js +0 -3
@@ -1,6 +1,6 @@
1
1
  // engine/hooks/file-watcher.ts — File system watcher with normalized events (SPEC-129)
2
2
  import { EventEmitter } from 'node:events';
3
- import { watch } from 'node:fs';
3
+ import { readdirSync, watch } from 'node:fs';
4
4
  import { stat } from 'node:fs/promises';
5
5
  import { normalize, join } from 'node:path';
6
6
  // ---------------------------------------------------------------------------
@@ -73,15 +73,22 @@ export function matchesPatterns(filePath, include, exclude) {
73
73
  // Default excludes
74
74
  // ---------------------------------------------------------------------------
75
75
  const DEFAULT_EXCLUDES = ['data/**', 'node_modules/**', '.git/**'];
76
+ const DEFAULT_MAX_TS_WATCHERS = 128;
77
+ function maxTypeScriptWatchers() {
78
+ const raw = Number(process.env.PLANU_MAX_TS_WATCHERS ?? DEFAULT_MAX_TS_WATCHERS);
79
+ return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : DEFAULT_MAX_TS_WATCHERS;
80
+ }
76
81
  // ---------------------------------------------------------------------------
77
82
  // FileWatcher
78
83
  // ---------------------------------------------------------------------------
79
84
  import { isNativeActive, startNativeWatcher } from '../core-bridge.js';
80
85
  export class FileWatcher extends EventEmitter {
81
86
  watcher = null;
87
+ watchers = new Set();
82
88
  rootDir;
83
89
  include;
84
90
  exclude;
91
+ maxWatchers = maxTypeScriptWatchers();
85
92
  /** Track known files to distinguish create vs modify */
86
93
  knownFiles = new Set();
87
94
  closed = false;
@@ -112,21 +119,11 @@ export class FileWatcher extends EventEmitter {
112
119
  });
113
120
  }
114
121
  else {
115
- this.watcher = watch(this.rootDir, { recursive: true }, (_eventType, filename) => {
116
- if (!filename || this.closed) {
117
- return;
118
- }
119
- // Normalize path separator
120
- const relPath = filename.replace(/\\/g, '/');
121
- void this.handleFsEvent(relPath);
122
- });
123
- this.watcher.on('error', (err) => {
124
- this.emit('error', err);
125
- });
122
+ this.startTypeScriptWatcher();
126
123
  }
127
124
  }
128
125
  catch (err) {
129
- this.emit('error', err);
126
+ this.emitWatcherError(err);
130
127
  }
131
128
  }
132
129
  /**
@@ -148,15 +145,71 @@ export class FileWatcher extends EventEmitter {
148
145
  */
149
146
  close() {
150
147
  this.closed = true;
151
- if (this.watcher) {
152
- this.watcher.close();
153
- this.watcher = null;
148
+ for (const watcher of this.watchers) {
149
+ watcher.close();
154
150
  }
151
+ this.watchers.clear();
152
+ this.watcher = null;
155
153
  this.removeAllListeners();
156
154
  }
157
155
  // ---------------------------------------------------------------------------
158
156
  // Private
159
157
  // ---------------------------------------------------------------------------
158
+ startTypeScriptWatcher() {
159
+ this.watchDirectory(this.rootDir, '');
160
+ this.watchSubdirectories(this.rootDir, '');
161
+ }
162
+ watchDirectory(absDir, relDir) {
163
+ const watcher = watch(absDir, {}, (_eventType, filename) => {
164
+ if (!filename || this.closed) {
165
+ return;
166
+ }
167
+ const relPath = join(relDir, filename).replace(/\\/g, '/');
168
+ void this.handleFsEvent(relPath);
169
+ });
170
+ watcher.on('error', (err) => {
171
+ this.emitWatcherError(err);
172
+ });
173
+ this.watchers.add(watcher);
174
+ this.watcher ??= watcher;
175
+ }
176
+ watchSubdirectories(absDir, relDir) {
177
+ if (this.watchers.size >= this.maxWatchers) {
178
+ return;
179
+ }
180
+ let entries;
181
+ try {
182
+ entries = readdirSync(absDir, { withFileTypes: true });
183
+ }
184
+ catch {
185
+ return;
186
+ }
187
+ for (const entry of entries) {
188
+ if (!entry.isDirectory()) {
189
+ continue;
190
+ }
191
+ const childRel = join(relDir, entry.name).replace(/\\/g, '/');
192
+ if (this.exclude.some((p) => matchesGlobPattern(childRel, p))) {
193
+ continue;
194
+ }
195
+ const childAbs = join(absDir, entry.name);
196
+ try {
197
+ this.watchDirectory(childAbs, childRel);
198
+ }
199
+ catch {
200
+ continue;
201
+ }
202
+ if (this.watchers.size >= this.maxWatchers) {
203
+ return;
204
+ }
205
+ this.watchSubdirectories(childAbs, childRel);
206
+ }
207
+ }
208
+ emitWatcherError(err) {
209
+ if (this.listenerCount('error') > 0) {
210
+ this.emit('error', err);
211
+ }
212
+ }
160
213
  async handleFsEvent(relPath) {
161
214
  try {
162
215
  // Check exclude patterns first
@@ -219,19 +219,33 @@ function buildPostCommitDriftScript() {
219
219
  '[ -z "$CHANGED" ] && exit 0',
220
220
  '',
221
221
  '# Build JSON array of file paths',
222
- 'FILES_JSON=$(echo "$CHANGED" | awk \'',
223
- ' BEGIN { printf "[" }',
224
- ' NR > 1 { printf "," }',
225
- // eslint-disable-next-line no-useless-escape
226
- ' { gsub(/"/, "\\\\\""); printf "\\"%s\\"", $0 }',
227
- ' END { printf "]" }',
228
- "')",
222
+ 'FILES_JSON="["',
223
+ 'FIRST=1',
224
+ 'while IFS= read -r FILE_PATH; do',
225
+ ' ESCAPED=$(printf \'%s\' "$FILE_PATH" | sed \'s/\\\\/\\\\\\\\/g; s/"/\\\\"/g\')',
226
+ ' if [ "$FIRST" -eq 0 ]; then',
227
+ ' FILES_JSON="$FILES_JSON,"',
228
+ ' fi',
229
+ ' FILES_JSON="$FILES_JSON\\"$ESCAPED\\""',
230
+ ' FIRST=0',
231
+ 'done <<PLANU_CHANGED_FILES',
232
+ '$CHANGED',
233
+ 'PLANU_CHANGED_FILES',
234
+ 'FILES_JSON="$FILES_JSON]"',
229
235
  '',
230
236
  "TS=$(date -u '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date -u)",
231
237
  '',
232
238
  '# Check for drift-worthy files (dep manifests or uncommon extensions)',
233
- 'HAS_DEP=$(echo "$CHANGED" | grep -cE \'(^|/)(package\\.json|go\\.mod|requirements\\.txt|Cargo\\.toml|pom\\.xml|build\\.gradle|pyproject\\.toml|Gemfile|composer\\.json)$\' 2>/dev/null || echo 0)',
234
- "HAS_EXT=$(echo \"$CHANGED\" | grep -oE '\\.[a-zA-Z]+$' | grep -cvE '\\.(ts|tsx|js|jsx|mjs|cjs|json|md|mdx|sh|bash|txt|yaml|yml|toml|lock|sum|mod|py|go|rs|java|kt|rb|php|cs|dart|swift|html|css|scss|vue|svelte|env|sql|xml|csv)$' 2>/dev/null || echo 0)",
239
+ 'if echo "$CHANGED" | grep -qE \'(^|/)(package\\.json|go\\.mod|requirements\\.txt|Cargo\\.toml|pom\\.xml|build\\.gradle|pyproject\\.toml|Gemfile|composer\\.json)$\' 2>/dev/null; then',
240
+ ' HAS_DEP=1',
241
+ 'else',
242
+ ' HAS_DEP=0',
243
+ 'fi',
244
+ "if echo \"$CHANGED\" | grep -oE '\\.[a-zA-Z]+$' | grep -qvE '\\.(ts|tsx|js|jsx|mjs|cjs|json|md|mdx|sh|bash|txt|yaml|yml|toml|lock|sum|mod|py|go|rs|java|kt|rb|php|cs|dart|swift|html|css|scss|vue|svelte|env|sql|xml|csv)$' 2>/dev/null; then",
245
+ ' HAS_EXT=1',
246
+ 'else',
247
+ ' HAS_EXT=0',
248
+ 'fi',
235
249
  '',
236
250
  '# Only write if there is something worth processing',
237
251
  'if [ "$HAS_DEP" -gt 0 ] || [ "$HAS_EXT" -gt 0 ]; then',
@@ -14,6 +14,9 @@ import { safe, safeLicensed, safeTracked } from '../safe-handler.js';
14
14
  import { handleActivateLicense, handleDeactivateLicense } from '../activate-license.js';
15
15
  import { handleLicenseStatus } from '../license-status.js';
16
16
  import { LicenseStatusOutputSchema } from '../schemas/index.js';
17
+ // ── OAuth tools (register-oauth-tools.ts / register-configure-oauth-tool.ts) ─
18
+ import { handleStartOAuthFlow, handleOAuthStatus, StartOAuthFlowInputSchema, OAuthStatusInputSchema, } from '../oauth-handler.js';
19
+ import { handleConfigureOAuth } from '../configure-oauth-handler.js';
17
20
  // ── Usage tools (register-usage-tools.ts) ────────────────────────────────────
18
21
  import { handleUsageStats } from '../usage-stats.js';
19
22
  import { handleUsageReport } from '../usage-report.js';
@@ -126,6 +129,25 @@ export function registerInfraGroupTools(server) {
126
129
  outputSchema: LicenseStatusOutputSchema,
127
130
  annotations: { title: 'License Status', readOnlyHint: true },
128
131
  }, safe(async (args) => handleLicenseStatus(args)));
132
+ // ── OAuth tools ────────────────────────────────────────────────────────────
133
+ server.registerTool('start_oauth_flow', {
134
+ description: 'Start guided OAuth setup for supported integrations such as Figma, GitHub, Sentry, or Supabase.',
135
+ inputSchema: StartOAuthFlowInputSchema,
136
+ annotations: { title: 'Start OAuth Flow', readOnlyHint: false },
137
+ }, safeLicensed('start_oauth_flow', async (args) => handleStartOAuthFlow(args)));
138
+ server.registerTool('oauth_status', {
139
+ description: 'Show which OAuth-backed integrations are connected for this project.',
140
+ inputSchema: OAuthStatusInputSchema,
141
+ annotations: { title: 'OAuth Status', readOnlyHint: true },
142
+ }, safeLicensed('oauth_status', async (args) => handleOAuthStatus(args)));
143
+ server.registerTool('configure_oauth', {
144
+ description: 'Inspect Planu MCP OAuth/API-key auth status or test a bearer token without exposing secrets.',
145
+ inputSchema: {
146
+ action: z.enum(['status', 'test']).describe('Action: status | test'),
147
+ token: z.string().max(4096).optional().describe('Bearer token to test when action=test'),
148
+ },
149
+ annotations: { title: 'Configure OAuth', readOnlyHint: true },
150
+ }, safe(async (args) => handleConfigureOAuth(args)));
129
151
  // ── Usage tools ────────────────────────────────────────────────────────────
130
152
  server.registerTool('usage_stats', {
131
153
  description: 'View your Planu usage statistics — tool calls, top tools, remaining daily calls. ' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "4.1.1",
3
+ "version": "4.1.3",
4
4
  "description": "Planu — MCP Server for Spec Driven Development with native Rust acceleration for hot paths. Cross-platform (Linux/macOS/Windows, x64/arm64, glibc/musl).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,12 +32,12 @@
32
32
  "packageName": "@planu/core"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@planu/core-darwin-arm64": "4.1.1",
36
- "@planu/core-darwin-x64": "4.1.1",
37
- "@planu/core-linux-arm64-gnu": "4.1.1",
38
- "@planu/core-linux-arm64-musl": "4.1.1",
39
- "@planu/core-linux-x64-gnu": "4.1.1",
40
- "@planu/core-linux-x64-musl": "4.1.1"
35
+ "@planu/core-darwin-arm64": "4.1.3",
36
+ "@planu/core-darwin-x64": "4.1.3",
37
+ "@planu/core-linux-arm64-gnu": "4.1.3",
38
+ "@planu/core-linux-arm64-musl": "4.1.3",
39
+ "@planu/core-linux-x64-gnu": "4.1.3",
40
+ "@planu/core-linux-x64-musl": "4.1.3"
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=24.0.0"
@@ -1,5 +0,0 @@
1
- export { RETRY_BUDGETS, nextDecision } from './policy.js';
2
- export { incrementCounter, readCounter, resetCounter } from './retry-counter.js';
3
- export type { RetryKey } from './retry-counter.js';
4
- export { withEscalation } from './with-escalation.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +0,0 @@
1
- // engine/escalator/index.ts — SPEC-729: Public API re-exports
2
- export { RETRY_BUDGETS, nextDecision } from './policy.js';
3
- export { incrementCounter, readCounter, resetCounter } from './retry-counter.js';
4
- export { withEscalation } from './with-escalation.js';
5
- //# sourceMappingURL=index.js.map
@@ -1,6 +0,0 @@
1
- import type { RetroAuditInput } from '../../types/index.js';
2
- /**
3
- * Record a retro-audit event for a frozen spec edit.
4
- */
5
- export declare function recordRetroAudit(input: RetroAuditInput): Promise<void>;
6
- //# sourceMappingURL=retro-audit.d.ts.map
@@ -1,24 +0,0 @@
1
- // engine/freeze/retro-audit.ts — SPEC-747: Append retro_audit entries to transition log
2
- import { appendTransitionEvent } from '../../storage/transition-log.js';
3
- /**
4
- * Record a retro-audit event for a frozen spec edit.
5
- */
6
- export async function recordRetroAudit(input) {
7
- await appendTransitionEvent({
8
- projectId: input.projectId,
9
- specId: input.specId,
10
- eventType: 'retro_audit',
11
- from: 'done',
12
- to: 'done',
13
- actor: input.actor ?? 'system',
14
- reason: input.reason,
15
- sessionId: input.sessionId,
16
- modelId: input.modelId,
17
- meta: {
18
- specVersionBefore: input.versionBefore,
19
- specVersionAfter: input.versionAfter,
20
- forceEdit: input.forceEdit ?? false,
21
- },
22
- });
23
- }
24
- //# sourceMappingURL=retro-audit.js.map
@@ -1,9 +0,0 @@
1
- /**
2
- * Create a backup of `filePath` at `<filePath>.bak.<unix-ms>`.
3
- * Must be called BEFORE the atomic rename of the new content.
4
- *
5
- * @returns The backup file path.
6
- * @throws If the source file doesn't exist or the copy fails.
7
- */
8
- export declare function backupFile(filePath: string, timestampMs?: number): Promise<string>;
9
- //# sourceMappingURL=backup.d.ts.map
@@ -1,21 +0,0 @@
1
- // engine/heal/backup.ts — SPEC-745
2
- // Creates timestamped backup files before any tier-1 heal.
3
- import { copyFile } from 'node:fs/promises';
4
- import { existsSync } from 'node:fs';
5
- /**
6
- * Create a backup of `filePath` at `<filePath>.bak.<unix-ms>`.
7
- * Must be called BEFORE the atomic rename of the new content.
8
- *
9
- * @returns The backup file path.
10
- * @throws If the source file doesn't exist or the copy fails.
11
- */
12
- export async function backupFile(filePath, timestampMs) {
13
- const ts = timestampMs ?? Date.now();
14
- const backupPath = `${filePath}.bak.${ts}`;
15
- if (!existsSync(filePath)) {
16
- throw new Error(`Cannot backup non-existent file: ${filePath}`);
17
- }
18
- await copyFile(filePath, backupPath);
19
- return backupPath;
20
- }
21
- //# sourceMappingURL=backup.js.map
@@ -1,17 +0,0 @@
1
- export type IdiomaVerdict = 'es' | 'en' | 'mixed' | 'unknown' | 'abstain';
2
- export interface IdiomaResult {
3
- verdict: IdiomaVerdict;
4
- reason?: string;
5
- wordCount?: number;
6
- esScore?: number;
7
- enScore?: number;
8
- }
9
- /**
10
- * Detect the language of a spec's prose content.
11
- *
12
- * - Strips fenced code blocks before analysis.
13
- * - Abstains when prose word count is below 50 (SPEC-724: avoids noise on early drafts).
14
- * - Returns 'mixed' when both ES and EN markers exceed threshold.
15
- */
16
- export declare function detectIdioma(text: string): IdiomaResult;
17
- //# sourceMappingURL=index.d.ts.map
@@ -1,89 +0,0 @@
1
- // engine/idioma-validator/index.ts — SPEC-724: Spanish/English mixing detector for spec prose.
2
- // Skips fenced code blocks and abstains when prose word count is below 50 words.
3
- import { stripFencedBlocks } from '../spec-format/text-fences.js';
4
- const SPANISH_MARKERS = [
5
- 'de',
6
- 'del',
7
- 'la',
8
- 'el',
9
- 'en',
10
- 'con',
11
- 'para',
12
- 'por',
13
- 'una',
14
- 'los',
15
- 'las',
16
- 'al',
17
- 'se',
18
- 'que',
19
- 'es',
20
- 'son',
21
- 'fue',
22
- 'está',
23
- 'este',
24
- 'esta',
25
- 'estos',
26
- 'estas',
27
- 'un',
28
- 'unos',
29
- 'unas',
30
- ];
31
- const ENGLISH_MARKERS = [
32
- 'the',
33
- 'and',
34
- 'for',
35
- 'with',
36
- 'that',
37
- 'this',
38
- 'are',
39
- 'from',
40
- 'have',
41
- 'has',
42
- 'will',
43
- 'should',
44
- 'must',
45
- 'when',
46
- 'where',
47
- 'which',
48
- ];
49
- /**
50
- * Detect the language of a spec's prose content.
51
- *
52
- * - Strips fenced code blocks before analysis.
53
- * - Abstains when prose word count is below 50 (SPEC-724: avoids noise on early drafts).
54
- * - Returns 'mixed' when both ES and EN markers exceed threshold.
55
- */
56
- export function detectIdioma(text) {
57
- const prose = stripFencedBlocks(text);
58
- const words = prose.split(/\s+/).filter(Boolean);
59
- const wordCount = words.length;
60
- // SPEC-724: abstain on short prose stubs — not enough signal for reliable detection
61
- if (wordCount < 50) {
62
- return { verdict: 'abstain', reason: 'INSUFFICIENT_PROSE', wordCount };
63
- }
64
- const lower = prose.toLowerCase();
65
- const tokens = lower.split(/[\s\W]+/).filter((t) => t.length > 0);
66
- const totalTokens = tokens.length || 1;
67
- const esHits = tokens.filter((t) => SPANISH_MARKERS.includes(t)).length;
68
- const enHits = tokens.filter((t) => ENGLISH_MARKERS.includes(t)).length;
69
- const esScore = esHits / totalTokens;
70
- const enScore = enHits / totalTokens;
71
- const THRESHOLD = 0.03; // >3% hit rate = language present
72
- const hasEs = esScore > THRESHOLD;
73
- const hasEn = enScore > THRESHOLD;
74
- let verdict;
75
- if (hasEs && hasEn) {
76
- verdict = 'mixed';
77
- }
78
- else if (hasEs) {
79
- verdict = 'es';
80
- }
81
- else if (hasEn) {
82
- verdict = 'en';
83
- }
84
- else {
85
- verdict = 'unknown';
86
- }
87
- return { verdict, wordCount, esScore, enScore };
88
- }
89
- //# sourceMappingURL=index.js.map
@@ -1,4 +0,0 @@
1
- export { runSaga } from './cascade-saga.js';
2
- export { runTransitionCascadeSaga } from './transition-cascade.js';
3
- export type { TransitionCascadeCtx, TransitionCascadeResult } from '../../types/saga.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1,4 +0,0 @@
1
- // engine/saga/index.ts — SPEC-735: Saga barrel exports
2
- export { runSaga } from './cascade-saga.js';
3
- export { runTransitionCascadeSaga } from './transition-cascade.js';
4
- //# sourceMappingURL=index.js.map
@@ -1,3 +0,0 @@
1
- export type { TransitionTrigger, TransitionContext, TransitionRecord } from './transition-spec.js';
2
- export { transitionSpec } from './transition-spec.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +0,0 @@
1
- export { transitionSpec } from './transition-spec.js';
2
- //# sourceMappingURL=index.js.map
@@ -1,6 +0,0 @@
1
- import type { Spec } from '../../types/index.js';
2
- export declare function getInlineCss(): string;
3
- export declare function getInlineScript(): string;
4
- /** Generate the full dashboard HTML document. */
5
- export declare function generateDashboardHtml(specs: Spec[], availablePages?: string[]): string;
6
- //# sourceMappingURL=dashboard-renderer.d.ts.map