openyida 2026.10.13 → 2026.10.14-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/README.md +63 -23
- package/bin/yida.js +32 -2
- package/lib/agent/PROTOCOL.md +201 -0
- package/lib/agent/ask-human-help.js +19 -0
- package/lib/agent/ask-human.js +222 -0
- package/lib/agent/cmd.js +405 -0
- package/lib/agent/command-receipt.js +84 -0
- package/lib/agent/connection-store.js +148 -0
- package/lib/agent/diagnostic-log.js +133 -0
- package/lib/agent/frozen-bundle.js +308 -0
- package/lib/agent/managed-command-map.js +47 -0
- package/lib/agent/managed-context.js +40 -0
- package/lib/agent/managed-run.js +84 -0
- package/lib/agent/mutation-receipt.js +82 -0
- package/lib/agent/private-directory.js +83 -0
- package/lib/agent/provider-preflight.js +253 -0
- package/lib/agent/providers.js +4 -0
- package/lib/agent/runtime-catalog.json +42 -0
- package/lib/agent/runtime-manifest.js +96 -0
- package/lib/agent/runtime-package.js +159 -0
- package/lib/agent/stdio.js +326 -0
- package/lib/app/check-prd-completeness.js +15 -4
- package/lib/app/create-form/batch.js +30 -9
- package/lib/app/create-form.js +7 -2
- package/lib/app/custom-theme.js +13 -3
- package/lib/app/get-schema.js +6 -1
- package/lib/app/update-app.js +13 -1
- package/lib/app/update-form-config.js +71 -80
- package/lib/asset/asset-plan.js +6 -4
- package/lib/auth/profile-lock.js +89 -0
- package/lib/auth/token-auth.js +57 -6
- package/lib/auth/token-store.js +26 -2
- package/lib/core/agent-capabilities.js +1 -0
- package/lib/core/command-manifest.js +206 -120
- package/lib/core/locales/en.js +49 -4
- package/lib/core/locales/zh.js +49 -4
- package/lib/core/managed-policy.js +88 -0
- package/lib/core/query-data.js +22 -3
- package/lib/core/sample.js +1 -0
- package/lib/core/update.js +3 -1
- package/lib/core/utils.js +34 -1
- package/lib/design-plan/confirmation.js +23 -2
- package/lib/design-plan/materialize.js +5 -22
- package/lib/design-plan/patch.js +1 -1
- package/lib/design-plan/render-html.js +299 -0
- package/lib/design-plan/visual-policy.js +20 -7
- package/lib/page-config/save-share-config.js +16 -5
- package/lib/samples/yida-data-management/empty-query.js +69 -0
- package/package.json +12 -2
- package/scripts/postinstall.js +2 -2
- package/yida-skills/SKILL.md +32 -2
- package/yida-skills/references/local-agent-diagnostics.md +154 -0
- package/yida-skills/references/local-agent-preflight.md +56 -0
- package/yida-skills/references/query-condition-guide.md +223 -195
- package/yida-skills/skills/yida-app/SKILL.md +1 -1
- package/yida-skills/skills/yida-app/workflow/plan/step-4-deliver.md +16 -20
- package/yida-skills/skills/yida-app/workflow/plan/workflow.md +4 -4
- package/yida-skills/skills/yida-app/workflow/step-2-design.md +1 -1
- package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +8 -5
- package/yida-skills/skills/yida-data-management/SKILL.md +64 -19
- package/yida-skills/skills/yida-data-management/references/data-format-guide.md +61 -25
- package/yida-skills/skills/yida-data-source-connectors/SKILL.md +6 -0
- package/yida-skills/skills/yida-design/SKILL.md +6 -3
- package/yida-skills/skills/yida-design/references/ask-human-interaction-contract.md +6 -4
- package/yida-skills/skills/yida-design/references/reference-visual-dna.md +34 -0
- package/yida-skills/skills/yida-design/references/theme-selection.md +27 -12
- package/yida-skills/skills/yida-design/sub_skill/ui-improve/references/confirmation.md +1 -1
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/SKILL.md +3 -3
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-theme-selection.md +7 -8
- package/yida-skills/skills/yida-design/templates/design-themes/README.md +1 -1
- package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +1 -1
- package/yida-skills/skills/yida-document-markdown/SKILL.md +6 -0
- package/yida-skills/skills/yida-image-assets/SKILL.md +1 -1
- package/yida-skills/skills/yida-requirement-analysis/references/handoff.md +2 -2
- package/yida-skills/skills/yida-requirement-analysis/workflow/prepare-brief.md +1 -1
- package/yida-skills/skills/yida-tingji/SKILL.md +4 -0
- package/yida-skills/skills-index.json +52 -7
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
OpenYida connects AI coding agents with Yida's low-code platform, so developers can create apps, forms, workflows, custom pages, reports, integrations, and deployment configuration from a normal chat-driven development workflow.
|
|
10
10
|
|
|
11
|
-
[Quick Start](#quick-start) · [帮助网站&文档](https://demo.aliwork.com/o/openyida/helpCenter) · [Capabilities](#capabilities) · [Full Capability List](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=capabilities) · [CLI Reference](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=features/skills) · [Examples](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=showcase) · [Contributing](./CONTRIBUTING.md) · [Changelog](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=changelog)
|
|
11
|
+
[Quick Start](#quick-start) · [帮助网站&文档](https://demo.aliwork.com/o/openyida/helpCenter) · [Capabilities](#capabilities) · [Full Capability List](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=capabilities) · [CLI Reference](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=features/skills) · [Examples](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=showcase) · [Contributing](./CONTRIBUTING.md) · [Changelog](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=changelog) · [Application Previews](#application-previews)
|
|
12
12
|
|
|
13
13
|
[](https://www.npmjs.com/package/openyida)
|
|
14
14
|
[](https://www.npmjs.com/package/openyida)
|
|
@@ -16,8 +16,6 @@ OpenYida connects AI coding agents with Yida's low-code platform, so developers
|
|
|
16
16
|
[](./LICENSE)
|
|
17
17
|
[](https://nodejs.org)
|
|
18
18
|
|
|
19
|
-
**帮助网站&文档:** [帮助网站&文档](https://demo.aliwork.com/o/openyida/helpCenter)
|
|
20
|
-
|
|
21
19
|
[English README](./README.md) · [简体中文 README](./README_zhCN.md)
|
|
22
20
|
|
|
23
21
|
</div>
|
|
@@ -26,7 +24,32 @@ OpenYida connects AI coding agents with Yida's low-code platform, so developers
|
|
|
26
24
|
|
|
27
25
|
## What OpenYida Provides
|
|
28
26
|
|
|
29
|
-
OpenYida is a bridge between AI coding tools and Yida. It gives agents a stable
|
|
27
|
+
OpenYida is a bridge between AI coding tools and Yida. It gives agents a stable `openyida` CLI to create resources, inspect schemas, generate source code, compile and publish pages, and diagnose issues.
|
|
28
|
+
|
|
29
|
+
The result remains a native Yida application: teams can continue editing it in Yida, use existing enterprise security controls, and deploy through the Yida platform.
|
|
30
|
+
|
|
31
|
+
## Application Previews
|
|
32
|
+
|
|
33
|
+
Example applications built with the themes below. Click an image to view it at full size. These are visual references, not ready-made business applications: content, data, brand colors, and layouts are adapted to your requirements.
|
|
34
|
+
|
|
35
|
+
<table>
|
|
36
|
+
<tr>
|
|
37
|
+
<td width="50%" align="center"><strong>Dark Rail · Fine Lines</strong><br><a href="https://img.alicdn.com/imgextra/i1/O1CN01oFp7XMYEjSI5r31K_!!6000000006946-2-tps-2884-1794.png"><img src="https://img.alicdn.com/imgextra/i1/O1CN01oFp7XMYEjSI5r31K_!!6000000006946-2-tps-2884-1794.png" alt="Dark Rail · Fine Lines example application" width="100%"></a></td>
|
|
38
|
+
<td width="50%" align="center"><strong>Soft Inset Surfaces</strong><br><a href="https://img.alicdn.com/imgextra/i3/O1CN01UEEmuLlMF3I5pHky_!!6000000006290-2-tps-2870-1798.png"><img src="https://img.alicdn.com/imgextra/i3/O1CN01UEEmuLlMF3I5pHky_!!6000000006290-2-tps-2870-1798.png" alt="Soft Inset Surfaces example application" width="100%"></a></td>
|
|
39
|
+
</tr>
|
|
40
|
+
<tr>
|
|
41
|
+
<td width="50%" align="center"><strong>Sage</strong><br><a href="https://img.alicdn.com/imgextra/i1/O1CN01NiHI4pBsbOK5qIC4_!!6000000007377-2-tps-2878-1798.png"><img src="https://img.alicdn.com/imgextra/i1/O1CN01NiHI4pBsbOK5qIC4_!!6000000007377-2-tps-2878-1798.png" alt="Sage example application" width="100%"></a></td>
|
|
42
|
+
<td width="50%" align="center"><strong>Teal</strong><br><a href="https://img.alicdn.com/imgextra/i2/O1CN01hLAdOTwuEWF5qXno_!!6000000004848-2-tps-2880-1796.png"><img src="https://img.alicdn.com/imgextra/i2/O1CN01hLAdOTwuEWF5qXno_!!6000000004848-2-tps-2880-1796.png" alt="Teal example application" width="100%"></a></td>
|
|
43
|
+
</tr>
|
|
44
|
+
<tr>
|
|
45
|
+
<td width="50%" align="center"><strong>Terminal</strong><br><a href="https://img.alicdn.com/imgextra/i3/O1CN01PPHEYDv6nMB5qXnq_!!6000000004777-2-tps-2880-1798.png"><img src="https://img.alicdn.com/imgextra/i3/O1CN01PPHEYDv6nMB5qXnq_!!6000000004777-2-tps-2880-1798.png" alt="Terminal example application" width="100%"></a></td>
|
|
46
|
+
<td width="50%" align="center"><strong>Platinum</strong><br><a href="https://img.alicdn.com/imgextra/i2/O1CN01eDGhh1WCtFI5soHi_!!6000000007333-2-tps-2898-1792.png"><img src="https://img.alicdn.com/imgextra/i2/O1CN01eDGhh1WCtFI5soHi_!!6000000007333-2-tps-2898-1792.png" alt="Platinum example application" width="100%"></a></td>
|
|
47
|
+
</tr>
|
|
48
|
+
</table>
|
|
49
|
+
|
|
50
|
+
Use an **application theme or an independent creative direction**. Describe a style you like, or provide a reference website or design image to customize your app’s appearance. [Browse more application examples](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=showcase).
|
|
51
|
+
|
|
52
|
+
## Core Capabilities
|
|
30
53
|
|
|
31
54
|
| Area | What you can do |
|
|
32
55
|
|------|-----------------|
|
|
@@ -38,7 +61,18 @@ OpenYida is a bridge between AI coding tools and Yida. It gives agents a stable
|
|
|
38
61
|
| Integrations | Manage HTTP connectors, connector actions, auth accounts, and automation flows |
|
|
39
62
|
| Operations | Diagnose environment issues, manage login state, configure sharing, upload CDN assets |
|
|
40
63
|
|
|
41
|
-
|
|
64
|
+
## From Request to Delivery
|
|
65
|
+
|
|
66
|
+
1. **Describe the goal.** Explain who will use the app, what they need to do, and any existing app or reference material.
|
|
67
|
+
2. **Share requirements and preferences.** Add the business details and appearance preferences that matter to you. Include any colors, websites, or design images you like.
|
|
68
|
+
3. **Choose how to build.** Fast suits clear requirements you want to move forward with. Plan produces a reviewable proposal and waits for approval before creating resources.
|
|
69
|
+
4. **Review and refine.** Check the delivered app and common actions, then request page, field, or workflow changes. Your chosen style is reused unless you ask to change it.
|
|
70
|
+
|
|
71
|
+
For existing-app improvements, review the visual proposal before backups and implementation. Restoration uses the saved backups; page content and theme settings need separate backups, with the supported scope explained before changes.
|
|
72
|
+
|
|
73
|
+
## Recent Updates
|
|
74
|
+
|
|
75
|
+
**2026.10.14-1** improves appearance customization, with better support for style descriptions, reference websites, and design images. [Read the full changelog](./CHANGELOG.md#20261014-1---2026-10-14).
|
|
42
76
|
|
|
43
77
|
## Quick Start
|
|
44
78
|
|
|
@@ -50,9 +84,14 @@ npm install -g openyida
|
|
|
50
84
|
|
|
51
85
|
OpenYida requires Node.js 18 or later. The package exposes both `openyida` and `yida` commands.
|
|
52
86
|
|
|
53
|
-
|
|
87
|
+
Global npm installations check for updates at most once a day and update automatically. Run `openyida update` to update manually, or set `OPENYIDA_NO_AUTO_UPDATE=1` to keep your installed version.
|
|
88
|
+
|
|
89
|
+
<details>
|
|
90
|
+
<summary>Auto-update environments and development settings</summary>
|
|
91
|
+
|
|
92
|
+
Local terminals and AI tools share the same policy. Managed cloud Agent runtimes skip automatic updates. For development and testing, `OPENYIDA_AUTO_UPDATE_SECS` changes the check interval.
|
|
54
93
|
|
|
55
|
-
|
|
94
|
+
</details>
|
|
56
95
|
|
|
57
96
|
If Codex is already installed, OpenYida also imports a local Codex plugin during postinstall. Restart Codex after installation, then type `@宜搭` or `@openyida` in the composer to attach the OpenYida context.
|
|
58
97
|
|
|
@@ -64,7 +103,7 @@ Run this from the AI coding workspace where you want OpenYida to operate:
|
|
|
64
103
|
openyida agent-capabilities --summary-json
|
|
65
104
|
```
|
|
66
105
|
|
|
67
|
-
|
|
106
|
+
This checks the installed version, login state, and workspace. Use `openyida agent-capabilities --json` for detailed diagnostics.
|
|
68
107
|
|
|
69
108
|
### 3. Log In
|
|
70
109
|
|
|
@@ -105,8 +144,9 @@ Ask your coding agent for a concrete Yida application or workflow:
|
|
|
105
144
|
|
|
106
145
|
```text
|
|
107
146
|
Create a CRM application in Yida with customer, contact, opportunity, and follow-up forms.
|
|
108
|
-
|
|
109
|
-
|
|
147
|
+
Use Plan mode to design a procurement app with requests, approvals, and dashboards. Show me the proposal first.
|
|
148
|
+
Build an oolong tea brand storefront and order management back office, with navigation groups.
|
|
149
|
+
Improve the appearance of this existing app. Show me the proposal first, preserve business logic, and back up before changes.
|
|
110
150
|
```
|
|
111
151
|
|
|
112
152
|
The agent can then call OpenYida commands to create the application, generate source files, publish pages, and return the final Yida URLs. In Codex, QwenWork, Qoder, Qoder IDE, and QoderWork environments, successful creation and publish commands also include a browser handoff so the agent can open the resulting Yida page in the in-app browser. Use `--open` to force this handoff or `--no-open` to suppress it.
|
|
@@ -118,7 +158,6 @@ The agent can then call OpenYida commands to create the application, generate so
|
|
|
118
158
|
| [Codex](https://openai.com/codex/) | Full support |
|
|
119
159
|
| [Claude Code](https://claude.ai/code) | Full support |
|
|
120
160
|
| [MuleRun](https://mulerun.com) | Full support |
|
|
121
|
-
| [OpenCode](https://opencode.ai) | Full support |
|
|
122
161
|
| [Cursor](https://cursor.com/) | Full support |
|
|
123
162
|
| [Visual Studio Code](https://code.visualstudio.com/) | Full support |
|
|
124
163
|
| QwenWork(千问办公) | Full support |
|
|
@@ -163,18 +202,6 @@ openyida/
|
|
|
163
202
|
|
|
164
203
|
For a user-facing list of supported features and matching CLI commands, see [OpenYida 功能完整列表](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=capabilities).
|
|
165
204
|
|
|
166
|
-
### Style Selection and Optional Previews
|
|
167
|
-
|
|
168
|
-
Only show reference previews when the user explicitly requests them. Style choices use the host's supported ask_human tool on every platform.
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
openyida sample yida-design theme-preview --theme-ids app-sage,app-teal,app-terminal,app-platinum --output .cache/theme-preview.html --json
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
This creates a read-only HTML gallery of all requested themes: titles and images only, four to six columns on desktop, fewer on narrow screens, with no row limit. It has no selection controls and refuses to overwrite existing files. Open it with the host's preview tools; raw HTML is not guaranteed to render in chat. QwenWork may alternatively prepare the same read-only template with `sample yida-design theme-selector --json` and pass its returned relative `widget_path` to `qoder_show_widget`. Neither preview path submits a choice.
|
|
175
|
-
|
|
176
|
-
Ready style questions join the same ask_human call as other necessary questions; split only for dependencies or host limits. Pop art is omitted unless explicitly requested or the primary task is showcase-oriented. Previewing app-pop requires --pop-art-context explicit-request or showcase, based on that evidence.
|
|
177
|
-
|
|
178
205
|
### Application and Form Management
|
|
179
206
|
|
|
180
207
|
```bash
|
|
@@ -537,6 +564,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
537
564
|
|---------|-------------|
|
|
538
565
|
| `openyida commands [--json]` | Output machine-readable command manifest |
|
|
539
566
|
| `openyida agent-capabilities [--json] [--summary-json\|--compact]` | Output one-shot agent capability snapshot |
|
|
567
|
+
| `openyida agent <doctor\|diagnose\|status\|connect\|run\|disconnect\|logout\|logs> [options]` | Connect a local Agent (Go runtime, development preview) |
|
|
540
568
|
| `openyida a2a <serve\|agent-card> [options]` | Start local read-only A2A adapter or print Agent Card |
|
|
541
569
|
| `openyida bridge start [--token <pair-token>] [--port 6736] [--origin https://demo.aliwork.com] [--open\|--no-open]` | Start OpenYida local web bridge service |
|
|
542
570
|
| `openyida copy [--force]` | Copy project working directory |
|
|
@@ -605,6 +633,18 @@ Form field definitions can include `alias` or `componentAlias` to populate Yida
|
|
|
605
633
|
|
|
606
634
|
`openyida integration create` supports form events (`insert`, `update`, `delete`, `comment`) and approval events (`processFinish`, `activityTask`; aliases: `approval`, `approvalNode`). Approval events require `--approval-actions agree,disagree,terminated`; `activityTask` also requires `--approval-node-ids <nodeId,...>`. Passing `--process-code` selects a full graph replacement and now requires explicit `--replace`; it is not a safe update. `integration update` currently performs capability detection only: because full platform `processJson` + `viewJson` readback is unproven, it writes a redacted local probe artifact and returns `PLATFORM_PROBE_REQUIRED` before authentication, spec reading, or remote writes. It does not edit a flow.
|
|
607
635
|
|
|
636
|
+
### Connect a Local Agent
|
|
637
|
+
|
|
638
|
+
Use an installed Qoder or Codex CLI on your computer to run tasks from the Yida web app. Local Agent supports macOS and Windows; the ordinary OpenYida CLI also supports Linux.
|
|
639
|
+
|
|
640
|
+
Check your local environment, then follow the connection instructions in the Yida web app:
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
openyida agent doctor --json
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
After connecting, the service runs in the background. Use `openyida agent status` to check its status, `openyida agent logs` to view logs, and `openyida agent disconnect` to disconnect. After restarting your computer, run `openyida agent run` to reconnect.
|
|
647
|
+
|
|
608
648
|
## Agent Skills
|
|
609
649
|
|
|
610
650
|
The `yida-skills/` directory is the source skill library used by OpenYida during development and distributed with the npm package.
|
package/bin/yida.js
CHANGED
|
@@ -24,6 +24,8 @@ const { COMMAND_GROUPS, buildCommandManifest, findCommandSuggestion } = require(
|
|
|
24
24
|
const command = process.argv[2];
|
|
25
25
|
const args = process.argv.slice(3);
|
|
26
26
|
const rawArgs = process.argv.slice(3);
|
|
27
|
+
const { beginCommandReceipt } = require('../lib/agent/command-receipt');
|
|
28
|
+
let commandReceipt;
|
|
27
29
|
|
|
28
30
|
function shouldUseEnvManagement(argsList) {
|
|
29
31
|
const subCommand = argsList[0];
|
|
@@ -571,6 +573,26 @@ function assertNoUnsupportedLegacyLoginFlags(...argLists) {
|
|
|
571
573
|
}
|
|
572
574
|
|
|
573
575
|
async function main() {
|
|
576
|
+
const { assertManagedInvocation, resolveManagedHelp } = require('../lib/agent/managed-run');
|
|
577
|
+
const { readManagedContext } = require('../lib/agent/managed-context');
|
|
578
|
+
if (readManagedContext() && [command, ...rawArgs].some(arg => arg === '--help' || arg === '-h')) {
|
|
579
|
+
assertManagedInvocation(command, rawArgs);
|
|
580
|
+
const entries = resolveManagedHelp(command, rawArgs, { t, version: currentVersion });
|
|
581
|
+
// Managed help is static and local: no Receipt, auth, update, first-run
|
|
582
|
+
// guide or business command module may run on this path.
|
|
583
|
+
commandReceipt = { finish() {} };
|
|
584
|
+
if (rawArgs.includes('--json')) {
|
|
585
|
+
console.log(JSON.stringify({ name: 'openyida', version: currentVersion, commands: entries }, null, 2));
|
|
586
|
+
} else {
|
|
587
|
+
printCommandUsage(...entries.flatMap(entry => [entry.usage, entry.description, ...(entry.examples || [])]));
|
|
588
|
+
}
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
commandReceipt = beginCommandReceipt({ command, args: rawArgs });
|
|
592
|
+
process.once('exit', code => {
|
|
593
|
+
try {commandReceipt.finish(code);} catch {process.exitCode = 1;}
|
|
594
|
+
});
|
|
595
|
+
assertManagedInvocation(command, rawArgs);
|
|
574
596
|
applyQuietFlag();
|
|
575
597
|
applyGlobalEnvironmentFlags();
|
|
576
598
|
|
|
@@ -619,6 +641,12 @@ async function main() {
|
|
|
619
641
|
break;
|
|
620
642
|
}
|
|
621
643
|
|
|
644
|
+
case 'agent': {
|
|
645
|
+
const { run } = require('../lib/agent/cmd');
|
|
646
|
+
await run(args);
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
|
|
622
650
|
case 'mcp': {
|
|
623
651
|
const { runStdioServer } = require('../lib/mcp/server');
|
|
624
652
|
runStdioServer();
|
|
@@ -894,8 +922,8 @@ async function main() {
|
|
|
894
922
|
if (args.length < 4) {
|
|
895
923
|
throwCliUsage(t('cli.form_config_usage'), t('cli.form_config_example'));
|
|
896
924
|
}
|
|
897
|
-
|
|
898
|
-
|
|
925
|
+
const { run: runUpdateFormConfig } = require('../lib/app/update-form-config');
|
|
926
|
+
await runUpdateFormConfig(args);
|
|
899
927
|
break;
|
|
900
928
|
}
|
|
901
929
|
|
|
@@ -1291,7 +1319,9 @@ async function main() {
|
|
|
1291
1319
|
}
|
|
1292
1320
|
|
|
1293
1321
|
main()
|
|
1322
|
+
.then(() => { commandReceipt.finish(process.exitCode || 0); })
|
|
1294
1323
|
.catch((err) => {
|
|
1324
|
+
try {commandReceipt?.finish(err && err.exitCode ? err.exitCode : 1);} catch { /* Intent remains recoverable. */ }
|
|
1295
1325
|
if (shouldUseStructuredErrorOutput(err, args)) {
|
|
1296
1326
|
console.error(JSON.stringify(toErrorPayload(err), null, 2));
|
|
1297
1327
|
} else if (isCliError(err)) {
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Local runtime launcher contract
|
|
2
|
+
|
|
3
|
+
This Node package ships no Go source. The packaged catalog and exact optional
|
|
4
|
+
platform dependencies select signed runtime binaries for macOS and Windows,
|
|
5
|
+
x64 and ARM64. npm installs the package matching the actual OS/CPU. Ordinary
|
|
6
|
+
commands do not resolve or spawn this runtime. There is no arbitrary URL, PATH
|
|
7
|
+
runtime discovery, or build/download fallback.
|
|
8
|
+
|
|
9
|
+
## Production metadata and development mode
|
|
10
|
+
|
|
11
|
+
`runtime-manifest.js` is the strict v2 codec: no extra/duplicate JSON keys, malformed
|
|
12
|
+
UTF-8, unknown OS/CPU aliases, invalid protocol/state ranges, unsafe binary paths,
|
|
13
|
+
oversized metadata/binaries or invalid digests. The binary path is exactly
|
|
14
|
+
`bin/openyida-agent-runtime` (Windows: `.exe`). `sourceRevision` is a 40- or
|
|
15
|
+
64-character lowercase source commit digest, not a public artifact tag.
|
|
16
|
+
|
|
17
|
+
Detached Ed25519 signature: original UTF-8 `runtime-manifest.json` bytes, with no
|
|
18
|
+
re-serialization; `.sig` is canonical base64 for 64 signature bytes, optionally
|
|
19
|
+
one final LF. Trust roots live in the main package's `runtime-catalog.json`:
|
|
20
|
+
`keys[keyId] = {publicKey: <SPKI PEM>, revoked?: boolean}`. Unknown/revoked keys
|
|
21
|
+
fail closed; no TOFU, downloaded trust key, arbitrary URL or PATH fallback exists.
|
|
22
|
+
|
|
23
|
+
Each approved release entry is `{platform, arch, packageName, packageVersion,
|
|
24
|
+
runtimeVersion, manifestSha256}`. The main package must declare that exact
|
|
25
|
+
`optionalDependencies` version. Public package naming is
|
|
26
|
+
`@openyida/local-agent-runtime-${process.platform}-${process.arch}`. Platform metadata must match its
|
|
27
|
+
exact name/version and single-element `os`/`cpu`, and have no lifecycle scripts.
|
|
28
|
+
Main-package-relative Node resolution supports hoisting; platform packages must
|
|
29
|
+
make `package.json` resolvable. Missing optional packages block Local Agent only.
|
|
30
|
+
The current production platform allowlist is macOS (`darwin`) and Windows (`win32`).
|
|
31
|
+
Linux remains a source/development target but must not appear in the production
|
|
32
|
+
catalog or optional dependencies until native acceptance is complete. Ordinary
|
|
33
|
+
non-Agent OpenYida CLI commands remain available on Linux.
|
|
34
|
+
|
|
35
|
+
Unsigned v1 requires CLI `--development-runtime` plus explicit absolute
|
|
36
|
+
`--runtime-path` and `--runtime-manifest`. Environment variables cannot enable it.
|
|
37
|
+
Node sends `developmentRuntime: true` only for that flag. v1 is not accepted as a
|
|
38
|
+
production compatibility fallback. Development binaries are normalized to the
|
|
39
|
+
bundle executable filename; their original manifest is preserved as evidence.
|
|
40
|
+
|
|
41
|
+
## Launch DTO (protocolVersion remains 1)
|
|
42
|
+
|
|
43
|
+
Go argv is `[command, "--stdio-config"]`; stdin is one JSON object plus LF, at
|
|
44
|
+
most 64 KiB. Business access/refresh tokens and ordinary OpenYida profile
|
|
45
|
+
identifiers are never included. The launch contains the control endpoint,
|
|
46
|
+
endpointId, providers and stateDir; web-first connect may additionally contain
|
|
47
|
+
one short-lived Enrollment token. `node.version` remains the OpenYida package
|
|
48
|
+
version, not the Node version.
|
|
49
|
+
|
|
50
|
+
CLI-first connect lets Go create a state/PKCE/device-key-bound Enrollment and open
|
|
51
|
+
the configured browser authorization page. Web-first connect receives the same
|
|
52
|
+
device result by claiming the single-use `--enroll` token. Both modes persist only
|
|
53
|
+
device connection credentials. For every accepted attempt, Python requests a
|
|
54
|
+
fixed-value Tianshu task grant with an initial 60-minute lease and Go injects it
|
|
55
|
+
only into that attempt's managed environment; Node never falls back to a normal
|
|
56
|
+
local profile. The authenticated Runtime heartbeat lets Python renew the lease
|
|
57
|
+
server-to-server while the authoritative Run remains active. Node has no task
|
|
58
|
+
RefreshToken and cannot renew the bearer itself. The grant is bound to the
|
|
59
|
+
application, not one form/page. An optional `formUuid` remains per-turn focus
|
|
60
|
+
context and may change between turns inside the same `appType`.
|
|
61
|
+
|
|
62
|
+
The device bearer is not sufficient by itself. Python sends a fresh nonce before
|
|
63
|
+
accepting the Runtime hello, and Go signs the device/endpoint/nonce binding with
|
|
64
|
+
the Ed25519 key created at Enrollment. Refresh requests similarly sign the
|
|
65
|
+
device/action/refresh-token digest/endpoint binding. A copied access or refresh
|
|
66
|
+
bearer therefore cannot connect or rotate without the enrolled private key.
|
|
67
|
+
|
|
68
|
+
For both `connect` and `run`, added fields are:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"parentWatchFD": 3,
|
|
73
|
+
"node": {
|
|
74
|
+
"executable": "/external/node",
|
|
75
|
+
"nodeVersion": "v22.22.3",
|
|
76
|
+
"sha256": "NODE_BINARY_SHA256",
|
|
77
|
+
"version": "2026.9.7",
|
|
78
|
+
"packageRoot": "/private/bundles/BUNDLE_SHA256/openyida",
|
|
79
|
+
"cliEntry": "/private/bundles/BUNDLE_SHA256/openyida/bin/yida.js"
|
|
80
|
+
},
|
|
81
|
+
"bundle": {
|
|
82
|
+
"schemaVersion": 1,
|
|
83
|
+
"id": "BUNDLE_SHA256",
|
|
84
|
+
"root": "/private/bundles/BUNDLE_SHA256",
|
|
85
|
+
"manifestPath": "/private/bundles/BUNDLE_SHA256/bundle-manifest.json",
|
|
86
|
+
"manifestSha256": "BUNDLE_SHA256",
|
|
87
|
+
"runtimeVersion": "0.1.0-dev",
|
|
88
|
+
"skillsDir": "/private/bundles/BUNDLE_SHA256/openyida/yida-skills"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The launcher uses four stdio pipes and keeps fd 3 open independently from normal
|
|
94
|
+
configuration stdin EOF. Parent death/pipe EOF asks Go to stop admission and
|
|
95
|
+
cancel/drain, never to report successful completion. Node forwards SIGINT/TERM;
|
|
96
|
+
failure grants 15 seconds before forcing the Go wrapper down. Such timeout returns
|
|
97
|
+
`AGENT_RUNTIME_STOP_UNCONFIRMED` with `executionState: unknown`, not proof that
|
|
98
|
+
provider processes or in-flight business effects stopped.
|
|
99
|
+
|
|
100
|
+
## Bundle bytes, ownership and lifetime
|
|
101
|
+
|
|
102
|
+
`bundle-manifest.json` is `JSON.stringify(object) + "\n"`, encoded as UTF-8.
|
|
103
|
+
Its exact SHA-256 is the bundle ID; it is a local content manifest, not a publisher
|
|
104
|
+
signature. Fields (in emitted order) are:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
schemaVersion: 1
|
|
108
|
+
product: "openyida-local-agent-bundle"
|
|
109
|
+
openyidaVersion, runtimeVersion
|
|
110
|
+
launcherProtocol: 1
|
|
111
|
+
wireProtocol: 1
|
|
112
|
+
node: {version: <process.version>, sha256: <external Node binary hash>}
|
|
113
|
+
runtime: {executable: "runtime/bin/openyida-agent-runtime[.exe]",
|
|
114
|
+
manifest: "runtime/runtime-manifest.json",
|
|
115
|
+
signature: "runtime/runtime-manifest.sig" | null,
|
|
116
|
+
development: boolean}
|
|
117
|
+
cliEntry: "openyida/bin/yida.js"
|
|
118
|
+
skillsDir: "openyida/yida-skills"
|
|
119
|
+
files: [{path: <relative POSIX>, size: <integer>, sha256: <lowercase hex>,
|
|
120
|
+
mode: 292 | 365}]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Files sort by path using UTF-8 byte order (not JavaScript UTF-16 comparison).
|
|
124
|
+
Mode 292 is octal 0444; 365 is 0555.
|
|
125
|
+
The manifest is not its own files entry. Unknown files and symlinks are rejected.
|
|
126
|
+
Go verifies the same raw manifest digest, file list/hash/size/mode, launch paths,
|
|
127
|
+
runtime version and external Node identity before accepting work and before
|
|
128
|
+
subsequent helper/new-turn use. Production publication trust is established by
|
|
129
|
+
Node's v2 signature and approved digest, not by pretending the local bundle hash
|
|
130
|
+
is a release signature.
|
|
131
|
+
|
|
132
|
+
Node copies only packaged CLI assets and the recursively resolved production
|
|
133
|
+
dependency/peer/available optional closure, preserving nested dependency
|
|
134
|
+
resolution and cycles. It omits root platform packages (verified runtime bytes
|
|
135
|
+
are copied separately), user projects, credentials, checkout metadata and
|
|
136
|
+
devDependencies. Source content/tree membership is checked again before publish;
|
|
137
|
+
missing dependencies or concurrent replacement fail closed. No install hook runs.
|
|
138
|
+
|
|
139
|
+
Unique private staging directories plus atomic compare-and-publish handle
|
|
140
|
+
concurrent materializers without a second execution lease. Contents are read-only;
|
|
141
|
+
on macOS the staging root must remain writable until rename, then becomes 0500.
|
|
142
|
+
Cache is 0700 on Unix. Same-user/root compromise is outside this protection;
|
|
143
|
+
Windows ACL/OS release acceptance remains unverified. Interrupted staging is not
|
|
144
|
+
an executable published bundle. Node does not repair a modified winner or GC
|
|
145
|
+
existing bundles, unknown journals or user files.
|
|
146
|
+
|
|
147
|
+
Go exclusively owns durable refs under
|
|
148
|
+
`stateDir/bundle-references/<bundleId>/...` for connection, session and attempt
|
|
149
|
+
lifetimes. Session identity no longer pins BundleID.
|
|
150
|
+
Node has no ref writer, owner lease, GC or automatic migration. Global npm upgrade
|
|
151
|
+
can produce a new bundle. After the connection drains and is restarted, a compatible
|
|
152
|
+
bundle may continue the same native session; an active attempt never switches. External Node and
|
|
153
|
+
provider binaries are not redistributed/frozen by this package; loss or an
|
|
154
|
+
incompatible change blocks new work rather than silently starting fresh.
|
|
155
|
+
|
|
156
|
+
For allowlisted Yida write commands only, Node writes one bounded Mutation Receipt
|
|
157
|
+
after an explicit success result in OPENYIDA_AGENT_RECEIPTS_DIR. Read-only, failed
|
|
158
|
+
and interrupted commands write nothing.
|
|
159
|
+
Go forwards a successful openyida_mutation through the authenticated Run stream;
|
|
160
|
+
Python adds requiresHostRefresh. No Go command gateway is involved.
|
|
161
|
+
Windows parent lifetime uses parentPID and an OS process handle, not parentWatchFD.
|
|
162
|
+
|
|
163
|
+
All current automated tests use generated signing keys and fake processes.
|
|
164
|
+
No real provider, user account, Yida write, public upload or npm publication is
|
|
165
|
+
part of this implementation checkpoint.
|
|
166
|
+
|
|
167
|
+
### Background startup receipt
|
|
168
|
+
|
|
169
|
+
A background `run` can carry a fresh `startupId` (safe identifier, generated per
|
|
170
|
+
spawn). The runtime atomically writes `startup-<startupId>.json` in `stateDir`
|
|
171
|
+
with mode 0600 after the control endpoint is bound, the cloud welcome is
|
|
172
|
+
validated, and recovery finishes. Its only fields are `protocolVersion: 1`,
|
|
173
|
+
`startupId`, and boolean `ready`. The launcher requires `ready: true`, then removes
|
|
174
|
+
the receipt and detaches. Provider logs are never a startup acknowledgement.
|
|
175
|
+
A startup failure/exit or the 60-second deadline rejects the launch; the launcher
|
|
176
|
+
terminates only its own new child, preserving credentials and journals.
|
|
177
|
+
|
|
178
|
+
This is an additive launch-config extension. Older launchers omit it. Older
|
|
179
|
+
runtimes reject unknown fields, so release the updated runtime and update the
|
|
180
|
+
CLI's exact runtime dependencies and signed catalog together before publishing
|
|
181
|
+
this launcher. Do not pair the updated launcher with a previously published
|
|
182
|
+
runtime and assume compatibility.
|
|
183
|
+
|
|
184
|
+
## Managed output delivery and business questions
|
|
185
|
+
|
|
186
|
+
Only `openyida.ask-human.v2` receipts are accepted. The CLI explicitly declares
|
|
187
|
+
bounded text attachments and freezes their bytes in the attempt's private
|
|
188
|
+
`.files` directory. Runtime verifies each snapshot and uploads it with device
|
|
189
|
+
authentication to `/api/local-runtime/v1/runs/{runId}/artifacts`, with bounded
|
|
190
|
+
base64url JSON metadata in `X-OpenYida-Output` and an octet-stream body.
|
|
191
|
+
Server-owned paths, digests and sizes are durably acknowledged in the attempt
|
|
192
|
+
journal before `question_opened`; local paths and file bytes never enter events.
|
|
193
|
+
No recursive directory sync or v1 receipt compatibility is implemented.
|
|
194
|
+
|
|
195
|
+
Question choices retain stable `value` separately from display labels; business
|
|
196
|
+
`contextRevision` is distinct from the integer interaction revision. Answers and
|
|
197
|
+
file references remain bound to the displayed question on continuation. The UI
|
|
198
|
+
uses the existing authenticated project-file reader and isolated HTML preview.
|
|
199
|
+
Permanent upload errors fail the turn; bounded transient retries remain cancellable.
|
|
200
|
+
Persisted ACKs/events can be replayed without executing business commands again.
|
|
201
|
+
An interrupted upload does not silently resume an unconfirmed provider execution.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Shared static help: no authentication, file access, or receipt creation.
|
|
4
|
+
const example = {
|
|
5
|
+
title: '确认搭建方案', revision: '<confirmation.revision>',
|
|
6
|
+
attachments: [{ name: '搭建方案.html', path: '<outputs.confirmationHtml>' }],
|
|
7
|
+
questions: [{ id: 'plan_decision', header: '搭建方案', question: '请确认当前搭建方案',
|
|
8
|
+
type: 'single_select', options: [
|
|
9
|
+
{ label: '确认并开始搭建', value: 'confirm_build' },
|
|
10
|
+
{ label: '继续调整', value: 'continue_editing' },
|
|
11
|
+
] }],
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
path: ['agent', 'ask-human'],
|
|
16
|
+
usage: 'openyida agent ask-human --request-key <稳定业务键> --questions-file <相对路径> --json',
|
|
17
|
+
description: '在宜搭云端发起的本地 Agent 任务中提交结构化问题并等待网页回答。',
|
|
18
|
+
examples: [JSON.stringify(example)],
|
|
19
|
+
};
|