@danxbot/plugin-sdk 0.1.6 → 0.2.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.
@@ -8,7 +8,7 @@ declare module "@danxbot/card-kit@1" {
8
8
 
9
9
  type IssueStatus$1 = "Review" | "ToDo" | "In Progress" | "Backlog" | "Done" | "Cancelled";
10
10
  type EffortLevelName = "min" | "very_low" | "low" | "medium" | "high" | "very_high" | "max";
11
- type IssueProblemType = "question" | "action";
11
+ type IssueAuthoredProblemType = "question" | "action";
12
12
  type DecisionOutcome = "answered" | "rejected";
13
13
  type IssueDependencyKind = "depends_on" | "conflict_on";
14
14
  type IssueDispatchKind = "work" | "triage" | "recovery" | "flesh-out" | "chat" | "main-sync-repair" | "worktree-maintenance" | "manual" | `gate-${string}`;
@@ -381,7 +381,7 @@ declare module "@danxbot/card-kit@1" {
381
381
  interface V2CopyProblem {
382
382
  statement: string;
383
383
  context: string | null;
384
- type: IssueProblemType;
384
+ type: IssueAuthoredProblemType;
385
385
  summary: string | null;
386
386
  removed: boolean;
387
387
  solutions: V2CopySolution[];
@@ -799,42 +799,14 @@ declare module "@danxbot/card-kit@1" {
799
799
  phase: "plan" | "code";
800
800
  };
801
801
  type ProblemViewV2 = {
802
- id: number;
803
- issue_id: string;
802
+ type: "question" | "action" | "design";
803
+ open: boolean;
804
804
  ordinal: number;
805
- statement: string;
806
- context: null | string;
807
- type: "question" | "action";
808
- summary: null | string;
809
- content_hash: string;
805
+ id: number;
810
806
  created_at: string;
811
807
  updated_at: string;
812
- feedback_consent: boolean;
813
- open: boolean;
814
- solutions: Array<{
815
- id: number;
816
- problem_id: number;
817
- removed: boolean;
818
- title: string;
819
- body: string;
820
- pro: string;
821
- con: string;
822
- recommended: boolean;
823
808
  content_hash: string;
824
- steps_hash: string;
825
- steps: Array<{
826
- id: number;
827
- solution_id: number;
828
- parent_step_id: null | number;
829
- label: string;
830
- title: string;
831
- description: null | string;
832
- content_hash: string;
833
- checked_at: null | string;
834
- checked_by: null | string;
835
- steps: Array<SolutionStepViewV2>;
836
- }>;
837
- }>;
809
+ summary: null | string;
838
810
  decisions: Array<{
839
811
  id: number;
840
812
  problem_id: number;
@@ -849,17 +821,19 @@ declare module "@danxbot/card-kit@1" {
849
821
  relayed_by_session: null | string;
850
822
  content_hash: string;
851
823
  }>;
824
+ feedback_consent: boolean;
825
+ choice_locked: boolean;
826
+ issue_id: string;
827
+ statement: string;
828
+ context: null | string;
829
+ solutions: Array<SolutionViewV2>;
852
830
  };
853
831
  type SolutionViewV2 = {
832
+ title: string;
854
833
  id: number;
834
+ content_hash: string;
855
835
  problem_id: number;
856
- removed: boolean;
857
- title: string;
858
836
  body: string;
859
- pro: string;
860
- con: string;
861
- recommended: boolean;
862
- content_hash: string;
863
837
  steps_hash: string;
864
838
  steps: Array<{
865
839
  id: number;
@@ -873,6 +847,40 @@ declare module "@danxbot/card-kit@1" {
873
847
  checked_by: null | string;
874
848
  steps: Array<SolutionStepViewV2>;
875
849
  }>;
850
+ removed: boolean;
851
+ pro: string;
852
+ con: string;
853
+ recommended: boolean;
854
+ design?: undefined | (Array<{
855
+ design_no: number;
856
+ title: string;
857
+ created_by: string;
858
+ created_at: string;
859
+ review_state: "rejected" | "awaiting_review" | "changes_requested" | "approved";
860
+ revision_count: number;
861
+ latest_revision_no: number;
862
+ revisions?: undefined | (Array<{
863
+ revision_no: number;
864
+ target: string;
865
+ entry: string;
866
+ built_from_commit: string;
867
+ note: string;
868
+ created_by: string;
869
+ created_at: string;
870
+ bundle_bytes: null | number;
871
+ bundle_available: boolean;
872
+ screenshot_available: boolean;
873
+ source_files?: undefined | Array<DesignSourceFile>;
874
+ }>);
875
+ decisions?: undefined | (Array<{
876
+ decision_id: number;
877
+ revision_no: number;
878
+ outcome: "rejected" | "changes_requested" | "approved";
879
+ note: null | string;
880
+ decided_by: string;
881
+ created_at: string;
882
+ }>);
883
+ }>);
876
884
  };
877
885
  interface SolutionStepViewV2 {
878
886
  id: number;
@@ -1040,6 +1048,7 @@ declare module "@danxbot/card-kit@1" {
1040
1048
  solutions: SolutionViewV2[];
1041
1049
  removedSolutionIds: ReadonlySet<number>;
1042
1050
  decisions: DecisionViewV2[];
1051
+ choiceLocked: boolean;
1043
1052
  }
1044
1053
 
1045
1054
  function ProblemsSection({ cardId, problems, comments, canAnswer, mutation, }: {
package/dist/cli.js CHANGED
@@ -5932,7 +5932,7 @@ ${output.trim()}`));
5932
5932
  }
5933
5933
  function isManifest(value) {
5934
5934
  const manifest = value;
5935
- return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5935
+ return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.exports) && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5936
5936
  }
5937
5937
  async function readBuiltPlugin(projectDir) {
5938
5938
  const distDir = join3(resolve2(projectDir), PLUGIN_DIST_DIR);
@@ -5942,7 +5942,7 @@ async function readBuiltPlugin(projectDir) {
5942
5942
  } catch (err) {
5943
5943
  throw new Error(`danx-plugin: the build left no readable ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} (is the danxPlugin() preset in vite.config?): ${err.message}`);
5944
5944
  }
5945
- if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry or no files list of paths`);
5945
+ if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry, no exports list or no files list of paths`);
5946
5946
  const files = await Promise.all(manifest.files.map(async (file) => ({ path: file.path, bytes: await readFile2(join3(distDir, file.path)) })));
5947
5947
  return { manifest, files };
5948
5948
  }
package/dist/publish.d.ts CHANGED
@@ -16,6 +16,8 @@ interface PluginManifestFile {
16
16
  /** Lowercase hex. */
17
17
  readonly sha256: string;
18
18
  }
19
+ declare const PLUGIN_VIEW_EXPORTS: readonly ["CardView", "CardListView"];
20
+ type PluginViewExport = (typeof PLUGIN_VIEW_EXPORTS)[number];
19
21
  interface PluginManifest {
20
22
  /** The ES module the app `import()`s, a `path` in `files`. */
21
23
  readonly entry: string;
@@ -25,6 +27,8 @@ interface PluginManifest {
25
27
  readonly screenshot?: string;
26
28
  /** Each shared library's major the plugin was built against (`PLUGIN_RUNTIME_LIBRARIES`), compared with what the app serves. */
27
29
  readonly runtime: Readonly<Record<string, number>>;
30
+ /** DX-5282: which view modules the entry exports (`PLUGIN_VIEW_EXPORTS`), recorded at build from the entry chunk's real exports; never empty. */
31
+ readonly exports: readonly PluginViewExport[];
28
32
  readonly files: readonly PluginManifestFile[];
29
33
  }
30
34
 
package/dist/publish.js CHANGED
@@ -5927,7 +5927,7 @@ ${output.trim()}`));
5927
5927
  }
5928
5928
  function isManifest(value) {
5929
5929
  const manifest = value;
5930
- return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5930
+ return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.exports) && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5931
5931
  }
5932
5932
  async function readBuiltPlugin(projectDir) {
5933
5933
  const distDir = join3(resolve2(projectDir), PLUGIN_DIST_DIR);
@@ -5937,7 +5937,7 @@ async function readBuiltPlugin(projectDir) {
5937
5937
  } catch (err) {
5938
5938
  throw new Error(`danx-plugin: the build left no readable ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} (is the danxPlugin() preset in vite.config?): ${err.message}`);
5939
5939
  }
5940
- if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry or no files list of paths`);
5940
+ if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry, no exports list or no files list of paths`);
5941
5941
  const files = await Promise.all(manifest.files.map(async (file) => ({ path: file.path, bytes: await readFile2(join3(distDir, file.path)) })));
5942
5942
  return { manifest, files };
5943
5943
  }
package/dist/vite.d.ts CHANGED
@@ -14,7 +14,7 @@ interface DanxPluginOptions {
14
14
  * - Anything else is bundled. Bundling a copy of a shared package (`react-dom/client` or `react-router` are not in the contract) would run a second copy
15
15
  * beside the app's, so that fails the build instead of shipping.
16
16
  * - Code-split chunks load by relative import from the entry's folder; CSS is emitted as one `index.css`.
17
- * - `danx-plugin.json` is written beside the output: every file's size and sha256, the entry, the stylesheets and the runtime majors.
17
+ * - `danx-plugin.json` is written beside the output: every file's size and sha256, the entry, the view modules it exports, the stylesheets and the runtime majors.
18
18
  */
19
19
  declare function danxPlugin(options?: DanxPluginOptions): Plugin;
20
20
 
package/dist/vite.js CHANGED
@@ -33,6 +33,9 @@ import { join, relative, sep } from "node:path";
33
33
 
34
34
  // ../../src/plugins/plugin-manifest.ts
35
35
  var PLUGIN_MANIFEST_FILE = "danx-plugin.json";
36
+ var CARD_VIEW_EXPORT = "CardView";
37
+ var CARD_LIST_VIEW_EXPORT = "CardListView";
38
+ var PLUGIN_VIEW_EXPORTS = [CARD_VIEW_EXPORT, CARD_LIST_VIEW_EXPORT];
36
39
 
37
40
  // src/manifest.ts
38
41
  function filesUnder(root, dir = root) {
@@ -46,18 +49,19 @@ function describeFile(root, file) {
46
49
  sha256: createHash("sha256").update(bytes).digest("hex")
47
50
  };
48
51
  }
49
- function buildManifest(outDir, entry) {
52
+ function buildManifest(outDir, entry, exports) {
50
53
  const files = filesUnder(outDir).map((file) => describeFile(outDir, file)).filter((file) => file.path !== PLUGIN_MANIFEST_FILE);
51
54
  if (!files.some((file) => file.path === entry)) throw new Error(`danx-plugin: the build produced no entry module ${entry} in ${outDir}`);
52
55
  return {
53
56
  entry,
54
57
  styles: files.filter((file) => file.path.endsWith(".css")).map((file) => file.path),
55
58
  runtime: pluginRuntimeContract().majors,
59
+ exports: [...exports],
56
60
  files
57
61
  };
58
62
  }
59
- function writeManifest(outDir, entry) {
60
- const manifest = buildManifest(outDir, entry);
63
+ function writeManifest(outDir, entry, exports) {
64
+ const manifest = buildManifest(outDir, entry, exports);
61
65
  writeFileSync(join(outDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
62
66
  `);
63
67
  return manifest;
@@ -72,6 +76,7 @@ function bundledNeverPackage(moduleId) {
72
76
  }
73
77
  function danxPlugin(options = {}) {
74
78
  const entry = options.entry ?? "src/index.tsx";
79
+ let viewExports = [];
75
80
  return {
76
81
  name: "danx-plugin",
77
82
  config() {
@@ -96,6 +101,14 @@ function danxPlugin(options = {}) {
96
101
  };
97
102
  },
98
103
  generateBundle(_options, bundle) {
104
+ const entryChunk = Object.values(bundle).find((output) => output.type === "chunk" && output.isEntry);
105
+ if (entryChunk?.type !== "chunk") throw new Error(`danx-plugin: the build produced no entry chunk for ${entry}`);
106
+ viewExports = PLUGIN_VIEW_EXPORTS.filter((name) => entryChunk.exports.includes(name));
107
+ if (viewExports.length === 0) {
108
+ throw new Error(
109
+ `danx-plugin: ${entry} must export ${PLUGIN_VIEW_EXPORTS.join(" and/or ")}, but it exports ${entryChunk.exports.length === 0 ? "nothing" : entryChunk.exports.join(", ")}.`
110
+ );
111
+ }
99
112
  for (const output of Object.values(bundle)) {
100
113
  if (output.type !== "chunk") continue;
101
114
  for (const id of output.moduleIds) {
@@ -109,7 +122,7 @@ function danxPlugin(options = {}) {
109
122
  },
110
123
  writeBundle(options2) {
111
124
  if (options2.dir === void 0) throw new Error("danx-plugin: the build has no output directory to write the manifest into");
112
- writeManifest(options2.dir, PLUGIN_ENTRY_FILE);
125
+ writeManifest(options2.dir, PLUGIN_ENTRY_FILE, viewExports);
113
126
  }
114
127
  };
115
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/plugin-sdk",
3
- "version": "0.1.6",
3
+ "version": "0.2.2",
4
4
  "description": "SDK for building 50 Arms card-type plugins (DX-5170): the card kit's type declarations, a Vite preset that builds a plugin against the app's shared runtime and writes its manifest, and the danx-plugin CLI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,7 +46,7 @@
46
46
  "test": "vitest run"
47
47
  },
48
48
  "devDependencies": {
49
- "@danxbot/ui": "26.20.0",
49
+ "@danxbot/ui": "26.23.0",
50
50
  "@types/node": "^22.0.0",
51
51
  "@types/react": "^19.2.2",
52
52
  "esbuild": "^0.25.0",