@aigne/doc-smith 0.9.7-beta.1 → 0.9.7-beta.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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.7-beta.2](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.9.7-beta.1...v0.9.7-beta.2) (2025-11-28)
4
+
5
+
6
+ ### Features
7
+
8
+ * support secret store for publish config ([#339](https://github.com/AIGNE-io/aigne-doc-smith/issues/339)) ([31bb282](https://github.com/AIGNE-io/aigne-doc-smith/commit/31bb282065707ad718d68d65722a9ced70047c91))
9
+
3
10
  ## [0.9.7-beta.1](https://github.com/AIGNE-io/aigne-doc-smith/compare/v0.9.7-beta...v0.9.7-beta.1) (2025-11-27)
4
11
 
5
12
 
@@ -1,4 +1,3 @@
1
- import { getDocSmithEnvFilePath } from "../../utils/auth-utils.mjs";
2
1
  import {
3
2
  getConfigFilePath,
4
3
  getMediaDescriptionCachePath,
@@ -32,7 +31,7 @@ const TARGET_METADATA = {
32
31
  authTokens: {
33
32
  label: "Authorizations",
34
33
  description: () =>
35
- `Delete authorization information in '${getDocSmithEnvFilePath()}'. You will need to re-authorize after clearing.`,
34
+ "Delete authorization information. You will need to re-authorize after clearing.",
36
35
  agent: "clearAuthTokens",
37
36
  },
38
37
  deploymentConfig: {
@@ -1,25 +1,13 @@
1
- import { existsSync } from "node:fs";
2
- import { readFile, writeFile } from "node:fs/promises";
3
1
  import chalk from "chalk";
4
- import { parse, stringify } from "yaml";
5
- import { getDocSmithEnvFilePath } from "../../utils/auth-utils.mjs";
2
+ import { createStore } from "../../utils/store/index.mjs";
6
3
 
7
4
  export default async function clearAuthTokens(_input = {}, options = {}) {
8
- const DOC_SMITH_ENV_FILE = getDocSmithEnvFilePath();
9
- // Check if the file exists
10
- if (!existsSync(DOC_SMITH_ENV_FILE)) {
11
- return {
12
- message: "🔑 No site authorizations found to clear",
13
- };
14
- }
5
+ const store = await createStore();
15
6
 
16
7
  try {
17
- // Read existing configuration
18
- const data = await readFile(DOC_SMITH_ENV_FILE, "utf8");
19
- const envs = parse(data) || {};
20
-
8
+ const listMap = await store.listMap();
21
9
  // Get all available sites
22
- const siteHostnames = Object.keys(envs);
10
+ const siteHostnames = Object.keys(listMap);
23
11
 
24
12
  if (siteHostnames.length === 0) {
25
13
  return {
@@ -67,24 +55,15 @@ export default async function clearAuthTokens(_input = {}, options = {}) {
67
55
 
68
56
  if (selectedSites.includes("__ALL__")) {
69
57
  // Clear all site authorizations
70
- await writeFile(DOC_SMITH_ENV_FILE, stringify({}));
58
+ await store.clear();
71
59
  results.push(`✔ Cleared site authorization for all sites (${siteHostnames.length} sites)`);
72
60
  clearedCount = siteHostnames.length;
73
61
  } else {
74
- // Clear site authorizations for selected sites
75
- const updatedEnvs = { ...envs };
76
-
77
62
  for (const hostname of selectedSites) {
78
- if (updatedEnvs[hostname]) {
79
- // Remove the entire site object
80
- delete updatedEnvs[hostname];
81
-
82
- results.push(`✔ Cleared site authorization for ${chalk.cyan(hostname)}`);
83
- clearedCount++;
84
- }
63
+ await store.deleteItem(hostname);
64
+ results.push(`✔ Cleared site authorization for ${chalk.cyan(hostname)}`);
65
+ clearedCount++;
85
66
  }
86
-
87
- await writeFile(DOC_SMITH_ENV_FILE, stringify(updatedEnvs));
88
67
  }
89
68
 
90
69
  const header = `🔑 Successfully cleared site authorizations!`;
@@ -3,9 +3,8 @@ description: Evaluates the results generated by the document-structure agent to
3
3
  instructions:
4
4
  url: ../../prompts/evaluate/document-structure.md
5
5
  model:
6
- model: openai/gpt-5
6
+ model: gpt-5
7
7
  temperature: 1
8
- # model: anthropic/claude-opus-4-0
9
8
  task_render_mode: collapse
10
9
  task_title: Evaluate the structure of the documentation
11
10
  input_schema:
@@ -3,9 +3,8 @@ description: Evaluates the quality of generated document content, ensuring compl
3
3
  instructions:
4
4
  url: ../../prompts/evaluate/document.md
5
5
  model:
6
- model: openai/gpt-5
6
+ model: gpt-5
7
7
  temperature: 1
8
- # model: anthropic/claude-opus-4-0
9
8
  task_render_mode: collapse
10
9
  task_title: Evaluate document for '{{ title }}'
11
10
  input_schema:
@@ -1,5 +1,5 @@
1
- import chalk from "chalk";
2
1
  import { createHash } from "node:crypto";
2
+ import chalk from "chalk";
3
3
  import { getHistory } from "../../utils/history-utils.mjs";
4
4
 
5
5
  export default function viewHistory() {
@@ -1,6 +1,6 @@
1
1
  name: generateMediaDescription
2
2
  description: Generate description for a single media file (image/video)
3
- model: "google/gemini-2.5-flash"
3
+ model: gemini-2.5-flash
4
4
  modalities: ["text", "image"]
5
5
  instructions:
6
6
  - role: system
package/aigne.yaml CHANGED
@@ -1,13 +1,12 @@
1
1
  #!/usr/bin/env aigne
2
2
 
3
3
  model:
4
- # model: aignehub/gpt-5
5
- # model: aignehub/claude-sonnet-4-0
6
- model: google/gemini-2.5-pro # reasoning_effort 128-32768
4
+ # model: gemini-3-pro-preview
5
+ model: gemini-2.5-pro
6
+ temperature: 0.8
7
7
  # https://github.com/AIGNE-io/aigne-framework/blob/main/models/gemini/src/gemini-chat-model.ts#L115
8
8
  reasoning_effort:
9
9
  $get: reasoningEffort
10
- temperature: 0.8
11
10
  agents:
12
11
  # Initialization
13
12
  - ./agents/init/index.mjs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/doc-smith",
3
- "version": "0.9.7-beta.1",
3
+ "version": "0.9.7-beta.2",
4
4
  "description": "AI-driven documentation generation tool built on the AIGNE Framework",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,6 +27,7 @@
27
27
  "@aigne/cli": "^1.56.0",
28
28
  "@aigne/core": "^1.69.0",
29
29
  "@aigne/publish-docs": "^0.14.1",
30
+ "@aigne/secrets": "^0.1.1-beta.3",
30
31
  "@blocklet/payment-broker-client": "^1.22.24",
31
32
  "@terrastruct/d2": "^0.1.33",
32
33
  "chalk": "^5.5.0",
@@ -1,13 +1,10 @@
1
1
  import { existsSync, mkdirSync } from "node:fs";
2
- import { readFile, writeFile } from "node:fs/promises";
3
2
  import { homedir } from "node:os";
4
3
  import { join } from "node:path";
5
4
  import { createConnect } from "@aigne/cli/utils/aigne-hub/credential.js";
6
5
  import chalk from "chalk";
7
6
  import open from "open";
8
- import { joinURL } from "ufo";
9
- import { parse, stringify } from "yaml";
10
-
7
+ import { joinURL, withQuery } from "ufo";
11
8
  import {
12
9
  ComponentNotFoundError,
13
10
  getComponentMountPoint,
@@ -21,7 +18,7 @@ import {
21
18
  DISCUSS_KIT_STORE_URL,
22
19
  PAYMENT_KIT_DID,
23
20
  } from "./constants/index.mjs";
24
- import { withQuery } from "ufo";
21
+ import { createStore } from "./store/index.mjs";
25
22
 
26
23
  const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
27
24
 
@@ -30,10 +27,6 @@ const FETCH_INTERVAL = 3000; // 3 seconds
30
27
 
31
28
  const RETRY_COUNT = (TIMEOUT_MINUTES * 60 * 1000) / FETCH_INTERVAL;
32
29
 
33
- export function getDocSmithEnvFilePath() {
34
- return join(homedir(), ".aigne", "doc-smith-connected.yaml");
35
- }
36
-
37
30
  /**
38
31
  * Get access token from environment, config file, or prompt user for authorization
39
32
  * @param {string} baseUrl - The application URL
@@ -41,7 +34,7 @@ export function getDocSmithEnvFilePath() {
41
34
  */
42
35
  export async function getCachedAccessToken(baseUrl) {
43
36
  const { hostname: targetHostname } = new URL(baseUrl);
44
- const DOC_SMITH_ENV_FILE = getDocSmithEnvFilePath();
37
+ const store = await createStore();
45
38
 
46
39
  let accessToken =
47
40
  process.env.DOC_SMITH_PUBLISH_ACCESS_TOKEN || process.env.DOC_DISCUSS_KIT_ACCESS_TOKEN;
@@ -49,16 +42,8 @@ export async function getCachedAccessToken(baseUrl) {
49
42
  // Check if access token exists in environment or config file
50
43
  if (!accessToken) {
51
44
  try {
52
- if (existsSync(DOC_SMITH_ENV_FILE)) {
53
- const data = await readFile(DOC_SMITH_ENV_FILE, "utf8");
54
- if (data.includes("DOC_DISCUSS_KIT_ACCESS_TOKEN")) {
55
- // Handle empty or invalid YAML files
56
- const envs = data.trim() ? parse(data) : null;
57
- if (envs?.[targetHostname]?.DOC_DISCUSS_KIT_ACCESS_TOKEN) {
58
- accessToken = envs[targetHostname].DOC_DISCUSS_KIT_ACCESS_TOKEN;
59
- }
60
- }
61
- }
45
+ const storeItem = await store.getItem(targetHostname);
46
+ accessToken = storeItem?.DOC_DISCUSS_KIT_ACCESS_TOKEN;
62
47
  } catch (error) {
63
48
  console.warn("Could not read the configuration file:", error.message);
64
49
  }
@@ -275,27 +260,14 @@ export async function getOfficialAccessToken(baseUrl, openPage = true, locale =
275
260
  */
276
261
  async function saveTokenToConfigFile(hostname, fields) {
277
262
  try {
278
- const configFile = getDocSmithEnvFilePath();
263
+ const store = await createStore();
279
264
 
280
265
  const aigneDir = join(homedir(), ".aigne");
281
266
  if (!existsSync(aigneDir)) {
282
267
  mkdirSync(aigneDir, { recursive: true });
283
268
  }
284
269
 
285
- let existingConfig = {};
286
- if (existsSync(configFile)) {
287
- const fileContent = await readFile(configFile, "utf8");
288
- const parsedConfig = fileContent.trim() ? parse(fileContent) : null;
289
- existingConfig = parsedConfig || {};
290
- }
291
-
292
- await writeFile(
293
- configFile,
294
- stringify({
295
- ...existingConfig,
296
- [hostname]: fields,
297
- }),
298
- );
270
+ await store.setItem(hostname, fields);
299
271
  } catch (error) {
300
272
  console.warn(`Could not save the token to the configuration file: ${error.message}`, error);
301
273
  // The token is already in the environment, so we don't need to throw an error here.
@@ -1,5 +1,5 @@
1
1
  import { execSync } from "node:child_process";
2
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { parse, stringify } from "yaml";
5
5
  import { DOC_SMITH_DIR } from "./constants/index.mjs";
@@ -0,0 +1,45 @@
1
+ import { access, rm } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import createSecretStore, { FileStore } from "@aigne/secrets";
5
+
6
+ export async function createStore() {
7
+ const filepath = join(homedir(), ".aigne", "doc-smith-connected.yaml");
8
+ const secretStore = await createSecretStore({
9
+ filepath,
10
+ serviceName: "aigne-doc-smith-publish",
11
+ });
12
+
13
+ async function migrate() {
14
+ // system doesn't support keyring
15
+ if (secretStore instanceof FileStore) {
16
+ return true;
17
+ }
18
+ // already migrated
19
+ try {
20
+ await access(filepath);
21
+ } catch {
22
+ return true;
23
+ }
24
+
25
+ const fileStore = new FileStore({ filepath });
26
+ const map = await fileStore.listMap();
27
+ for (const [key, value] of Object.entries(map)) {
28
+ await secretStore.setItem(key, value);
29
+ }
30
+ await rm(filepath);
31
+ }
32
+
33
+ async function clear() {
34
+ const map = await secretStore.listMap();
35
+ for (const key of Object.keys(map)) {
36
+ await secretStore.deleteItem(key);
37
+ }
38
+ }
39
+
40
+ await migrate();
41
+
42
+ secretStore.clear = clear;
43
+
44
+ return secretStore;
45
+ }