@hadooppei/hwcode 0.2.0 → 0.2.1

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/.env.example CHANGED
@@ -1,10 +1,5 @@
1
- # Keep real credentials outside version control.
2
- # Local provider credentials. Model addresses and capabilities live in
3
- # .pi/model-providers.json.
4
- PI_LOCAL_MODEL_API_KEY=local
5
-
6
- # Optional credential used as the default when logging in to the configurable
7
- # "hw" provider. Leave unset for a keyless local endpoint.
1
+ # Keep real credentials outside version control. Set this value to provide the
2
+ # required "hw" credential through the environment, or enter it through /login.
8
3
  # HW_API_KEY=
9
4
 
10
5
  # OPENAI_API_KEY=
@@ -1,7 +1,7 @@
1
1
  import { dirname, join } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
 
4
- import { loadReplacingResource } from "../runtime/config.ts";
4
+ import { readJsonObject } from "../runtime/config.ts";
5
5
 
6
6
  export type ModelInput = "text" | "image";
7
7
  export interface ConfiguredModel { id: string; name?: string; reasoning?: boolean; input?: ModelInput[]; contextWindow?: number; maxTokens?: number; }
@@ -42,9 +42,9 @@ function validateModel(providerId: string, model: ConfiguredModel): void {
42
42
  if (model.maxTokens !== undefined && !isPositiveNumber(model.maxTokens)) throw new Error(`Model "${model.id}" has an invalid maxTokens`);
43
43
  }
44
44
 
45
- export function loadModelProvidersConfig(cwd = process.cwd()): ModelProvidersConfig {
45
+ export function loadModelProvidersConfig(): ModelProvidersConfig {
46
46
  const source = "model-providers.json";
47
- const config = loadReplacingResource<ModelProvidersConfig & Record<string, unknown>>(cwd, source, BUNDLED_CONFIG_PATH);
47
+ const config = readJsonObject(BUNDLED_CONFIG_PATH) as ModelProvidersConfig & Record<string, unknown>;
48
48
  if (!Array.isArray(config.providers) || config.providers.length === 0) throw new Error(`${source} must contain a non-empty providers array`);
49
49
  const providerIds = new Set<string>();
50
50
  for (const provider of config.providers) {
@@ -1,53 +1,14 @@
1
1
  {
2
2
  "providers": [
3
- {
4
- "id": "local",
5
- "name": "Qwen3 VL (8081)",
6
- "baseUrl": "http://127.0.0.1:8081",
7
- "apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
8
- "modelDefaults": {
9
- "contextWindow": 1000000,
10
- "maxTokens": 8192
11
- },
12
- "models": [
13
- {
14
- "id": "qwen3-VL:2b",
15
- "name": "Qwen3 VL 2B",
16
- "input": ["text", "image"],
17
- "contextWindow": 1000000,
18
- "maxTokens": 8192
19
- }
20
- ]
21
- },
22
- {
23
- "id": "local-8080",
24
- "name": "Qwen3.5 9B (8080)",
25
- "baseUrl": "http://127.0.0.1:8080",
26
- "apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
27
- "modelDefaults": {
28
- "contextWindow": 1000000,
29
- "maxTokens": 8192
30
- },
31
- "models": [
32
- {
33
- "id": "Qwen3.5-9B-Q4_K_M",
34
- "name": "Qwen3.5 9B Q4_K_M",
35
- "input": ["text"],
36
- "contextWindow": 1000000,
37
- "maxTokens": 8192
38
- }
39
- ]
40
- },
41
3
  {
42
4
  "id": "hw",
43
5
  "name": "Huawei MaaS",
44
- "baseUrl": "http://127.0.0.1:8080/v1",
45
6
  "apiKeyEnv": "HW_API_KEY",
46
7
  "login": {
47
8
  "enabled": true,
48
9
  "promptBaseUrl": true,
49
10
  "promptApiKey": true,
50
- "apiKeyRequired": false,
11
+ "apiKeyRequired": true,
51
12
  "catalogPath": "models",
52
13
  "timeoutMs": 15000
53
14
  },
@@ -55,16 +16,7 @@
55
16
  "input": ["text"],
56
17
  "contextWindow": 1000000,
57
18
  "maxTokens": 8192
58
- },
59
- "models": [
60
- {
61
- "id": "Qwen3.5-9B-Q4_K_M",
62
- "name": "Qwen3.5 9B Q4_K_M",
63
- "input": ["text"],
64
- "contextWindow": 1000000,
65
- "maxTokens": 8192
66
- }
67
- ]
19
+ }
68
20
  }
69
21
  ]
70
22
  }
package/README.md CHANGED
@@ -21,10 +21,11 @@ hwcode
21
21
  Run `hwcode --help` for the HWCode command reference, including model,
22
22
  session, tool, and workflow options.
23
23
 
24
- `npx @hadooppei/hwcode` is also supported without a global installation. HWCode loads a
25
- project's `.env` file when present and keeps Pi's normal user-level auth and
26
- session storage. Project-local `.pi` resources continue to load alongside the
27
- built-in HWCode profile.
24
+ `npx @hadooppei/hwcode` is also supported without a global installation. HWCode
25
+ loads a project's `.env` file when present and keeps Pi's normal user-level auth
26
+ and session storage. Project-local Pi resources continue to load alongside the
27
+ built-in HWCode profile, except for HWCode's package-scoped model-provider
28
+ definition described below.
28
29
 
29
30
  ## Repository setup
30
31
 
@@ -38,45 +39,31 @@ On first launch, review and accept Pi's project-trust prompt so it can load the
38
39
 
39
40
  ## Model providers
40
41
 
41
- OpenAI-compatible providers are declared in `.pi/model-providers.json`.
42
- Static providers list their models directly:
42
+ The published `.pi/model-providers.json` is package-scoped and is not replaced
43
+ by a file in the current project. It registers the configurable `hw` provider
44
+ without shipping a machine-specific endpoint or a pre-populated model catalog.
45
+ Use Pi's native `/login` flow, select `Huawei MaaS`, and enter the endpoint and
46
+ API key. The key can instead come from `HW_API_KEY`. HWCode then discovers every model exposed by the
47
+ OpenAI-compatible endpoint and Pi stores the selected endpoint, credential, and
48
+ dynamic catalog in its user-level stores.
43
49
 
44
- ```json
45
- {
46
- "id": "local-example",
47
- "name": "Local example",
48
- "baseUrl": "http://127.0.0.1:8082",
49
- "apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
50
- "models": [
51
- {
52
- "id": "model-id",
53
- "input": ["text", "image"],
54
- "contextWindow": 32768,
55
- "maxTokens": 8192
56
- }
57
- ]
58
- }
59
- ```
60
-
61
- Login providers use Pi's native `/login` flow and discover every model exposed
62
- by an OpenAI-compatible model endpoint:
50
+ The published provider is equivalent to:
63
51
 
64
52
  ```json
65
53
  {
66
54
  "id": "hw",
67
- "name": "hw",
68
- "baseUrl": "http://127.0.0.1:8080/v1",
55
+ "name": "Huawei MaaS",
69
56
  "apiKeyEnv": "HW_API_KEY",
70
57
  "login": {
71
58
  "enabled": true,
72
59
  "promptBaseUrl": true,
73
60
  "promptApiKey": true,
74
- "apiKeyRequired": false,
61
+ "apiKeyRequired": true,
75
62
  "catalogPath": "models"
76
63
  },
77
64
  "modelDefaults": {
78
65
  "input": ["text"],
79
- "contextWindow": 32768,
66
+ "contextWindow": 1000000,
80
67
  "maxTokens": 8192
81
68
  }
82
69
  }
@@ -84,12 +71,14 @@ by an OpenAI-compatible model endpoint:
84
71
 
85
72
  `id` is the stable credential and cache key; `name` is the configurable label
86
73
  shown alongside other providers in `/login`. A login authenticates the whole
87
- provider and publishes its complete model catalog to `/model`. Entries in a
88
- login provider's `models` array are optional metadata overrides for discovered
89
- IDs, which is where vision support should be declared with
90
- `"input": ["text", "image"]`. Unknown models default to text-only. Keep real
91
- API keys in `.env` or enter them through `/login`; Pi stores entered credentials
92
- in its own auth store rather than the project configuration.
74
+ provider and publishes its complete model catalog to `/model`. Unknown models
75
+ default to text-only. Keep real API keys in `.env` or enter them through
76
+ `/login`; Pi stores entered credentials in its own auth store rather than the
77
+ package configuration.
78
+
79
+ Repository maintainers can refer to `.pi/model-providers.json.template` for the
80
+ previous local static-provider examples, including multimodal metadata. The
81
+ template is not loaded at runtime and is explicitly excluded from npm packages.
93
82
 
94
83
  ## Welcome screen
95
84
 
@@ -174,9 +163,9 @@ commands, tools, and UI. Reusable behavior lives under `.pi/lib/`:
174
163
  - `context/` and `models/` own compaction and provider-configuration policy.
175
164
 
176
165
  `settings.json` is layered as defaults → profile → project for settings such as
177
- context and hidden commands. `welcome.json` and `model-providers.json` use a
178
- single replacing resource, preferring project, then profile, then the bundled
179
- default. This keeps configuration precedence consistent across extensions.
166
+ context and hidden commands. `welcome.json` uses a single replacing resource.
167
+ `model-providers.json` is deliberately package-scoped so a project cannot
168
+ silently replace login providers or reintroduce machine-local defaults.
180
169
 
181
170
  ## Working directory
182
171
 
@@ -204,8 +193,9 @@ HWCode defaults locally configured and dynamically discovered models to a
204
193
  1,000,000-token context window and caps configured or provider-reported values
205
194
  at that limit. If an OpenAI-compatible model catalog reports a smaller
206
195
  `context_window`, `context_length`, `max_context_length`, `max_model_len`, or
207
- `n_ctx`, the smaller server value wins. Per-model `contextWindow` values in
208
- `.pi/model-providers.json` can also select a smaller limit.
196
+ `n_ctx`, the smaller server value wins. The package-scoped provider's
197
+ `modelDefaults.contextWindow` can also select a smaller limit for dynamically
198
+ discovered models.
209
199
 
210
200
  The default context policy is configured under `hwcode.context` in
211
201
  `.pi/settings.json`:
package/bin/hwcode.js CHANGED
@@ -82,7 +82,7 @@ HWCode 交互命令:
82
82
  hwcode -p "总结当前代码库"
83
83
  hwcode @README.md "检查文档是否完整"
84
84
 
85
- 项目中的 .env 会自动加载;项目本地 .pi 资源会与 HWCode 内置配置共同生效。`;
85
+ 项目中的 .env 会自动加载;模型 Provider 使用 HWCode 发布配置,其余项目本地 .pi 资源照常生效。`;
86
86
  }
87
87
 
88
88
  if (userArgs[0] === "--help" || userArgs[0] === "-h") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hadooppei/hwcode",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A customizable terminal coding agent with local-model support and HWCode workflows.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "pi": "node --env-file-if-exists=.env ./bin/hwcode.js",
27
27
  "test": "node --test .pi/lib/*.test.ts",
28
28
  "test:workflows": "npm test",
29
- "prepack": "npm test"
29
+ "prepack": "npm test && node scripts/audit-package.mjs"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=22.19.0"