@zq-silk/yui 2.1.0 → 2.2.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.
Files changed (102) hide show
  1. package/README.md +4 -0
  2. package/dist/cli/commandCatalog.js +24 -3
  3. package/dist/cli/commandDiscovery.js +4 -1
  4. package/dist/cli.js +23 -3078
  5. package/dist/commands/taskCommands.js +79 -21
  6. package/dist/commands/taskIntegrationCommands.js +3 -1
  7. package/dist/commands/taskUpstreamCommands.js +3 -1
  8. package/dist/context/runContextPack.js +132 -5
  9. package/dist/context/sourceRunContext.js +4 -2
  10. package/dist/context/taskContext.js +6 -1
  11. package/dist/controlPlaneCli.js +3092 -0
  12. package/dist/controller/fileSchedulerStoreAdapter.js +19 -6
  13. package/dist/controller/jobControl.js +21 -0
  14. package/dist/executor/agentExecutor.js +1 -1
  15. package/dist/executor/effectiveLaunch.js +18 -5
  16. package/dist/executor/fileRoleLaunchPlanner.js +15 -19
  17. package/dist/integration/gitIntegrationService.js +50 -15
  18. package/dist/message/messageContinuation.js +7 -2
  19. package/dist/nativeAgent/agent.js +176 -74
  20. package/dist/nativeAgent/cliDemo.js +37 -0
  21. package/dist/nativeAgent/codingTools.js +11 -0
  22. package/dist/nativeAgent/commandTool.js +215 -0
  23. package/dist/nativeAgent/compactionDemo.js +158 -0
  24. package/dist/nativeAgent/composition.js +71 -0
  25. package/dist/nativeAgent/context/budget.js +44 -0
  26. package/dist/nativeAgent/context/index.js +339 -0
  27. package/dist/nativeAgent/context/providerCompressor.js +103 -0
  28. package/dist/nativeAgent/demo.js +12 -1
  29. package/dist/nativeAgent/evaluation/cases.js +38 -0
  30. package/dist/nativeAgent/evaluation/checks.js +91 -0
  31. package/dist/nativeAgent/evaluation/demo.js +19 -0
  32. package/dist/nativeAgent/evaluation/files.js +54 -0
  33. package/dist/nativeAgent/evaluation/fixture.js +36 -0
  34. package/dist/nativeAgent/evaluation/index.js +239 -0
  35. package/dist/nativeAgent/executionOwner.js +209 -0
  36. package/dist/nativeAgent/filePatterns.js +170 -0
  37. package/dist/nativeAgent/fileToolsSupport.js +202 -0
  38. package/dist/nativeAgent/index.js +13 -0
  39. package/dist/nativeAgent/interaction/cli.js +358 -0
  40. package/dist/nativeAgent/interaction/contracts.js +1 -0
  41. package/dist/nativeAgent/interaction/index.js +3 -0
  42. package/dist/nativeAgent/interaction/memoryDemo.js +115 -0
  43. package/dist/nativeAgent/interaction/renderer.js +34 -0
  44. package/dist/nativeAgent/localSafety.js +258 -0
  45. package/dist/nativeAgent/model/anthropicMessages.js +204 -0
  46. package/dist/nativeAgent/model/chatCompletions.js +210 -0
  47. package/dist/nativeAgent/model/errors.js +47 -0
  48. package/dist/nativeAgent/model/gateway.js +423 -0
  49. package/dist/nativeAgent/model/index.js +7 -0
  50. package/dist/nativeAgent/model/observationAdapter.js +21 -0
  51. package/dist/nativeAgent/model/protocols.js +19 -0
  52. package/dist/nativeAgent/model/responses.js +263 -0
  53. package/dist/nativeAgent/model/types.js +1 -0
  54. package/dist/nativeAgent/model/wire.js +73 -0
  55. package/dist/nativeAgent/observability/index.js +220 -0
  56. package/dist/nativeAgent/product/catalog.js +82 -0
  57. package/dist/nativeAgent/product/config.js +295 -0
  58. package/dist/nativeAgent/product/facts.js +30 -0
  59. package/dist/nativeAgent/product/index.js +62 -0
  60. package/dist/nativeAgent/product/location.js +44 -0
  61. package/dist/nativeAgent/product/runtime.js +276 -0
  62. package/dist/nativeAgent/product/storage.js +49 -0
  63. package/dist/nativeAgent/product/tools.js +47 -0
  64. package/dist/nativeAgent/product/transport.js +54 -0
  65. package/dist/nativeAgent/projectGuidance/index.js +425 -0
  66. package/dist/nativeAgent/searchTools.js +305 -0
  67. package/dist/nativeAgent/session/backends.js +293 -0
  68. package/dist/nativeAgent/session/catalog.js +97 -0
  69. package/dist/nativeAgent/session/catalogDemo.js +87 -0
  70. package/dist/nativeAgent/session/contracts.js +1 -0
  71. package/dist/nativeAgent/session/format.js +269 -0
  72. package/dist/nativeAgent/session/index.js +5 -0
  73. package/dist/nativeAgent/session/location.js +36 -0
  74. package/dist/nativeAgent/session/sqliteFormat.js +134 -0
  75. package/dist/nativeAgent/session/store.js +248 -0
  76. package/dist/nativeAgent/textTools.js +270 -133
  77. package/dist/nativeAgent/toolManager/executor.js +290 -0
  78. package/dist/nativeAgent/toolManager/index.js +4 -0
  79. package/dist/nativeAgent/validation.js +2 -2
  80. package/dist/task/taskAuthority.js +56 -0
  81. package/dist/web/assets/client/app.js +64 -3
  82. package/dist/web/assets/client/detail.js +6 -6
  83. package/dist/web/assets/client/i18n.js +4 -0
  84. package/dist/web/assets/client/overview.js +12 -9
  85. package/dist/web/assets/client/sidebar.js +31 -2
  86. package/dist/web/assets/shell.js +2 -1
  87. package/dist/web/assets/styles/components.js +2 -0
  88. package/dist/web/assets/styles/layout.js +11 -4
  89. package/dist/web/assets/styles/responsive.js +12 -4
  90. package/dist/web/assets/styles/views.js +16 -13
  91. package/docs/agent-result-consumption.md +16 -0
  92. package/docs/agent-result-consumption.zh-CN.md +13 -0
  93. package/docs/examples/agent-offline.mjs +194 -0
  94. package/docs/native-agent.md +283 -0
  95. package/docs/release-workflow.md +47 -9
  96. package/docs/release-workflow.zh-CN.md +36 -6
  97. package/docs/roles-and-configuration.md +32 -0
  98. package/docs/roles-and-configuration.zh-CN.md +26 -0
  99. package/package.json +1 -1
  100. package/skills/yui-leader/SKILL.md +9 -0
  101. package/skills/yui-reviewer/SKILL.md +5 -0
  102. package/skills/yui-runtime/SKILL.md +7 -0
@@ -0,0 +1,248 @@
1
+ import { digest } from './backends.js';
2
+ import { copyEvent, identity, immutable, inspectDocument, revision, SessionError, sessionLimits } from './format.js';
3
+ import { metadataRevision, normalizeTitle, queryBounds } from './catalog.js';
4
+ import { copyLocation } from './location.js';
5
+ export class SessionSaveError extends SessionError {
6
+ sessionId;
7
+ expectedRevision;
8
+ event;
9
+ location;
10
+ /** Conservative: a thrown backend write is not proof that no commit occurred. */
11
+ effect = 'unknown';
12
+ constructor(sessionId, expectedRevision, event, cause, location) {
13
+ super('save_failed', 'Necessary Session save failed; stop new effects and inspect exact saved facts', { cause });
14
+ this.sessionId = sessionId;
15
+ this.expectedRevision = expectedRevision;
16
+ this.event = event;
17
+ this.location = location;
18
+ this.name = 'SessionSaveError';
19
+ }
20
+ }
21
+ export class SessionMetadataSaveError extends SessionError {
22
+ sessionId;
23
+ title;
24
+ expectedMetadataRevision;
25
+ effect = 'unknown';
26
+ constructor(sessionId, title, expectedMetadataRevision, cause) {
27
+ super('metadata_save_failed', 'Metadata save confirmation failed; inspect exact title/revision before another write', { cause });
28
+ this.sessionId = sessionId;
29
+ this.title = title;
30
+ this.expectedMetadataRevision = expectedMetadataRevision;
31
+ this.name = 'SessionMetadataSaveError';
32
+ }
33
+ }
34
+ export function createSessionStore(backend) {
35
+ identity(backend.source.id);
36
+ const source = immutable(structuredClone(backend.source));
37
+ if (!['volatile', 'persistent'].includes(source.durability)) {
38
+ throw new SessionError('invalid_backend', 'Backend must advertise its persistence boundary');
39
+ }
40
+ let closed = false;
41
+ let backendClosed = false;
42
+ const observers = new Set();
43
+ const check = () => { if (closed)
44
+ throw new SessionError('closed', 'Session store is closed'); };
45
+ const catalog = () => {
46
+ check();
47
+ if (!backend.catalog)
48
+ throw new SessionError('unsupported_catalog', 'Backend does not implement the bounded SessionCatalog port');
49
+ return backend.catalog;
50
+ };
51
+ const read = async (operation) => {
52
+ check();
53
+ try {
54
+ const value = await operation();
55
+ check();
56
+ return immutable(value);
57
+ }
58
+ catch (cause) {
59
+ if (cause instanceof SessionError)
60
+ throw cause;
61
+ throw new SessionError('read_failed', 'Session query failed; no empty-page fallback', { cause });
62
+ }
63
+ };
64
+ const receipt = (document) => immutable({
65
+ sessionId: document.sessionId, revision: revision(document), digest: digest(document), source,
66
+ });
67
+ const dispatch = (observer) => {
68
+ if (observer.busy || !observer.active || !observer.pending)
69
+ return;
70
+ observer.busy = true;
71
+ queueMicrotask(() => {
72
+ const next = observer.pending;
73
+ observer.pending = undefined;
74
+ if (!observer.active || !next) {
75
+ observer.busy = false;
76
+ return;
77
+ }
78
+ // An observer has at most one in-flight callback and one coalesced receipt.
79
+ // A hung UI never blocks a commit or creates an unbounded notification queue.
80
+ void Promise.resolve().then(() => {
81
+ if (observer.active)
82
+ return observer.callback(next);
83
+ }).catch(() => {
84
+ observer.active = false;
85
+ observers.delete(observer);
86
+ }).finally(() => {
87
+ observer.busy = false;
88
+ dispatch(observer);
89
+ });
90
+ });
91
+ };
92
+ const notify = (saved) => {
93
+ for (const observer of observers) {
94
+ if (observer.sessionId === saved.sessionId) {
95
+ observer.pending = saved;
96
+ dispatch(observer);
97
+ }
98
+ }
99
+ };
100
+ const save = async (document, expected, location) => {
101
+ check();
102
+ try {
103
+ if (location === undefined)
104
+ await backend.write(immutable(document), expected);
105
+ else
106
+ await backend.createWithLocation(immutable(document), location);
107
+ }
108
+ catch (cause) {
109
+ throw new SessionSaveError(document.sessionId, expected, document.events.at(-1), cause, location);
110
+ }
111
+ const saved = receipt(document);
112
+ notify(saved);
113
+ return saved;
114
+ };
115
+ const store = {
116
+ async listSessions(options = {}) { return read(() => catalog().listSessions(options)); },
117
+ async getSessionInfo(sessionId) {
118
+ identity(sessionId);
119
+ return read(() => catalog().getSessionInfo(sessionId));
120
+ },
121
+ async readHistory(sessionId, options = {}) {
122
+ identity(sessionId);
123
+ return read(() => catalog().readHistory(sessionId, options));
124
+ },
125
+ async renameSession(sessionId, title, expected) {
126
+ check();
127
+ identity(sessionId);
128
+ const normalized = normalizeTitle(title);
129
+ metadataRevision(expected);
130
+ const port = catalog();
131
+ try {
132
+ return immutable(await port.renameSession(sessionId, normalized, expected));
133
+ }
134
+ catch (cause) {
135
+ // These port errors are confirmed precondition refusals, not ambiguous saves.
136
+ if (cause instanceof SessionError && ['revision_conflict', 'not_found', 'closed'].includes(cause.code))
137
+ throw cause;
138
+ throw new SessionMetadataSaveError(sessionId, normalized, expected, cause);
139
+ }
140
+ },
141
+ async create(sessionId, location) {
142
+ check();
143
+ identity(sessionId);
144
+ const selected = location === undefined ? undefined : immutable(copyLocation(location));
145
+ if (selected !== undefined && (!backend.createWithLocation || !backend.catalog)) {
146
+ throw new SessionError('unsupported_location', 'Backend lacks atomic location creation and bounded detail reconciliation');
147
+ }
148
+ return save({ schemaVersion: 2, sessionId, events: [] }, null, selected);
149
+ },
150
+ async load(sessionId) {
151
+ check();
152
+ identity(sessionId);
153
+ const raw = await backend.read(sessionId);
154
+ check();
155
+ if (raw === null)
156
+ throw new SessionError('not_found', 'Session not found');
157
+ const state = inspectDocument(raw);
158
+ if (state.document.sessionId !== sessionId)
159
+ throw new SessionError('invalid_session', 'Backend returned another Session');
160
+ return immutable({ ...receipt(state.document), ...state });
161
+ },
162
+ async append(event, expectedRevision) {
163
+ check();
164
+ if (!Number.isSafeInteger(expectedRevision) || expectedRevision < 0) {
165
+ throw new SessionError('revision_conflict', 'Expected revision must be a nonnegative integer');
166
+ }
167
+ const next = copyEvent(event);
168
+ const previous = await store.load(next.sessionId);
169
+ if (previous.revision !== expectedRevision) {
170
+ throw new SessionError('revision_conflict', 'Session revision conflict; read current facts');
171
+ }
172
+ const state = inspectDocument({ ...previous.document, events: [...previous.document.events, next] });
173
+ return save(state.document, expectedRevision);
174
+ },
175
+ async query(sessionId, options = {}) {
176
+ const after = options.after ?? 0;
177
+ const limit = options.limit ?? 50;
178
+ queryBounds(after, limit);
179
+ if (backend.query) {
180
+ identity(sessionId);
181
+ return read(() => backend.query(sessionId, { after, limit }));
182
+ }
183
+ const loaded = await store.load(sessionId);
184
+ if (after > loaded.revision)
185
+ throw new SessionError('invalid_query', 'Cursor exceeds the saved revision');
186
+ const end = Math.min(after + limit, loaded.revision);
187
+ return immutable({ ...receipt(loaded.document),
188
+ records: loaded.document.events.slice(after, end).map((event, offset) => ({ revision: after + offset + 1, event })),
189
+ nextCursor: end < loaded.revision ? end : null,
190
+ });
191
+ },
192
+ subscribe(sessionId, callback) {
193
+ check();
194
+ identity(sessionId);
195
+ if (typeof callback !== 'function' || observers.size >= sessionLimits.subscribers) {
196
+ throw new SessionError('invalid_subscription', 'Expected observer within subscription limit');
197
+ }
198
+ const observer = { sessionId, callback, active: true, busy: false };
199
+ observers.add(observer);
200
+ return () => { observer.active = false; observer.pending = undefined; observers.delete(observer); };
201
+ },
202
+ async recorder(sessionId) {
203
+ const saved = await store.load(sessionId);
204
+ if (saved.recovery.disposition !== 'ready') {
205
+ throw new SessionError('recovery_required', 'Session requires explicit recovery; automatic replay is forbidden');
206
+ }
207
+ let lastReceipt = receipt(saved.document);
208
+ let failure;
209
+ let busy = false;
210
+ return {
211
+ get lastReceipt() { return lastReceipt; },
212
+ get failure() { return failure; },
213
+ async record(event) {
214
+ if (failure)
215
+ throw new SessionError('recorder_failed', 'Session recorder is stopped after failure', { cause: failure });
216
+ if (busy)
217
+ throw new SessionError('recorder_busy', 'Session recorder requires sequential facts');
218
+ busy = true;
219
+ try {
220
+ if (event.sessionId !== sessionId)
221
+ throw new SessionError('invalid_session', 'Recorder Session mismatch');
222
+ lastReceipt = await store.append(event, lastReceipt.revision);
223
+ }
224
+ catch (cause) {
225
+ failure = cause instanceof Error ? cause : new Error(String(cause));
226
+ throw failure;
227
+ }
228
+ finally {
229
+ busy = false;
230
+ }
231
+ },
232
+ };
233
+ },
234
+ async close() {
235
+ if (backendClosed)
236
+ return;
237
+ closed = true;
238
+ for (const observer of observers) {
239
+ observer.active = false;
240
+ observer.pending = undefined;
241
+ }
242
+ observers.clear();
243
+ await backend.close();
244
+ backendClosed = true;
245
+ },
246
+ };
247
+ return store;
248
+ }