@jskit-ai/assistant 0.1.41 → 0.1.42

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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/assistant",
4
- version: "0.1.41",
4
+ version: "0.1.42",
5
5
  kind: "generator",
6
6
  description: "Install assistant runtime/config for one surface and scaffold assistant pages at explicit target files.",
7
7
  options: {
@@ -19,8 +19,7 @@ export default Object.freeze({
19
19
  inputType: "text",
20
20
  validationType: "enabled-surface-id",
21
21
  defaultValue: "",
22
- promptLabel: "Settings surface",
23
- promptHint: "Enabled settings host surface id used by assistant setup.",
22
+ promptLabel: "Which enabled surface should host the assistant settings UI?",
24
23
  helpHint: "Surface that hosts the settings UI for the selected assistant runtime."
25
24
  },
26
25
  "config-scope": {
@@ -69,7 +68,7 @@ export default Object.freeze({
69
68
  "ai-config-prefix": {
70
69
  required: false,
71
70
  inputType: "text",
72
- defaultValue: "",
71
+ defaultFromOptionTemplate: "${option:surface|snake|upper}_ASSISTANT",
73
72
  promptLabel: "AI config prefix",
74
73
  promptHint: "Optional env/config prefix override. Defaults to <SURFACE>_ASSISTANT."
75
74
  },
@@ -87,8 +86,7 @@ export default Object.freeze({
87
86
  promptHint: "Leave empty to keep the assistant disabled until you add a key."
88
87
  },
89
88
  "ai-base-url": {
90
- required: true,
91
- allowEmpty: true,
89
+ required: false,
92
90
  defaultValue: "",
93
91
  promptLabel: "AI base URL",
94
92
  promptHint: "Optional provider-compatible base URL override."
@@ -289,19 +287,40 @@ export default Object.freeze({
289
287
  }
290
288
  },
291
289
  {
292
- op: "append-text",
293
290
  file: ".env",
294
- position: "bottom",
295
- skipIfContains: "__ASSISTANT_AI_CONFIG_PREFIX___AI_PROVIDER=",
296
- value:
297
- "\n__ASSISTANT_AI_CONFIG_PREFIX___AI_PROVIDER=${option:ai-provider}\n__ASSISTANT_AI_CONFIG_PREFIX___AI_API_KEY=${option:ai-api-key}\n__ASSISTANT_AI_CONFIG_PREFIX___AI_BASE_URL=${option:ai-base-url}\n__ASSISTANT_AI_CONFIG_PREFIX___AI_TIMEOUT_MS=${option:ai-timeout-ms}\n",
298
- reason: "Append assistant AI env defaults for the generated surface prefix.",
291
+ op: "upsert-env",
292
+ key: "${option:ai-config-prefix}_AI_PROVIDER",
293
+ value: "${option:ai-provider}",
294
+ reason: "Configure the assistant AI provider for the selected surface.",
299
295
  category: "runtime-config",
300
- id: "assistant-ai-prefixed-env",
301
- templateContext: {
302
- entrypoint: "src/server/buildTemplateContext.js",
303
- export: "buildTemplateContext"
304
- }
296
+ id: "assistant-ai-provider"
297
+ },
298
+ {
299
+ file: ".env",
300
+ op: "upsert-env",
301
+ key: "${option:ai-config-prefix}_AI_API_KEY",
302
+ value: "${option:ai-api-key}",
303
+ reason: "Configure the assistant AI API key for the selected surface.",
304
+ category: "runtime-config",
305
+ id: "assistant-ai-api-key"
306
+ },
307
+ {
308
+ file: ".env",
309
+ op: "upsert-env",
310
+ key: "${option:ai-config-prefix}_AI_BASE_URL",
311
+ value: "${option:ai-base-url}",
312
+ reason: "Configure the optional assistant AI base URL override for the selected surface.",
313
+ category: "runtime-config",
314
+ id: "assistant-ai-base-url"
315
+ },
316
+ {
317
+ file: ".env",
318
+ op: "upsert-env",
319
+ key: "${option:ai-config-prefix}_AI_TIMEOUT_MS",
320
+ value: "${option:ai-timeout-ms}",
321
+ reason: "Configure the assistant AI timeout for the selected surface.",
322
+ category: "runtime-config",
323
+ id: "assistant-ai-timeout-ms"
305
324
  }
306
325
  ]
307
326
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/assistant",
3
- "version": "0.1.41",
3
+ "version": "0.1.42",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -9,6 +9,6 @@
9
9
  "./server/buildTemplateContext": "./src/server/buildTemplateContext.js"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/kernel": "0.1.32"
12
+ "@jskit-ai/kernel": "0.1.33"
13
13
  }
14
14
  }
@@ -94,7 +94,7 @@ function renderAssistantPageLinkPlacementBlock({
94
94
 
95
95
  function renderAssistantPageSummary(
96
96
  pageTarget = {},
97
- { pageAlreadyExisted = false, pageOverwritten = false, placementChanged = false } = {}
97
+ { pageAlreadyExisted = false, pageOverwritten = false } = {}
98
98
  ) {
99
99
  if (!pageAlreadyExisted) {
100
100
  return `Generated assistant page "${String(pageTarget?.routeUrlSuffix || "")}".`;
@@ -102,10 +102,7 @@ function renderAssistantPageSummary(
102
102
  if (pageOverwritten) {
103
103
  return `Regenerated assistant page "${String(pageTarget?.routeUrlSuffix || "")}".`;
104
104
  }
105
- if (placementChanged) {
106
- return `Updated assistant page link placement for "${String(pageTarget?.routeUrlSuffix || "")}".`;
107
- }
108
- return `Assistant page "${String(pageTarget?.routeUrlSuffix || "")}" is already up to date.`;
105
+ return `Generated assistant page "${String(pageTarget?.routeUrlSuffix || "")}".`;
109
106
  }
110
107
 
111
108
  export {
@@ -96,8 +96,7 @@ async function runGeneratorSubcommand({
96
96
  touchedFiles: [...touchedFiles].sort((left, right) => left.localeCompare(right)),
97
97
  summary: renderAssistantPageSummary(pageTarget, {
98
98
  pageAlreadyExisted,
99
- pageOverwritten: pageAlreadyExisted && forceOverwrite,
100
- placementChanged: placementApplied.changed
99
+ pageOverwritten: pageAlreadyExisted && forceOverwrite
101
100
  })
102
101
  };
103
102
  }
@@ -100,8 +100,7 @@ async function runGeneratorSubcommand({
100
100
  touchedFiles: [...touchedFiles].sort((left, right) => left.localeCompare(right)),
101
101
  summary: renderAssistantPageSummary(pageTarget, {
102
102
  pageAlreadyExisted,
103
- pageOverwritten: pageAlreadyExisted && forceOverwrite,
104
- placementChanged: placementApplied.changed
103
+ pageOverwritten: pageAlreadyExisted && forceOverwrite
105
104
  })
106
105
  };
107
106
  }
@@ -15,8 +15,13 @@ test("assistant descriptor exposes setup as the primary command and still depend
15
15
  assert.equal(descriptor.options?.["settings-surface"]?.required, true);
16
16
  assert.equal(descriptor.options?.["settings-surface"]?.validationType, "enabled-surface-id");
17
17
  assert.equal(descriptor.options?.["config-scope"]?.defaultValue, "global");
18
+ assert.equal(
19
+ descriptor.options?.["ai-config-prefix"]?.defaultFromOptionTemplate,
20
+ "${option:surface|snake|upper}_ASSISTANT"
21
+ );
18
22
  assert.equal(descriptor.options?.name?.required, false);
19
23
  assert.equal(descriptor.options?.["link-placement"]?.required, false);
24
+ assert.equal(descriptor.options?.["ai-base-url"]?.required, false);
20
25
  assert.deepEqual(descriptor.dependsOn, ["@jskit-ai/assistant-runtime"]);
21
26
  });
22
27
 
@@ -34,16 +39,30 @@ test("assistant descriptor defines explicit page subcommands and setup-only muta
34
39
  assert.equal(fileMutations.length, 0);
35
40
  });
36
41
 
37
- test("assistant descriptor appends only setup config and env entries", () => {
42
+ test("assistant descriptor appends setup config and upserts assistant env entries", () => {
38
43
  const publicConfig = findTextMutation("assistant-public-surface-config");
39
44
  const serverConfig = findTextMutation("assistant-server-surface-config");
40
- const envBlock = findTextMutation("assistant-ai-prefixed-env");
45
+ const envProvider = findTextMutation("assistant-ai-provider");
46
+ const envApiKey = findTextMutation("assistant-ai-api-key");
47
+ const envBaseUrl = findTextMutation("assistant-ai-base-url");
48
+ const envTimeout = findTextMutation("assistant-ai-timeout-ms");
41
49
  const textMutations = Array.isArray(descriptor?.mutations?.text) ? descriptor.mutations.text : [];
42
50
 
43
- assert.equal(textMutations.length, 3);
51
+ assert.equal(textMutations.length, 6);
44
52
  assert.match(String(publicConfig?.value || ""), /config\.assistantSurfaces\.\$\{option:surface\|lower\} = \{/);
45
53
  assert.match(String(publicConfig?.value || ""), /settingsSurfaceId: "__ASSISTANT_SETTINGS_SURFACE_ID__"/);
46
54
  assert.match(String(serverConfig?.value || ""), /config\.assistantServer\.\$\{option:surface\|lower\} = \{/);
47
55
  assert.match(String(serverConfig?.value || ""), /aiConfigPrefix: "__ASSISTANT_AI_CONFIG_PREFIX__"/);
48
- assert.match(String(envBlock?.value || ""), /__ASSISTANT_AI_CONFIG_PREFIX___AI_PROVIDER=\$\{option:ai-provider\}/);
56
+ assert.equal(envProvider?.op, "upsert-env");
57
+ assert.equal(envProvider?.key, "${option:ai-config-prefix}_AI_PROVIDER");
58
+ assert.equal(envProvider?.value, "${option:ai-provider}");
59
+ assert.equal(envApiKey?.op, "upsert-env");
60
+ assert.equal(envApiKey?.key, "${option:ai-config-prefix}_AI_API_KEY");
61
+ assert.equal(envApiKey?.value, "${option:ai-api-key}");
62
+ assert.equal(envBaseUrl?.op, "upsert-env");
63
+ assert.equal(envBaseUrl?.key, "${option:ai-config-prefix}_AI_BASE_URL");
64
+ assert.equal(envBaseUrl?.value, "${option:ai-base-url}");
65
+ assert.equal(envTimeout?.op, "upsert-env");
66
+ assert.equal(envTimeout?.key, "${option:ai-config-prefix}_AI_TIMEOUT_MS");
67
+ assert.equal(envTimeout?.value, "${option:ai-timeout-ms}");
49
68
  });
@@ -87,6 +87,7 @@ test("assistant page subcommand creates a runtime page at an explicit target fil
87
87
  });
88
88
 
89
89
  assert.deepEqual(result.touchedFiles, [toPagePath(targetFile), "src/placement.js"]);
90
+ assert.equal(result.summary, 'Generated assistant page "/ops/copilot".');
90
91
 
91
92
  const pageSource = await readFile(path.join(appRoot, toPagePath(targetFile)), "utf8");
92
93
  assert.match(pageSource, /<AssistantSurfaceClientElement surface-id="admin" \/>/);
@@ -129,6 +130,7 @@ test("assistant settings-page subcommand uses the target assistant surface and i
129
130
  });
130
131
 
131
132
  assert.deepEqual(result.touchedFiles, [toPagePath(targetFile), "src/placement.js"]);
133
+ assert.equal(result.summary, 'Generated assistant page "/settings/assistant".');
132
134
 
133
135
  const pageSource = await readFile(path.join(appRoot, toPagePath(targetFile)), "utf8");
134
136
  assert.match(pageSource, /<AssistantSettingsClientElement target-surface-id="console" \/>/);