ai-project-manage-cli 7.0.5 → 7.0.7

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/dist/index.js CHANGED
@@ -177,20 +177,6 @@ function isWorkspaceApmInitialized(workdir) {
177
177
  }
178
178
  return readdirSync(fsApmDir).length > 0;
179
179
  }
180
- function assertWorkspaceApmDirExists(workdir) {
181
- if (!isWorkspaceApmInitialized(workdir)) {
182
- const apmDir = workspaceApmDir(workdir);
183
- const fsApmDir = toFsPath(apmDir);
184
- if (!existsSync2(fsApmDir)) {
185
- throw new Error(
186
- `\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u4E0B\u672A\u68C0\u6D4B\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5728\u8BE5\u4ED3\u5E93\u6839\u76EE\u5F55\u6267\u884C apm init \u5B8C\u6210\u63A5\u5165\u3002`
187
- );
188
- }
189
- throw new Error(
190
- `\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u4E0B .apm \u76EE\u5F55\u4E3A\u7A7A\uFF0C\u8BF7\u5728\u8BE5\u4ED3\u5E93\u6839\u76EE\u5F55\u6267\u884C apm init \u5B8C\u6210\u63A5\u5165\u3002`
191
- );
192
- }
193
- }
194
180
  var APM_GITIGNORE_PATTERNS = [
195
181
  /^\.apm\/?$/,
196
182
  /^\.apm\/\*\*$/,
@@ -1867,6 +1853,61 @@ function saveMemberPlanDocument(input) {
1867
1853
  }
1868
1854
 
1869
1855
  // src/event-session.ts
1856
+ var MAX_TOOL_CALL_RESULT_BYTES = 1024 * 1024;
1857
+ function utf8ByteLength(text) {
1858
+ return Buffer.byteLength(text, "utf8");
1859
+ }
1860
+ function truncateUtf8ByBytes(text, maxBytes) {
1861
+ if (maxBytes <= 0) {
1862
+ return "";
1863
+ }
1864
+ if (utf8ByteLength(text) <= maxBytes) {
1865
+ return text;
1866
+ }
1867
+ let end = 0;
1868
+ for (let index = 0; index < text.length; index += 1) {
1869
+ if (utf8ByteLength(text.slice(0, index + 1)) > maxBytes) {
1870
+ break;
1871
+ }
1872
+ end = index + 1;
1873
+ }
1874
+ return text.slice(0, end);
1875
+ }
1876
+ function serializeToolCallResult(result) {
1877
+ return typeof result === "string" ? result : JSON.stringify(result);
1878
+ }
1879
+ function truncateToolCallResult(result) {
1880
+ if (result === void 0 || result === null) {
1881
+ return result;
1882
+ }
1883
+ const originalText = serializeToolCallResult(result);
1884
+ const originalBytes = utf8ByteLength(originalText);
1885
+ if (originalBytes <= MAX_TOOL_CALL_RESULT_BYTES) {
1886
+ return result;
1887
+ }
1888
+ const meta = {
1889
+ _apmTruncated: true,
1890
+ _apmOriginalBytes: originalBytes,
1891
+ _apmMaxBytes: MAX_TOOL_CALL_RESULT_BYTES,
1892
+ _apmMessage: "tool_call result \u8D85\u8FC7\u5E73\u53F0\u540C\u6B65\u5927\u5C0F\u4E0A\u9650\uFF0C\u4EE5\u4E0B\u5185\u5BB9\u5DF2\u622A\u65AD\uFF1B\u5B8C\u6574\u7ED3\u679C\u4EC5\u4FDD\u7559\u5728\u672C\u5730 Cursor \u8FD0\u884C\u4E2D\u3002"
1893
+ };
1894
+ let low = 0;
1895
+ let high = originalBytes;
1896
+ let content = "";
1897
+ while (low <= high) {
1898
+ const mid = Math.floor((low + high) / 2);
1899
+ const candidateContent = truncateUtf8ByBytes(originalText, mid);
1900
+ const candidate = { ...meta, content: candidateContent };
1901
+ const candidateBytes = utf8ByteLength(JSON.stringify(candidate));
1902
+ if (candidateBytes <= MAX_TOOL_CALL_RESULT_BYTES) {
1903
+ content = candidateContent;
1904
+ low = mid + 1;
1905
+ } else {
1906
+ high = mid - 1;
1907
+ }
1908
+ }
1909
+ return { ...meta, content };
1910
+ }
1870
1911
  var EventSession = class {
1871
1912
  events = [];
1872
1913
  dirtyIndices = /* @__PURE__ */ new Set();
@@ -1952,7 +1993,7 @@ var EventSession = class {
1952
1993
  return {
1953
1994
  type: "tool_call",
1954
1995
  args: event.args,
1955
- result: event.result,
1996
+ result: truncateToolCallResult(event.result),
1956
1997
  status: event.status,
1957
1998
  call_id: event.call_id,
1958
1999
  name: event.name
@@ -1972,15 +2013,26 @@ var EventSession = class {
1972
2013
  return { type: "status", status: event.status, message: event.message };
1973
2014
  }
1974
2015
  }
2016
+ getDirtyIndices() {
2017
+ return [...this.dirtyIndices].sort((a, b) => a - b);
2018
+ }
2019
+ /** 按 index 读取待同步 event(上传时取最新内容,避免 snapshot 过期)。 */
2020
+ getSyncEvent(index) {
2021
+ if (!this.dirtyIndices.has(index)) {
2022
+ return null;
2023
+ }
2024
+ const event = this.events[index];
2025
+ if (!event) {
2026
+ return null;
2027
+ }
2028
+ return {
2029
+ index,
2030
+ type: event.type,
2031
+ data: JSON.stringify(event)
2032
+ };
2033
+ }
1975
2034
  getDirtyEvents() {
1976
- return [...this.dirtyIndices].sort((a, b) => a - b).map((index) => {
1977
- const event = this.events[index];
1978
- return {
1979
- index,
1980
- type: event.type,
1981
- data: JSON.stringify(event)
1982
- };
1983
- });
2035
+ return this.getDirtyIndices().map((index) => this.getSyncEvent(index)).filter((event) => event !== null);
1984
2036
  }
1985
2037
  clearDirty(indices) {
1986
2038
  for (const index of indices) {
@@ -2246,22 +2298,20 @@ function createThrottledCursorLogSync(cfg, ctx, onError) {
2246
2298
  let timer;
2247
2299
  let latestSession;
2248
2300
  let syncChain = Promise.resolve();
2249
- const syncDirtyEventsOnce = async (session) => {
2250
- const events = session.getDirtyEvents();
2251
- if (events.length === 0) {
2252
- return;
2253
- }
2254
- lastRunAt = Date.now();
2255
- try {
2256
- await syncCursorLog(cfg, ctx, events);
2257
- session.clearDirty(events.map((event) => event.index));
2258
- } catch (err) {
2259
- onError(err);
2260
- }
2261
- };
2262
2301
  const drainDirtyEvents = async (session) => {
2263
- while (session.getDirtyEvents().length > 0) {
2264
- await syncDirtyEventsOnce(session);
2302
+ const pendingIndices = session.getDirtyIndices();
2303
+ for (const index of pendingIndices) {
2304
+ const event = session.getSyncEvent(index);
2305
+ if (!event) {
2306
+ continue;
2307
+ }
2308
+ lastRunAt = Date.now();
2309
+ try {
2310
+ await syncCursorLog(cfg, ctx, event);
2311
+ session.clearDirty([index]);
2312
+ } catch (err) {
2313
+ onError(err);
2314
+ }
2265
2315
  }
2266
2316
  };
2267
2317
  const enqueueSync = (session) => {
@@ -2299,9 +2349,9 @@ function createThrottledCursorLogSync(cfg, ctx, onError) {
2299
2349
  }
2300
2350
  };
2301
2351
  }
2302
- async function syncCursorLog(cfg, ctx, events) {
2352
+ async function syncCursorLog(cfg, ctx, event) {
2303
2353
  const agentId = ctx.agentId.trim();
2304
- if (!agentId || events.length === 0) {
2354
+ if (!agentId) {
2305
2355
  return;
2306
2356
  }
2307
2357
  const api = createApmApiClient(cfg);
@@ -2309,7 +2359,7 @@ async function syncCursorLog(cfg, ctx, events) {
2309
2359
  taskId: ctx.taskId,
2310
2360
  mailboxMessageId: ctx.mailboxMessageId,
2311
2361
  agentId,
2312
- events
2362
+ events: [event]
2313
2363
  });
2314
2364
  }
2315
2365
 
@@ -2706,7 +2756,7 @@ async function syncPlatformRules(cfg, workdirPath, apmRoot) {
2706
2756
  // src/commands/connect/task-pull.ts
2707
2757
  async function runTaskPull(cfg, detail) {
2708
2758
  const { taskId, workdir } = detail;
2709
- assertWorkspaceApmDirExists(workdir);
2759
+ await ensureWorkspaceInitialized(workdir);
2710
2760
  const apmRoot = workspaceApmDir(workdir);
2711
2761
  const dir = taskDir(taskId, apmRoot, workdir);
2712
2762
  const docsDir = taskDocsDir(taskId, apmRoot, workdir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "7.0.5",
3
+ "version": "7.0.7",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,8 +0,0 @@
1
- ## 前端产物下载地址
2
-
3
- http://<服务器地址>/dist.zip
4
- http://<服务器地址>/{name}.jar.zip
5
-
6
- ## 测试地址
7
-
8
- http://<服务器地址>