dsh-as-aistudio 0.2.0 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-as-aistudio",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Google-AI-Studio-style turn controls for DeepSeek Harness, in one install: edit a prompt and re-run it, re-run a reply in place, delete a turn from the model context, and render sent prompts as Markdown. Self-contained: the plugin list shows this one row; the four components are dependencies mounted by it. Each still installs alone and works alone.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "dsh-delete-turn": "^0.1.7",
50
- "dsh-edit-turn": "^0.2.15",
50
+ "dsh-edit-turn": "^0.2.25",
51
51
  "dsh-markdown-bubble": "^0.1.4",
52
52
  "dsh-rerun-turn": "^0.1.24"
53
53
  },
@@ -71,7 +71,7 @@
71
71
  "compatibility": {
72
72
  "dshReleases": {
73
73
  "0.1.6-alpha.2": "compatible",
74
- "0.2.0-rc.1": "compatible"
74
+ "0.2.2-rc.1": "compatible"
75
75
  }
76
76
  }
77
77
  }
package/src/client.js CHANGED
@@ -4779,7 +4779,7 @@ window.__ModuleLoader__.load({
4779
4779
  }
4780
4780
 
4781
4781
  // --- which factories the studio mounts ---
4782
- const VENDORED_TABLE = { factory_dsh_edit_turn, factory_dsh_rerun_turn, factory_dsh_delete_turn, factory_dsh_markdown_bubble }
4782
+ const VENDORED_TABLE = { "dsh-edit-turn": factory_dsh_edit_turn, "dsh-rerun-turn": factory_dsh_rerun_turn, "dsh-delete-turn": factory_dsh_delete_turn, "dsh-markdown-bubble": factory_dsh_markdown_bubble }
4783
4783
 
4784
4784
  // --- the studio own browser half ---
4785
4785
 
@@ -4795,7 +4795,7 @@ window.__ModuleLoader__.load({
4795
4795
  const NS = 'dsh-as-aistudio'
4796
4796
 
4797
4797
  /** Keep in sync with package.json and src/components.js. */
4798
- const PLUGIN_VERSION = '0.2.0'
4798
+ const PLUGIN_VERSION = '0.2.2'
4799
4799
 
4800
4800
  /** Presence marker the live verifier reads. */
4801
4801
  const DEBUG_KEY = '__DSH_AS_AISTUDIO__'
package/src/components.js CHANGED
@@ -19,7 +19,7 @@
19
19
  export const STUDIO_ID = 'dsh-as-aistudio'
20
20
 
21
21
  /** Keep in sync with package.json and src/client.js. */
22
- export const STUDIO_VERSION = '0.2.0'
22
+ export const STUDIO_VERSION = '0.2.2'
23
23
 
24
24
  /**
25
25
  * The AI Studio action strip this studio composes, in the order the user meets
package/src/index.js CHANGED
@@ -64,22 +64,32 @@ export async function mountComponentHosts(ctx) {
64
64
  mounted.set(component.id, { mounted: false, reason: 'no-plugin-shape' })
65
65
  continue
66
66
  }
67
+ // A mount is only honest once the fiber has SETTLED. A component whose
68
+ // apply() threw synchronously is caught below, but one whose start failed
69
+ // asynchronously — a tool registered twice, a route refused — rejects after
70
+ // ctx.plugin() has already returned. Reporting it optimistically as mounted
71
+ // is exactly the lie that shipped: the host log said "failed to start" while
72
+ // /status said 4/4. So the record is created optimistic and CORRECTED when
73
+ // the fiber settles, and statusOf reads the record, not the promise.
74
+ const record = { mounted: true, reason: null, dispose: null }
67
75
  try {
68
76
  const fiber = ctx.plugin(plugin)
69
- // A rejected start is still a start we know nothing about yet: record it
70
- // when it settles rather than leaving the row silently half-mounted.
77
+ if (fiber !== undefined && fiber !== null && typeof fiber.dispose === 'function') {
78
+ record.dispose = fiber.dispose.bind(fiber)
79
+ }
71
80
  if (fiber && typeof fiber.then === 'function') {
72
- fiber.then(
81
+ Promise.resolve(fiber).then(
73
82
  () => {},
74
83
  (error) => {
84
+ record.mounted = false
85
+ record.reason = 'start-failed'
75
86
  console.error('[' + STUDIO_ID + '] component ' + component.id + ' failed to start:', error)
76
87
  },
77
88
  )
78
89
  }
79
- mounted.set(component.id, {
80
- mounted: true,
81
- dispose: typeof fiber !== 'undefined' && fiber !== null && typeof fiber.dispose === 'function' ? fiber.dispose.bind(fiber) : null,
82
- })
90
+ // A synchronous apply failure also arrives as a throw here, and it must win
91
+ // over the optimistic value we are about to store.
92
+ mounted.set(component.id, record)
83
93
  } catch (error) {
84
94
  mounted.set(component.id, { mounted: false, reason: 'apply-failed', detail: String((error && error.message) || error) })
85
95
  }
package/src/studio.js CHANGED
@@ -49,7 +49,7 @@ window.__ModuleLoader__.load({
49
49
  const NS = 'dsh-as-aistudio'
50
50
 
51
51
  /** Keep in sync with package.json and src/components.js. */
52
- const PLUGIN_VERSION = '0.2.0'
52
+ const PLUGIN_VERSION = '0.2.2'
53
53
 
54
54
  /** Presence marker the live verifier reads. */
55
55
  const DEBUG_KEY = '__DSH_AS_AISTUDIO__'
package/tools/build.mjs CHANGED
@@ -61,7 +61,17 @@ for (const id of ORDER) {
61
61
  parts.push(' // ===== vendored ' + id + ' =====')
62
62
  parts.push(' const factory_' + id.replace(/-/g, '_') + ' = ' + vendored(id))
63
63
  }
64
- parts.push(read('tail.txt').replace('__T__', ORDER.map((id) => 'factory_' + id.replace(/-/g, '_')).join(', ')))
64
+ // The table is keyed by COMPONENT ID, because that is what the studio looks up
65
+ // (VENDORED_TABLE[id] with id like 'dsh-edit-turn'). Emitting the bare factory
66
+ // names would build an object whose keys are the variable names instead, every
67
+ // lookup would be undefined, and every component would silently fail to mount -
68
+ // which is exactly the regression this line now prevents.
69
+ parts.push(
70
+ read('tail.txt').replace(
71
+ '__T__',
72
+ ORDER.map((id) => JSON.stringify(id) + ': factory_' + id.replace(/-/g, '_')).join(', '),
73
+ ),
74
+ )
65
75
  parts.push(studio)
66
76
  parts.push(read('tail2.txt'))
67
77