code-workspace-zhuiyi 1.0.0-beta.5 → 1.0.0

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,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "releaseVersion": "1.0.0-beta.5",
3
+ "releaseVersion": "1.0.0",
4
4
  "requirements": {
5
5
  "node": ">=20.19.0"
6
6
  },
File without changes
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // TODO: implement the extension init protocol.
@@ -45,12 +45,16 @@ codew extension init ./example-extension --yes
45
45
 
46
46
  ```text
47
47
  example-extension/
48
+ ├── .gitignore
49
+ ├── README.md
48
50
  ├── extension/
49
51
  │ ├── manifest.json
50
52
  │ └── init.js
51
53
  └── package.json
52
54
  ```
53
55
 
56
+ 初始化产物中的静态文件模板位于仓库的 `artifacts/templates/extension-init/`。后续调整 README、`.gitignore` 或 `extension/` 下的默认文件时,直接修改该模板目录即可;其中 `gitignore` 会在生成时映射为 `.gitignore`,以避免 npm 发布包排除点文件。`extension init` 只负责注入元数据、生成摘要并写入 package envelope。
57
+
54
58
  系统扩展仍使用固定版本目录:
55
59
 
56
60
  ```text
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-workspace-zhuiyi",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0",
4
4
  "description": "Local multi-project registry and safety layer for AI coding workspaces",
5
5
  "author": "icebearx-ai",
6
6
  "license": "MIT",
@@ -38,8 +38,25 @@ function validateScaffoldMetadata(options = {}, targetRoot) {
38
38
  return Object.freeze({ id, name, description, version });
39
39
  }
40
40
 
41
- function shellEntry() {
42
- return "#!/usr/bin/env node\n\"use strict\";\n\n// TODO: implement the extension init protocol.\n";
41
+ const SCAFFOLD_TEMPLATE_ROOT = path.join(__dirname, "..", "..", "artifacts", "templates", "extension-init");
42
+
43
+ function readTemplateFiles(root = SCAFFOLD_TEMPLATE_ROOT, current = root, result = {}) {
44
+ let entries;
45
+ try {
46
+ entries = fs.readdirSync(current, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
47
+ } catch (error) {
48
+ throw scaffoldError("EXTENSION_TEMPLATE_INVALID", `Cannot read extension init template: ${root}`, { path: root, cause: error.code || error.message });
49
+ }
50
+ for (const entry of entries) {
51
+ const file = path.join(current, entry.name);
52
+ const relative = path.relative(root, file).split(path.sep).join("/");
53
+ const stat = fs.lstatSync(file);
54
+ if (stat.isSymbolicLink()) throw scaffoldError("EXTENSION_TEMPLATE_INVALID", `Extension init template contains a symbolic link: ${relative}`, { path: relative });
55
+ if (stat.isDirectory()) readTemplateFiles(root, file, result);
56
+ else if (stat.isFile()) result[relative === "gitignore" ? ".gitignore" : relative] = fs.readFileSync(file);
57
+ else throw scaffoldError("EXTENSION_TEMPLATE_INVALID", `Extension init template contains a special file: ${relative}`, { path: relative });
58
+ }
59
+ return result;
43
60
  }
44
61
 
45
62
  function validateShellManifest(raw) {
@@ -107,7 +124,9 @@ function shellEnvelope(metadata, packageSha256) {
107
124
  function scaffoldExtensionPackage(target, options = {}) {
108
125
  const targetRoot = path.resolve(target || ".");
109
126
  const metadata = validateScaffoldMetadata(options, targetRoot);
110
- const entry = shellEntry();
127
+ const templateFiles = readTemplateFiles();
128
+ const entry = templateFiles["extension/init.js"];
129
+ if (!entry) throw scaffoldError("EXTENSION_TEMPLATE_INVALID", "Extension init template must contain extension/init.js", { path: "extension/init.js" });
111
130
  const manifest = {
112
131
  schemaVersion: 3,
113
132
  extensionSpecVersion: 1,
@@ -121,9 +140,9 @@ function scaffoldExtensionPackage(target, options = {}) {
121
140
  timeoutMs: 30000,
122
141
  };
123
142
  const files = {
143
+ ...templateFiles,
124
144
  "package.json": null,
125
145
  "extension/manifest.json": Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`, "utf8"),
126
- "extension/init.js": Buffer.from(entry, "utf8"),
127
146
  };
128
147
  const temporary = fs.mkdtempSync(path.join(path.dirname(targetRoot), `.${path.basename(targetRoot)}-`));
129
148
  try {