@pikku/inspector 0.12.107 → 0.12.109

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.
@@ -363,6 +363,11 @@ function processCommand(logger, inspectorState, options, name, node, sourceFile,
363
363
  meta.isDefault = prop.initializer.kind === ts.SyntaxKind.TrueKeyword;
364
364
  }
365
365
  break;
366
+ case 'hidden':
367
+ if (prop.initializer.kind === ts.SyntaxKind.TrueKeyword) {
368
+ meta.hidden = true;
369
+ }
370
+ break;
366
371
  }
367
372
  }
368
373
  // --- validate auth/sessionless ---
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { inspect, analyzeProgram } from './inspector.js';
2
2
  export { getInitialInspectorState } from './initial-state.js';
3
3
  export { finalizeInspectorState } from './finalize.js';
4
4
  export type { TypesMap } from './types-map.js';
5
- export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, ScreensManifestMeta, AddonScreenMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorServiceTypes, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
5
+ export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, ScreensManifestMeta, AddonScreenMeta, AddonContributorRef, AddonContributorsMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorServiceTypes, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
6
6
  export type { FilesAndMethodsErrors } from './utils/get-files-and-methods.js';
7
7
  export { ErrorCode } from './error-codes.js';
8
8
  export type { DiagnosticSeverity, CodedDiagnostic } from './error-codes.js';
package/dist/types.d.ts CHANGED
@@ -544,11 +544,26 @@ export interface InspectorServiceTypes {
544
544
  /** Singleton services that are a `SecretService` under another name. */
545
545
  secretAliases: string[];
546
546
  }
547
+ export interface AddonContributorRef {
548
+ module: string;
549
+ export?: string;
550
+ }
551
+ export interface AddonContributorsMeta {
552
+ packageName: string;
553
+ packageDir: string;
554
+ contributors: AddonContributorRef[];
555
+ }
547
556
  export interface InspectorState {
548
557
  /** Set when this package calls `defineScreens`: the screens it ships. */
549
558
  screensManifest?: ScreensManifestMeta;
550
559
  /** The screens of the addons this project wires with `ui: true`, by namespace. */
551
560
  addonScreens?: Record<string, ScreensManifestMeta>;
561
+ /**
562
+ * Platform service contributors each wired, non-remote addon declares in its
563
+ * `package.json` under `pikku.contributors`, by namespace. `module` resolves
564
+ * from `packageDir`.
565
+ */
566
+ addonContributors?: Record<string, AddonContributorsMeta>;
552
567
  rootDir: string;
553
568
  singletonServicesTypeImportMap: PathToNameAndType;
554
569
  wireServicesTypeImportMap: PathToNameAndType;
@@ -1,4 +1,4 @@
1
- import type { InspectorState, InspectorLogger } from '../types.js';
1
+ import type { AddonContributorsMeta, InspectorState, InspectorLogger } from '../types.js';
2
2
  import type { WebhookSourcesMeta } from '@pikku/core/trigger';
3
3
  export declare const describeMissingAddonMeta: (namespace: string, packageName: string, dirs: string[], declFile?: string) => string;
4
4
  /**
@@ -8,6 +8,13 @@ export declare const describeMissingAddonMeta: (namespace: string, packageName:
8
8
  * Every source starts off: the app turns one on at runtime.
9
9
  */
10
10
  export declare const namespaceAddonWebhookSources: (sources: WebhookSourcesMeta, namespace: string) => WebhookSourcesMeta;
11
+ /**
12
+ * The platform service contributors an addon declares in its package.json,
13
+ * `"pikku": { "contributors": [{ "module", "export" }] }` — the same shape as
14
+ * `dev.contributors`. `wireAddon` has no place for them: a contributor emits
15
+ * code into the host's entry, so it belongs to the package, not the wiring.
16
+ */
17
+ export declare const readAddonContributors: (dirs: string[], packageName: string) => Promise<AddonContributorsMeta | null>;
11
18
  export declare function loadAddonFunctionsMeta(logger: InspectorLogger, state: InspectorState): Promise<void>;
12
19
  /**
13
20
  * Load addon schemas into state.schemas. Called after generateAllSchemas
@@ -203,6 +203,42 @@ const readAddonNeeds = async (dirs, packageName) => {
203
203
  return [];
204
204
  }
205
205
  };
206
+ const isContributorRef = (value) => !!value &&
207
+ typeof value === 'object' &&
208
+ typeof value.module === 'string' &&
209
+ (value.export === undefined ||
210
+ typeof value.export === 'string');
211
+ /**
212
+ * The platform service contributors an addon declares in its package.json,
213
+ * `"pikku": { "contributors": [{ "module", "export" }] }` — the same shape as
214
+ * `dev.contributors`. `wireAddon` has no place for them: a contributor emits
215
+ * code into the host's entry, so it belongs to the package, not the wiring.
216
+ */
217
+ export const readAddonContributors = async (dirs, packageName) => {
218
+ const packageDir = findInstalledPackageDir(dirs, packageName);
219
+ if (!packageDir)
220
+ return null;
221
+ let declared;
222
+ try {
223
+ const pkg = JSON.parse(await readFile(join(packageDir, 'package.json'), 'utf-8'));
224
+ declared = pkg?.pikku?.contributors;
225
+ }
226
+ catch {
227
+ return null;
228
+ }
229
+ if (declared === undefined)
230
+ return null;
231
+ if (!Array.isArray(declared) || !declared.every(isContributorRef)) {
232
+ throw new Error(`${packageName} declares pikku.contributors in its package.json, but it is not a list of { module, export? }.`);
233
+ }
234
+ if (declared.length === 0)
235
+ return null;
236
+ return {
237
+ packageName,
238
+ packageDir,
239
+ contributors: declared.map(({ module, export: name }) => name === undefined ? { module } : { module, export: name }),
240
+ };
241
+ };
206
242
  export async function loadAddonFunctionsMeta(logger, state) {
207
243
  const { wireAddonDeclarations } = state.rpc;
208
244
  if (wireAddonDeclarations.size === 0)
@@ -216,6 +252,16 @@ export async function loadAddonFunctionsMeta(logger, state) {
216
252
  const dirs = addonResolutionDirs(state.rootDir, decl.file);
217
253
  const require = createAddonResolver(dirs);
218
254
  try {
255
+ try {
256
+ const contributors = await readAddonContributors(dirs, decl.package);
257
+ if (contributors) {
258
+ ;
259
+ (state.addonContributors ??= {})[namespace] = contributors;
260
+ }
261
+ }
262
+ catch (error) {
263
+ logger.error(`wireAddon('${namespace}'): ${error instanceof Error ? error.message : error}`);
264
+ }
219
265
  for (const needed of await readAddonNeeds(dirs, decl.package)) {
220
266
  if (!decl.uses?.[needed]) {
221
267
  logger.critical(ErrorCode.ADDON_NEEDS_NOT_MAPPED, `${decl.package} needs ${needed}, but wireAddon('${namespace}') does not map it. Wire ${needed} and add uses: { '${needed}': '<name>' } to this wireAddon.`);
@@ -42,6 +42,34 @@ const NON_TEXT_ATTRIBUTES = new Set([
42
42
  'value',
43
43
  'key',
44
44
  ]);
45
+ /**
46
+ * Calls whose string arguments are class lists. A literal anywhere inside one —
47
+ * `cva('…', { variants: { size: { heading: 'font-heading text-xl' } } })` — is
48
+ * styling, even under a key like `heading` that would otherwise read as text.
49
+ */
50
+ const CLASS_BUILDERS = new Set([
51
+ 'cn',
52
+ 'cva',
53
+ 'clsx',
54
+ 'cx',
55
+ 'classNames',
56
+ 'classnames',
57
+ 'tv',
58
+ 'twMerge',
59
+ 'twJoin',
60
+ ]);
61
+ const isInsideClassBuilder = (node) => {
62
+ for (let at = node.parent; at; at = at.parent) {
63
+ if (ts.isJsxElement(at) || ts.isJsxSelfClosingElement(at))
64
+ return false;
65
+ if (ts.isCallExpression(at) &&
66
+ ts.isIdentifier(at.expression) &&
67
+ CLASS_BUILDERS.has(at.expression.text)) {
68
+ return true;
69
+ }
70
+ }
71
+ return false;
72
+ };
45
73
  const isProse = (text) => /^\p{Lu}[^\s]*(\s+[^\s]+)+/u.test(text.trim()) &&
46
74
  !/[:/[\]=_#]/.test(text.split(/\s+/)[0] ?? '');
47
75
  const isSentence = (text) => /\p{L}+\s+\p{L}+/u.test(text);
@@ -72,7 +100,9 @@ export const readJsxLiteralText = (fileName, content) => {
72
100
  const found = [];
73
101
  const seen = new Set();
74
102
  const add = (node, text) => {
75
- if (!hasLetter(text) || seen.has(node.getStart(source)))
103
+ if (!hasLetter(text) ||
104
+ seen.has(node.getStart(source)) ||
105
+ isInsideClassBuilder(node))
76
106
  return;
77
107
  seen.add(node.getStart(source));
78
108
  const { line } = source.getLineAndCharacterOfPosition(node.getStart(source));
@@ -328,6 +328,7 @@ export interface SerializableInspectorState {
328
328
  addonFunctions: InspectorState['addonFunctions'];
329
329
  screensManifest?: InspectorState['screensManifest'];
330
330
  addonScreens?: InspectorState['addonScreens'];
331
+ addonContributors?: InspectorState['addonContributors'];
331
332
  exportedContracts: InspectorState['exportedContracts'];
332
333
  }
333
334
  /**
@@ -192,6 +192,7 @@ export function serializeInspectorState(state) {
192
192
  addonFunctions: state.addonFunctions,
193
193
  screensManifest: state.screensManifest,
194
194
  addonScreens: state.addonScreens,
195
+ addonContributors: state.addonContributors,
195
196
  exportedContracts: state.exportedContracts,
196
197
  };
197
198
  }
@@ -397,6 +398,7 @@ export function deserializeInspectorState(data) {
397
398
  addonFunctions: data.addonFunctions || {},
398
399
  screensManifest: data.screensManifest,
399
400
  addonScreens: data.addonScreens,
401
+ addonContributors: data.addonContributors,
400
402
  exportedContracts: data.exportedContracts || {
401
403
  http: {},
402
404
  cli: {},
@@ -413,6 +413,7 @@ export function convertDslToGraph(workflowName, meta) {
413
413
  name: workflowName,
414
414
  pikkuFuncId: meta.pikkuFuncId,
415
415
  source,
416
+ scenario: meta.scenario || undefined,
416
417
  title: meta.title,
417
418
  description: meta.description,
418
419
  tags: meta.tags,
@@ -156,6 +156,8 @@ export interface SerializedWorkflowGraph {
156
156
  pikkuFuncId: string;
157
157
  /** Source type: 'dsl' for pikkuWorkflowFunc, 'graph' for pikkuWorkflowGraph */
158
158
  source: WorkflowSourceType;
159
+ /** True for a scenario, so meta readers can tell it from a real workflow */
160
+ scenario?: boolean;
159
161
  /** Optional short display name */
160
162
  title?: string;
161
163
  /** Optional description */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/inspector",
3
- "version": "0.12.107",
3
+ "version": "0.12.109",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/pikkujs/pikku.git",
@@ -70,10 +70,10 @@
70
70
  "zod": "^4.6.7"
71
71
  },
72
72
  "peerDependencies": {
73
- "@pikku/core": "^0.12.144"
73
+ "@pikku/core": "^0.12.145"
74
74
  },
75
75
  "devDependencies": {
76
- "@pikku/core": "^0.12.144",
76
+ "@pikku/core": "^0.12.145",
77
77
  "@types/node": "^26.6.5"
78
78
  },
79
79
  "engines": {