@enter-pro/enter-cli 0.4.1 → 0.4.3

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,14 +1,27 @@
1
1
  {
2
2
  "name": "@enter-pro/enter-cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Enter CLI - manage Enter platform resources from the command line",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "enter-cli": "dist/index.js"
9
9
  },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "test": "npm run build && node --test",
15
+ "mock:serve": "node scripts/mock-enter.mjs",
16
+ "local:cli": "node scripts/local-cli.mjs",
17
+ "prepublishOnly": "npm run build",
18
+ "install:hosts": "node scripts/install-hosts.mjs"
19
+ },
10
20
  "files": [
11
- "dist"
21
+ "dist",
22
+ "skills",
23
+ "scripts/install-hosts.mjs",
24
+ "README.md"
12
25
  ],
13
26
  "publishConfig": {
14
27
  "access": "public"
@@ -25,17 +38,16 @@
25
38
  },
26
39
  "dependencies": {
27
40
  "commander": "^13.0.0",
28
- "js-yaml": "^4.1.0"
41
+ "https-proxy-agent": "^7.0.6",
42
+ "js-yaml": "^4.3.2",
43
+ "proxy-from-env": "^1.1.0",
44
+ "ws": "^8.21.3"
29
45
  },
30
46
  "devDependencies": {
31
47
  "@types/js-yaml": "^4.0.9",
32
48
  "@types/node": "^22.0.0",
49
+ "@types/proxy-from-env": "^1.0.4",
50
+ "@types/ws": "^8.18.1",
33
51
  "typescript": "^5.7.0"
34
- },
35
- "scripts": {
36
- "build": "tsc",
37
- "dev": "tsc --watch",
38
- "start": "node dist/index.js",
39
- "test": "npm run build && node --test"
40
52
  }
41
- }
53
+ }
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'node:util';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { readFileSync, writeFileSync, mkdirSync, cpSync, chmodSync, realpathSync } from 'node:fs';
5
+ import { homedir } from 'node:os';
6
+ import { resolve, join } from 'node:path';
7
+ import { createHash } from 'node:crypto';
8
+ const { values } = parseArgs({ options: { package: { type: 'string' }, host: { type: 'string', default: 'all' }, home: { type: 'string', default: homedir() } } });
9
+ if (!values.package || !['all', 'codex', 'dsh'].includes(values.host)) throw Error('Usage: install-hosts.mjs --package /path/package.tgz [--host all|codex|dsh] [--home /path]');
10
+ const archive = realpathSync(values.package);
11
+ const hash = createHash('sha256').update(readFileSync(archive)).digest('hex');
12
+ const quote = s => "'" + s.replaceAll("'", "'\\''") + "'";
13
+ for (const host of values.host === 'all' ? ['codex', 'dsh'] : [values.host]) {
14
+ const root = join(resolve(values.home), '.' + host);
15
+ const prefix = join(root, 'tools/enter-cli');
16
+ const result = spawnSync('npm', ['install', '--prefix', prefix, '--ignore-scripts', '--no-audit', '--no-fund', archive], { stdio: 'inherit' });
17
+ if (result.status !== 0) throw Error(`Installation failed for ${host}`);
18
+ const installed = join(prefix, 'node_modules/@enter-pro/enter-cli');
19
+ const skill = join(root, 'skills/enter');
20
+ mkdirSync(join(skill, 'scripts'), { recursive: true });
21
+ cpSync(join(installed, 'skills/enter/references'), join(skill, 'references'), { recursive: true });
22
+ const wrapper = join(skill, 'scripts/enter-cli');
23
+ writeFileSync(wrapper, '#!/bin/sh\nset -eu\nexport NODE_USE_ENV_PROXY="${NODE_USE_ENV_PROXY:-1}"\nexec ' + quote(realpathSync(process.execPath)) + ' ' + quote(join(installed, 'dist/index.js')) + ' "$@"\n');
24
+ chmodSync(wrapper, 0o755);
25
+ writeFileSync(join(skill, 'SKILL.md'), readFileSync(join(installed, 'skills/enter/SKILL.md'), 'utf8').replaceAll('{{CLI_ENTRY}}', wrapper));
26
+ const pkg = JSON.parse(readFileSync(join(installed, 'package.json'), 'utf8'));
27
+ writeFileSync(join(prefix, 'install-info.json'), JSON.stringify({ version: pkg.version, package_sha256: hash, installed_at: new Date().toISOString(), source_archive: archive }, null, 2) + '\n');
28
+ console.log(`${host}: installed ${pkg.version}, sha256 ${hash}`);
29
+ }
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: enter
3
+ description: 使用 Enter CLI 创建和修改网站或应用,跟踪任务、处理提问与配置卡,并交付 Enter 的构建和验证结果。
4
+ ---
5
+
6
+ # Enter
7
+
8
+ 用户描述需求,Enter 负责开发与视觉/功能验证,宿主通过 CLI 提交、收集输入和交付。
9
+
10
+ ## 入口
11
+
12
+ 使用 `{{CLI_ENTRY}}`。第一次调用核对 `--version` 和登录状态;命令参数按需查 `--help`。输出优先用 JSON,保持 stdout/stderr 分离;不要回显完整身份资料或凭据。
13
+
14
+ ## 流程
15
+
16
+ 1. 从用户上下文确定项目;新建时确定 workspace。通过 `project create` 或 `thread chat` 提交一次,保存 task_id。accepted 或观察超时不代表完成,也不是重新提交的理由。
17
+ 2. 按下方观察规则执行返回的 wait_command,按同一 task_id 继续;需交付构建时加 `--require-build`。新增需求单独记录返回的 task_id。
18
+ 3. 状态的 `workflow` 给出任务关联、next_action 和构建匹配信息。遇到 `handle_actions` 按下方卡片规则处理;`read_delivery` 执行 messages_command,取得 Enter 的总结与验证证据。未知关联不代表提交失败,不猜测它属于其他已完成任务。
19
+ 4. 依用户已有授权继续,不因阶段切换反复确认。明确要求用户决策的计划和提问仍需转交。写操作超时或解析失败先查真实状态,再决定是否重试。
20
+ 5. 交付说明完成内容、预览/发布地址、Enter 验证结果及待配置项;代码存在、配置保存、构建成功、真实服务可用分开判断。发布按用户授权范围执行。
21
+
22
+ ## 观察与响应
23
+
24
+ - 默认执行短时 wait(返回命令为 10 秒),返回后先处理用户新消息,再按同一任务续接。观察超时只结束本次观察;不要为等到完成不断增加超时,也不要重新提交任务。
25
+ - 只有宿主支持完成通知和非阻塞取结果时,才选择后台 watch。启动后让出对话执行权,由通知续接;不要再用数分钟的阻塞工具等待后台任务。若无法可靠接收通知,使用短时 wait。始终只保留一个观察路径,不叠加 sleep 或反复查询。
26
+ - 用户问进度时,先用最新已知状态答复并标明是否为上次观察;需要刷新再执行一次 status,随后继续原任务。不要等到构建完成才回答。收到完成通知先读取该任务结果,再决定是否需要继续观察。
27
+ - CLI 的 `--timeout` 限制观察进程寿命,宿主的取结果等待参数限制一次工具调用;两者都不是实际耗时。耗时看时间戳,任务是否结束看返回状态,不能由等待上限推断卡死。
28
+
29
+ ## 卡片
30
+
31
+ - 计划:展示 plan,等待用户同意或修改意见,展示不等于批准。
32
+ - ask_user_question:转交所有问题、选项和单/多选要求,收集答案后用 --answers 回传。JSON 的键是 Enter 原始问题全文,不是宿主提问工具生成的 ID;值是 {"selected_options":["选项原文"],"other_text":"自由文字"},纯文字回答使用空数组。只有用户要求跳过时才执行 skip_command。
33
+ - 普通确认:已有授权就 approve;需要新的决定时询问。用户拒绝才 reject。
34
+ - 配置输入:已有授权和值/文件就提交;缺什么只问什么。普通配置可直接询问,真实密钥使用可用的安全输入或用户指定文件;表单是替代入口,不强制绕路。OAuth/secret/Stripe 的字段、stdin 和更新方法见 [配置输入](references/configuration.md),仅遇到这些卡片时读取。
35
+
36
+ CLI 负责事件监听、断线恢复和查询兜底;宿主负责后台调度与用户交互。等待工具不自动批准卡片。宿主没有浏览器不影响 Enter 内部验证,不以关键词扫描替代其验证结果。
@@ -0,0 +1,19 @@
1
+ # 配置输入
2
+
3
+ 遇到 OAuth、Stripe 或 secret 卡时读取。目标是让用户提供一次所缺信息,然后由 CLI 保存、批准并继续任务。
4
+
5
+ 1. 读取卡片字段和现有任务上下文。已有获授权的值或文件直接使用;缺少字段时只说明字段用途及可用输入方式,不默认要求切换网页,也不反复确认已有授权。
6
+ 2. 非敏感配置(例如 GA Measurement ID)可直接询问。真实密钥使用宿主已有安全输入或用户指定文件;没有这些渠道时给出 Enter 项目表单入口。不要虚构宿主弹窗。用户主动提供的值可按当前授权处理,避免再次复制;若工具无法在不暴露值的情况下提交,说明具体限制并改用文件或表单。
7
+ 3. OAuth JSON 字段以卡片 configuration.fields 为准。Google 示例结构为 client_ids、client_secret;只在确实需要时给模板。文件通过重定向送入 stdin,命令中只有路径:
8
+
9
+ ```sh
10
+ <CLI> --output json thread approve <PROJECT> <ACTION> --auth-config-stdin < /absolute/path/oauth.json
11
+ <CLI> --output json thread approve <PROJECT> <ACTION> --secret-value-stdin < /absolute/path/stripe-key.txt
12
+ <CLI> --output json thread approve <PROJECT> <ACTION> --secret-name <NAME> --secret-value-stdin < /absolute/path/secret.txt
13
+ ```
14
+
15
+ `<CLI>` 使用技能入口的实际路径。不要 cat 文件、把值插入 printf/heredoc 或复制进 Enter 构建提示;这些都会进入工具记录。stdin 只避免 CLI 参数暴露,不能消除上游聊天或工具记录。不要在命令中合并 stderr 与需要 JSON 解析的 stdout。
16
+
17
+ 4. 表单保存可能已批准卡片,先查状态;CLI 批准后按返回 task_id 继续。不重复要求用户填写。OAuth 回调地址以实际配置返回或表单为准;需要服务商配置时提供确切地址,不猜测,也不声称该地址只能从某个入口取得。
18
+ 5. 提交失败先查状态再决定是否重试;例如 failed to connect Stripe 只说明连接失败,未证明具体原因。缺输入时等待补填,不自行拒绝卡片。用户明确暂不接入才 reject。
19
+ 6. 读取 Enter 的交付总结和验证证据。分别说明配置已保存、功能已接线、构建/发布状态、真实服务是否验证;mock 值可以验证流程,不能证明登录或支付成功。需要换值时沿同一配置流程更新,保持用户已选择的发布范围。