agentlas 1.0.59 → 1.0.60

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.
@@ -972,6 +972,37 @@ async function newGraph(ctx, request, flags) {
972
972
  }
973
973
  }
974
974
 
975
+ /*
976
+ * ★저장하기 **전에** 싼 단계를 실제로 돌려 본다.
977
+ * 빌더가 쓴 스크립트는 한 번도 돌아 본 적이 없다 — 실측 2026-08-20: 새로 만든 환율
978
+ * 자동화의 첫 단계가 자료원에서 403 을 받고 죽었고, 사람은 며칠 뒤 예약 실행에서야
979
+ * 알게 된다. code 단계 실행은 실측 0.0~0.1초라 사람이 못 느낀다.
980
+ * ★에러코드를 늘어놓지 않는다 — 고칠 수 있으면 조용히 고치고, 안 되면 사람 말로 한 줄.
981
+ */
982
+ const core = await acquireCore(ctx);
983
+ const verifier = core && core.verifyBeforeSave;
984
+ if (verifier && typeof verifier.run === "function") {
985
+ try {
986
+ const seen = await verifier.run(built.graph);
987
+ for (const step of seen.steps || []) {
988
+ if (step.state === "repaired" && step.repairedCode) {
989
+ const node = built.graph.nodes.find((n) => n.id === step.nodeId);
990
+ if (node && node.config) node.config.code = step.repairedCode;
991
+ }
992
+ }
993
+ for (const line of verifier.render(seen)) ctx.out(ctx.ui.dim(line));
994
+ } catch (verifyError) {
995
+ /*
996
+ * ★확인하지 못한 것은 실패가 아니므로 저장은 막지 않는다. 다만 **조용히 삼키지도
997
+ * 않는다** — 실측 2026-08-20: 이 자리의 첫 판이 오타 하나로 매번 던졌는데,
998
+ * 빈 catch 가 그것을 통째로 먹어 "검증이 통과한 것"과 구분되지 않았다.
999
+ * 확인을 못 했으면 못 했다고 말한다.
1000
+ */
1001
+ ctx.err(ctx.ui.dim(en
1002
+ ? `Could not check the steps before saving: ${verifyError && verifyError.message}`
1003
+ : `저장 전 단계 확인을 하지 못했습니다: ${verifyError && verifyError.message}`));
1004
+ }
1005
+ }
975
1006
  // 이름이 겹치면 덮어쓰지 않는다.
976
1007
  const existing = graphRows(ctx, db).find((row) => row.name === bp.name);
977
1008
  const name = existing ? `${bp.name} (2)` : bp.name;
@@ -231,6 +231,18 @@ function loadDesktopCore(options = {}) {
231
231
  initStore: req("store/db").initStore,
232
232
  getDb: req("store/db").getDb,
233
233
  runGraph: kernel.runGraph,
234
+ /*
235
+ * 저장 전 확인 — 빌더가 만든 스크립트를 **저장하기 전에** 돌려 보고, 안 되면 한 번
236
+ * 고친다. 옛 코어에는 없으므로 정직하게 null 로 둔다(부르는 쪽이 없으면 건너뛴다).
237
+ */
238
+ verifyBeforeSave: (() => {
239
+ try {
240
+ const mod = req("workflow/verify-before-save");
241
+ return typeof mod.verifyGraphBeforeSaveWithKernel === "function"
242
+ ? { run: mod.verifyGraphBeforeSaveWithKernel, render: mod.renderPreSaveVerification }
243
+ : null;
244
+ } catch { return null; }
245
+ })(),
234
246
  getAutomation: req("store/automations").getAutomation,
235
247
  // shared/ 는 electron/ 밖이라 req 로 못 닿는다 — 직접 해석한다.
236
248
  graphExecutionDigest: (() => {
@@ -50,6 +50,23 @@ function quietSink() {
50
50
  * @returns {Promise<{ok:true,text:string,runtime:string,fellBackFrom?:string}
51
51
  * |{ok:false,reason:string,nextAction:string}>}
52
52
  */
53
+ /**
54
+ * 이 컴퓨터에서 **이미 동의된** MCP 서버들. 빌더도 실행기와 같은 재료를 본다.
55
+ *
56
+ * 새 동의를 받지 않는다 — 만드는 중에 승인 창을 띄우면 사람이 흐름에서 튕긴다.
57
+ * 못 읽으면 빈 배열: 예전 동작과 같아질 뿐 나빠지지 않는다(조용한 실패가 아니라
58
+ * "없는 것"이 사실이다).
59
+ */
60
+ function consentedMcpServersFor(ctx) {
61
+ try {
62
+ const mcp = require("../mcp/index.cjs");
63
+ if (typeof mcp.readConsentedSystemMcpServers !== "function") return [];
64
+ return mcp.readConsentedSystemMcpServers(ctx.db(), { env: process.env }) || [];
65
+ } catch {
66
+ return [];
67
+ }
68
+ }
69
+
53
70
  async function askModel(ctx, prompt, opts = {}) {
54
71
  const db = ctx.db();
55
72
  let primary = null;
@@ -103,12 +120,27 @@ async function askModel(ctx, prompt, opts = {}) {
103
120
  ui: quietSink(),
104
121
  cwd: opts.cwd || process.cwd(),
105
122
  prompt,
106
- // 읽기 권한 — 인터뷰는 사람에게 묻고 형식을 만드는 일이라 파일을 바꿀 이유가 없다.
123
+ /*
124
+ * 읽기 권한 — 만드는 동안 바깥을 바꾸지 않는다. 메일이 나가거나 글이 올라가면 안 된다.
125
+ * ★런타임의 "read"는 **쓰기 금지가 아니라 도구 금지에 가깝다**(이 저장소 실측:
126
+ * 조회 그래프가 조회조차 못 했던 사고). 조회 도구는 남으므로 확인은 할 수 있다.
127
+ */
107
128
  permission: "read",
108
129
  session: {},
109
130
  model: runtime.model,
110
131
  effort: runtime.effort,
111
- mcpServers: [],
132
+ /*
133
+ * ★사용자가 **이미 동의한** MCP 를 빌더에게도 준다.
134
+ *
135
+ * 실측 2026-08-20: 여기가 빈 배열이었다. 그래서 빌더는 이 컴퓨터에 무엇이
136
+ * 연결돼 있는지 모른 채 그래프를 지었고, 자기가 쓴 스크립트가 도는지도 볼 수
137
+ * 없었다. 도구는 제품에 다 있는데(브라우저·MCP·크리덴셜) **만드는 자리에만
138
+ * 안 닿아 있었다.**
139
+ *
140
+ * 새로 동의를 받지 않는다 — 이미 받아 둔 것만 그대로 쓴다(consent 영수증 기준).
141
+ * 못 읽으면 빈 배열로 간다: 예전과 같아질 뿐 나빠지지 않는다.
142
+ */
143
+ mcpServers: consentedMcpServersFor(ctx),
112
144
  mcpAllowlistMode: "exact",
113
145
  });
114
146
  } catch (err) {
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "11",
3
- "url": "https://github.com/agentlas-ai/agentlas-terminal/releases/download/desktop-core-v11/desktop-core.tar.gz",
4
- "sha256": "c68cddd2cd4ee6978903a7a1bea39fbdce218c1dcbaa74165231ea99bbd1999e",
5
- "sizeBytes": 12557470,
6
- "writtenAt": "2026-08-19T22:35:51.167Z"
2
+ "version": "12",
3
+ "url": "https://github.com/agentlas-ai/agentlas-terminal/releases/download/desktop-core-v12/desktop-core.tar.gz",
4
+ "sha256": "cc2ad07bd7695a9dcee4e61f7eb1f65ea86454caf79a6e449e5afb10d3ff8150",
5
+ "sizeBytes": 12563495,
6
+ "writtenAt": "2026-08-19T23:39:35.152Z"
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentlas",
3
- "version": "1.0.59",
3
+ "version": "1.0.60",
4
4
  "description": "Agentlas project terminal — run project controllers and task-scoped agent teams from the terminal. Standalone: no desktop app process required.",
5
5
  "bin": {
6
6
  "agentlas": "bin/agentlas.cjs"