agentlas 1.0.65 → 1.0.67

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 (163) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +12 -4
  3. package/bin/agentlas.cjs +354 -16
  4. package/engine/acp/server.cjs +34 -3
  5. package/engine/agentlas-api-agent.cjs +151 -120
  6. package/engine/agentlas-banner.cjs +6 -2
  7. package/engine/agentlas-capabilities.cjs +17 -10
  8. package/engine/agentlas-cloud-runtime.cjs +4 -5
  9. package/engine/agentlas-config.cjs +19 -54
  10. package/engine/agentlas-core-harness.cjs +59 -5
  11. package/engine/agentlas-desktop-loadout.cjs +17 -3
  12. package/engine/agentlas-evolution.cjs +75 -18
  13. package/engine/agentlas-experience-exchange.cjs +145 -14
  14. package/engine/agentlas-experience-intake.cjs +2 -2
  15. package/engine/agentlas-i18n.cjs +0 -2
  16. package/engine/agentlas-input.cjs +273 -20
  17. package/engine/agentlas-judgment.cjs +0 -0
  18. package/engine/agentlas-mcp-env.cjs +84 -23
  19. package/engine/agentlas-mcp-wrapper.cjs +36 -4
  20. package/engine/agentlas-memory-governance.cjs +2 -1
  21. package/engine/agentlas-memory-import.cjs +49 -12
  22. package/engine/agentlas-native-host.cjs +279 -44
  23. package/engine/agentlas-onboard.cjs +23 -1
  24. package/engine/agentlas-permissions.cjs +5 -1
  25. package/engine/agentlas-sqlite-policy.cjs +40 -2
  26. package/engine/agentlas-tasks.cjs +7 -0
  27. package/engine/agentlas-tools.cjs +37 -10
  28. package/engine/agentlas-ui.cjs +26 -4
  29. package/engine/agentlas-workforce.cjs +30 -5
  30. package/engine/agentlas-workload-routing.cjs +83 -10
  31. package/engine/agentlas.cjs +21 -4
  32. package/engine/agents/builder.cjs +35 -10
  33. package/engine/agents/files.cjs +81 -10
  34. package/engine/agents/import-local.cjs +10 -2
  35. package/engine/agents/registry.cjs +10 -3
  36. package/engine/agents/router.cjs +7 -7
  37. package/engine/agents/routes.cjs +31 -9
  38. package/engine/automation/daemon.cjs +154 -40
  39. package/engine/automation/launchd.cjs +395 -16
  40. package/engine/automation/schedule.cjs +90 -3
  41. package/engine/automation/store.cjs +163 -59
  42. package/engine/browser/cdp.cjs +190 -17
  43. package/engine/browser/vault.cjs +1 -0
  44. package/engine/cli-output.cjs +96 -30
  45. package/engine/cloud/auth.cjs +131 -13
  46. package/engine/cloud/hub-client.cjs +41 -16
  47. package/engine/cloud-assets/cas.cjs +18 -9
  48. package/engine/cloud-assets/commands.cjs +108 -30
  49. package/engine/cloud-assets/package.cjs +66 -3
  50. package/engine/cloud-assets/restore.cjs +12 -9
  51. package/engine/cloud-assets/state.cjs +609 -116
  52. package/engine/commands/acp.cjs +13 -2
  53. package/engine/commands/automation.cjs +75 -24
  54. package/engine/commands/billing.cjs +6 -1
  55. package/engine/commands/browser.cjs +61 -29
  56. package/engine/commands/build.cjs +72 -14
  57. package/engine/commands/call.cjs +1 -1
  58. package/engine/commands/cd.cjs +1 -1
  59. package/engine/commands/cloud.cjs +2 -1
  60. package/engine/commands/connect.cjs +38 -13
  61. package/engine/commands/creds.cjs +74 -29
  62. package/engine/commands/doctor.cjs +17 -1
  63. package/engine/commands/document.cjs +38 -10
  64. package/engine/commands/env.cjs +6 -1
  65. package/engine/commands/firm.cjs +42 -12
  66. package/engine/commands/graph.cjs +36 -32
  67. package/engine/commands/help.cjs +11 -1
  68. package/engine/commands/hep.cjs +1 -1
  69. package/engine/commands/import.cjs +5 -4
  70. package/engine/commands/index.cjs +1 -1
  71. package/engine/commands/install.cjs +6 -4
  72. package/engine/commands/list.cjs +56 -16
  73. package/engine/commands/login.cjs +5 -0
  74. package/engine/commands/logout.cjs +6 -1
  75. package/engine/commands/mcp.cjs +150 -37
  76. package/engine/commands/memory.cjs +3 -2
  77. package/engine/commands/multimodal.cjs +12 -0
  78. package/engine/commands/native.cjs +5 -1
  79. package/engine/commands/one.cjs +78 -33
  80. package/engine/commands/plugin.cjs +13 -2
  81. package/engine/commands/project.cjs +15 -12
  82. package/engine/commands/research.cjs +18 -7
  83. package/engine/commands/roles.cjs +104 -28
  84. package/engine/commands/route.cjs +2 -2
  85. package/engine/commands/run.cjs +42 -9
  86. package/engine/commands/search.cjs +23 -2
  87. package/engine/commands/setup.cjs +6 -1
  88. package/engine/commands/storm.cjs +44 -6
  89. package/engine/commands/swarm.cjs +47 -9
  90. package/engine/commands/telegram.cjs +6 -1
  91. package/engine/commands/uninstall.cjs +12 -6
  92. package/engine/commands/update.cjs +5 -0
  93. package/engine/commands/upload.cjs +2 -1
  94. package/engine/commands/usage.cjs +6 -1
  95. package/engine/commands/version.cjs +6 -1
  96. package/engine/commands/whoami.cjs +6 -1
  97. package/engine/commands/workforce.cjs +60 -16
  98. package/engine/core/capability-grants.cjs +7 -2
  99. package/engine/core/daemon-client.cjs +36 -7
  100. package/engine/core/db.cjs +10 -2
  101. package/engine/core/desktop-core-fetch.cjs +477 -77
  102. package/engine/core/schema-ensure.cjs +23 -11
  103. package/engine/experience/build.cjs +5 -1
  104. package/engine/experience/intents.cjs +35 -82
  105. package/engine/experience/runtime.cjs +7 -1
  106. package/engine/experience/variant.cjs +58 -4
  107. package/engine/firms/orchestrate.cjs +9 -6
  108. package/engine/graph/ask-model.cjs +22 -11
  109. package/engine/graph/interview.cjs +74 -23
  110. package/engine/graph/package.cjs +63 -8
  111. package/engine/hephaestus/local-core.cjs +18 -5
  112. package/engine/hephaestus/runtime.cjs +48 -43
  113. package/engine/hub/install.cjs +484 -63
  114. package/engine/hub/plugins.cjs +391 -29
  115. package/engine/mcp/consent.cjs +25 -17
  116. package/engine/mcp/contract.cjs +229 -24
  117. package/engine/mcp/inventory.cjs +46 -10
  118. package/engine/mcp/plan.cjs +10 -1
  119. package/engine/mcp/probe.cjs +24 -9
  120. package/engine/memory-cli/curate.cjs +74 -16
  121. package/engine/oberon/common.cjs +37 -12
  122. package/engine/oberon/manifest.cjs +25 -2
  123. package/engine/oberon/outputs.cjs +49 -19
  124. package/engine/oberon/render.cjs +665 -40
  125. package/engine/project/career-graph.cjs +15 -2
  126. package/engine/project/controller.cjs +133 -15
  127. package/engine/project/credentials.cjs +382 -34
  128. package/engine/project/env-file.cjs +93 -8
  129. package/engine/project/memory-context.cjs +11 -57
  130. package/engine/project/ontology.cjs +66 -25
  131. package/engine/project/paths.cjs +42 -8
  132. package/engine/project/seed.cjs +88 -51
  133. package/engine/project/state.cjs +41 -16
  134. package/engine/project/team.cjs +26 -1
  135. package/engine/runtime-refusal.cjs +4 -1
  136. package/engine/runtimes/acp-driver.cjs +56 -9
  137. package/engine/runtimes/auth-evidence.cjs +21 -2
  138. package/engine/runtimes/detect.cjs +28 -8
  139. package/engine/runtimes/kinds.cjs +12 -4
  140. package/engine/runtimes/overrides.cjs +4 -3
  141. package/engine/runtimes/resolve.cjs +8 -7
  142. package/engine/runtimes/roles.cjs +7 -5
  143. package/engine/sessions/apply-fences.cjs +396 -56
  144. package/engine/sessions/fences.cjs +111 -27
  145. package/engine/sessions/memory-turn.cjs +62 -3
  146. package/engine/sessions/orchestrator.cjs +11 -1
  147. package/engine/sessions/prompt.cjs +66 -9
  148. package/engine/sessions/session.cjs +70 -10
  149. package/engine/sessions/sink.cjs +78 -12
  150. package/engine/sessions/store.cjs +29 -7
  151. package/engine/storm/storm.cjs +26 -3
  152. package/engine/storm/swarm.cjs +31 -3
  153. package/engine/telegram/connect.cjs +185 -22
  154. package/engine/ui/commands-catalog.cjs +1 -1
  155. package/engine/ui/palette.cjs +12 -2
  156. package/engine/ui/repl.cjs +57 -9
  157. package/engine/ui/screens.cjs +2 -4
  158. package/engine/vendor/desktop-core.manifest.json +5 -5
  159. package/engine/workforce/capture.cjs +9 -27
  160. package/engine/workforce/deps.cjs +18 -6
  161. package/engine/workforce/local-core-transport.cjs +68 -5
  162. package/package.json +1 -1
  163. package/engine/commands/career-graph.cjs +0 -51
@@ -21,22 +21,47 @@ function fail(msg, code) {
21
21
  throw new OberonFail(String(msg ?? ""), code);
22
22
  }
23
23
 
24
- // v1 oberonParseFlags 그대로: `--key value` / `--key`(불리언) / 나머지는 위치 인자.
25
- // 다음 토큰이 `--`로 시작하면 값이 아니라 다른 플래그로 본다.
26
- function parseFlags(args) {
24
+ // 타입 스키마가 있으면 없는/중복/값 누락 플래그를 fail-closed 한다.
25
+ // `--key=value`와 위치 인자용 `--` sentinel도 지원한다.
26
+ function parseFlags(args, schema = null) {
27
27
  const flags = {};
28
28
  const rest = [];
29
29
  for (let i = 0; i < args.length; i++) {
30
- const a = args[i];
31
- if (a.startsWith("--")) {
32
- const key = a.slice(2);
30
+ const a = String(args[i]);
31
+ if (a === "--") {
32
+ rest.push(...args.slice(i + 1).map(String));
33
+ break;
34
+ }
35
+ if (!a.startsWith("--")) { rest.push(a); continue; }
36
+ const equals = a.indexOf("=");
37
+ const key = a.slice(2, equals >= 0 ? equals : undefined);
38
+ const inlineValue = equals >= 0 ? a.slice(equals + 1) : null;
39
+ if (!key) fail("Oberon option name is empty");
40
+ if (Object.prototype.hasOwnProperty.call(flags, key)) fail(`Duplicate Oberon option: --${key}`);
41
+ const type = schema && schema[key];
42
+ if (schema && !type) fail(`Unknown Oberon option: --${key}`);
43
+ if (!schema) {
33
44
  const next = args[i + 1];
34
- if (next === undefined || next.startsWith("--")) flags[key] = true;
35
- else {
36
- flags[key] = next;
37
- i++;
38
- }
39
- } else rest.push(a);
45
+ if (inlineValue != null) flags[key] = inlineValue;
46
+ else if (next === undefined || String(next).startsWith("--")) flags[key] = true;
47
+ else { flags[key] = String(next); i += 1; }
48
+ continue;
49
+ }
50
+ if (type === "boolean") {
51
+ if (inlineValue != null) fail(`Boolean Oberon option does not take a value: --${key}`);
52
+ flags[key] = true;
53
+ continue;
54
+ }
55
+ if (type !== "value") fail(`Invalid Oberon option schema: --${key}`);
56
+ if (inlineValue != null) {
57
+ if (!inlineValue) fail(`Oberon option requires a value: --${key}`);
58
+ flags[key] = inlineValue;
59
+ continue;
60
+ }
61
+ const next = args[i + 1];
62
+ if (next === undefined || String(next).startsWith("--")) fail(`Oberon option requires a value: --${key}`);
63
+ flags[key] = String(next);
64
+ i += 1;
40
65
  }
41
66
  return { flags, rest };
42
67
  }
@@ -130,12 +130,35 @@ function buildScaffoldManifest({ title, aspect, shotCount, provider, model, reso
130
130
 
131
131
  // `oberon scaffold [out.json] [--title T] [--aspect 16:9] [--shots N] [--titles] [--overwrite]`
132
132
  function scaffold(io, args) {
133
- const { flags, rest } = parseFlags(args);
133
+ const { flags, rest } = parseFlags(args, {
134
+ title: "value",
135
+ aspect: "value",
136
+ shots: "value",
137
+ provider: "value",
138
+ model: "value",
139
+ resolution: "value",
140
+ titles: "boolean",
141
+ overwrite: "boolean",
142
+ });
143
+ if (rest.length > 1) fail("Oberon scaffold accepts at most one output path");
134
144
  const outPath = path.resolve(rest[0] || "oberon-manifest.json");
135
145
  const title = flags.title || "My Oberon Film";
136
146
  const aspect = flags.aspect || "16:9";
147
+ for (const [label, value, max] of [
148
+ ["title", title, 300],
149
+ ["aspect", aspect, 32],
150
+ ["provider", flags.provider || "google-gemini-veo", 128],
151
+ ["model", flags.model || "veo-3.1-lite-generate-001", 128],
152
+ ["resolution", flags.resolution || "720p", 32],
153
+ ]) {
154
+ if (typeof value !== "string" || !value.trim() || value.length > max || /[\u0000\r\n]/.test(value)) {
155
+ fail(`Oberon ${label} is invalid`);
156
+ }
157
+ }
137
158
  // v1 계약: 샷 수는 1..12로 클램프, 기본 2 (Veo 폴링 비용 상한).
138
- const shotCount = Math.max(1, Math.min(Number(flags.shots) || 2, 12));
159
+ const requestedShots = flags.shots === undefined ? 2 : Number(flags.shots);
160
+ if (!Number.isInteger(requestedShots)) fail("Oberon --shots must be an integer");
161
+ const shotCount = Math.max(1, Math.min(requestedShots, 12));
139
162
  const manifest = buildScaffoldManifest({
140
163
  title,
141
164
  aspect,
@@ -10,6 +10,28 @@ const { spawnSync } = require("node:child_process");
10
10
  const { userDataDir } = require("../core/paths.cjs");
11
11
  const { fail } = require("./common.cjs");
12
12
 
13
+ const MAX_RENDER_DIRECTORIES = 4096;
14
+ const MAX_FILES_PER_RENDER = 4096;
15
+
16
+ function terminalSafe(value, maxLength = 240) {
17
+ return String(value ?? "").replace(/[\u0000-\u001f\u007f]/g, "�").slice(0, maxLength);
18
+ }
19
+
20
+ function readDirectoryBounded(dir, maxEntries, label) {
21
+ const handle = fs.opendirSync(dir);
22
+ const entries = [];
23
+ try {
24
+ while (entries.length <= maxEntries) {
25
+ const entry = handle.readSync();
26
+ if (!entry) return entries;
27
+ entries.push(entry);
28
+ }
29
+ } finally {
30
+ handle.closeSync();
31
+ }
32
+ fail(`${label} contains more than ${maxEntries} entries; narrow or clean the output directory first`);
33
+ }
34
+
13
35
  function oberonHome() {
14
36
  return path.join(userDataDir(), "oberon");
15
37
  }
@@ -17,41 +39,48 @@ function oberonHome() {
17
39
  // `oberon list` — 최근 렌더 산출물 15개 (mtime 내림차순).
18
40
  function list(io) {
19
41
  const dir = oberonHome();
20
- if (!fs.existsSync(dir)) {
42
+ let homeStat;
43
+ try { homeStat = fs.lstatSync(dir); } catch (error) {
44
+ if (!error || error.code !== "ENOENT") throw error;
21
45
  io.out("No render outputs yet. Start with agentlas oberon scaffold my.json.");
22
46
  return 0;
23
47
  }
24
- const entries = fs
25
- .readdirSync(dir, { withFileTypes: true })
48
+ if (!homeStat.isDirectory() || homeStat.isSymbolicLink()) fail(`Oberon output home must be a regular directory, not a symbolic link: ${terminalSafe(dir)}`);
49
+ const entries = readDirectoryBounded(dir, MAX_RENDER_DIRECTORIES, "Oberon output home")
26
50
  .filter((d) => d.isDirectory())
27
51
  .map((d) => {
28
52
  const full = path.join(dir, d.name);
29
53
  let mtime = 0;
30
54
  try {
31
- mtime = fs.statSync(full).mtimeMs;
55
+ const stat = fs.lstatSync(full);
56
+ if (!stat.isDirectory() || stat.isSymbolicLink()) return null;
57
+ mtime = stat.mtimeMs;
32
58
  } catch {}
33
- const files = (() => {
34
- try {
35
- return fs.readdirSync(full);
36
- } catch {
37
- return [];
38
- }
39
- })();
40
- return { name: d.name, full, mtime, files };
59
+ return { name: d.name, full, mtime };
41
60
  })
61
+ .filter(Boolean)
42
62
  .sort((a, b) => b.mtime - a.mtime)
43
- .slice(0, 15);
63
+ .slice(0, 15)
64
+ .map((entry) => {
65
+ let files = [];
66
+ try {
67
+ files = readDirectoryBounded(entry.full, MAX_FILES_PER_RENDER, `Oberon render ${terminalSafe(entry.name)}`).map((file) => file.name);
68
+ } catch (error) {
69
+ if (error && error.oberonFail) throw error;
70
+ }
71
+ return { ...entry, files };
72
+ });
44
73
  if (!entries.length) {
45
74
  io.out("No render outputs yet.");
46
75
  return 0;
47
76
  }
48
- io.out(`Recent Oberon renders (${dir}):\n`);
77
+ io.out(`Recent Oberon renders (${terminalSafe(dir, 4096)}):\n`);
49
78
  for (const e of entries) {
50
79
  // master/titled 최종본만 요약에 노출 (중간 클립·로그 숨김) — v1 필터 그대로.
51
80
  const masters = e.files.filter((f) => /master|titled/.test(f) && /\.(mp4|mov)$/.test(f));
52
81
  const when = e.mtime ? new Date(e.mtime).toISOString().slice(0, 16).replace("T", " ") : "";
53
- io.out(` ${when} ${e.name}`);
54
- if (masters.length) io.out(` ${masters.join(", ")}`);
82
+ io.out(` ${when} ${terminalSafe(e.name)}`);
83
+ if (masters.length) io.out(` ${masters.map((name) => terminalSafe(name)).join(", ")}`);
55
84
  }
56
85
  io.out(`\nOpen the folder with: agentlas oberon open`);
57
86
  return 0;
@@ -59,6 +88,7 @@ function list(io) {
59
88
 
60
89
  // `oberon open [path]` — 산출물 폴더를 OS 파일 매니저로 연다.
61
90
  function open(io, args, options = {}) {
91
+ if (args.length > 1) fail("Oberon open accepts at most one path");
62
92
  const target = args[0] ? path.resolve(args[0]) : oberonHome();
63
93
  if (!fs.existsSync(target)) fail(`Path not found: ${target}`);
64
94
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "explorer" : "xdg-open";
@@ -68,9 +98,9 @@ function open(io, args, options = {}) {
68
98
  // launch result and only claim success on exit 0.
69
99
  const launch = options.spawnSyncImpl || spawnSync;
70
100
  const result = launch(opener, [target], { stdio: "ignore", windowsHide: true });
71
- if (result && result.error) fail(`Could not open ${target}: ${result.error.message}`);
72
- if (!result || result.status !== 0) fail(`Could not open ${target} (opener exit ${result && result.status != null ? result.status : "unknown"})`);
73
- io.out(`Opening folder: ${target}`);
101
+ if (result && result.error) fail(`Could not open ${terminalSafe(target, 4096)}: ${terminalSafe(result.error.message)}`);
102
+ if (!result || result.status !== 0) fail(`Could not open ${terminalSafe(target, 4096)} (opener exit ${result && result.status != null ? result.status : "unknown"})`);
103
+ io.out(`Opening folder: ${terminalSafe(target, 4096)}`);
74
104
  return 0;
75
105
  }
76
106