newmark-agent 0.3.11 → 0.4.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 (69) hide show
  1. package/config.example.json +6 -0
  2. package/dist/cli-commands.d.ts +8 -0
  3. package/dist/cli-commands.js +216 -16
  4. package/dist/cli-discovery.d.ts +15 -0
  5. package/dist/cli-discovery.js +182 -0
  6. package/dist/cli-help.d.ts +2 -0
  7. package/dist/cli-help.js +25 -1
  8. package/dist/context/domain/types.d.ts +37 -0
  9. package/dist/context/services/context-orchestrator.js +2 -0
  10. package/dist/conversation-utility-host.bundle.cjs +1503 -214
  11. package/dist/conversation-utility-host.js +3 -0
  12. package/dist/core/agent.d.ts +157 -8
  13. package/dist/core/agent.js +1176 -112
  14. package/dist/core/agentKernel/agent-loop.js +29 -3
  15. package/dist/core/agentKernel/types.d.ts +7 -0
  16. package/dist/core/agentKernelRunner.d.ts +2 -0
  17. package/dist/core/agentKernelRunner.js +174 -27
  18. package/dist/core/config.d.ts +7 -2
  19. package/dist/core/config.js +24 -6
  20. package/dist/core/conversationKernel.d.ts +5 -0
  21. package/dist/core/conversationKernel.js +30 -1
  22. package/dist/core/dshCompatibility.d.ts +198 -0
  23. package/dist/core/dshCompatibility.js +600 -0
  24. package/dist/core/electronUtilityAgentClient.d.ts +4 -0
  25. package/dist/core/electronUtilityAgentClient.js +4 -0
  26. package/dist/core/electronUtilityRuntimePool.d.ts +19 -0
  27. package/dist/core/electronUtilityRuntimePool.js +76 -0
  28. package/dist/core/flow-runner.js +1 -1
  29. package/dist/core/mcpManager.d.ts +1 -0
  30. package/dist/core/mcpManager.js +100 -10
  31. package/dist/core/modelValidationStore.d.ts +4 -1
  32. package/dist/core/modelValidationStore.js +7 -1
  33. package/dist/core/subagent.d.ts +6 -0
  34. package/dist/core/subagent.js +22 -1
  35. package/dist/core/toolPolicy.d.ts +6 -0
  36. package/dist/core/toolPolicy.js +49 -1
  37. package/dist/core/types.d.ts +1 -1
  38. package/dist/core/utilityAgentProtocol.d.ts +8 -1
  39. package/dist/core/workspace.d.ts +15 -0
  40. package/dist/core/workspace.js +62 -1
  41. package/dist/core/wslAgentClient.d.ts +4 -0
  42. package/dist/core/wslAgentClient.js +4 -0
  43. package/dist/core/wslAgentProtocol.d.ts +8 -1
  44. package/dist/core/wslAgentRuntimePool.d.ts +12 -0
  45. package/dist/core/wslAgentRuntimePool.js +71 -0
  46. package/dist/launcher.js +48 -11
  47. package/dist/llm/provider.d.ts +9 -6
  48. package/dist/llm/provider.js +89 -36
  49. package/dist/main.js +326 -52
  50. package/dist/preload.js +17 -0
  51. package/dist/providers/chat-completions.adapter.js +42 -20
  52. package/dist/providers/provider-adapter.d.ts +3 -0
  53. package/dist/providers/provider-events.d.ts +7 -0
  54. package/dist/providers/provider-events.js +44 -0
  55. package/dist/providers/responses.adapter.js +1 -3
  56. package/dist/toolchain/registry/tool-registry.d.ts +13 -1
  57. package/dist/toolchain/registry/tool-registry.js +8 -0
  58. package/dist/toolchain/registry-seeder.js +51 -5
  59. package/dist/tools/index.js +11 -2
  60. package/dist/tools/nativeTools.js +5 -1
  61. package/dist/tui/src/adapters/core-runtime-adapter.js +40 -3
  62. package/dist/tui/src/app.js +47 -13
  63. package/dist/tui/src/render.js +23 -7
  64. package/dist/tui/src/state.js +61 -9
  65. package/dist/ui/index.html +2775 -284
  66. package/dist/ui/lucide-sprite.svg +26 -0
  67. package/dist/wsl-agent-host.bundle.cjs +1503 -214
  68. package/dist/wsl-agent-host.js +3 -0
  69. package/package.json +16 -5
@@ -11,6 +11,12 @@
11
11
  "_type": "choice",
12
12
  "_values": ["en", "zh", "auto"],
13
13
  "value": "auto"
14
+ },
15
+ "close_behavior": {
16
+ "_description": "Close behavior",
17
+ "_type": "choice",
18
+ "_values": ["minimize", "exit"],
19
+ "value": "exit"
14
20
  }
15
21
  },
16
22
  "ui": {
@@ -1,4 +1,12 @@
1
1
  export declare const CLI_COMMANDS: readonly ["state", "tool", "send", "validate-models", "fuzzy-inject", "skills-market", "memory-lab", "install-update", "compat", "compat-tool"];
2
+ export declare function cliHelpRequested(args: string[]): boolean;
3
+ /**
4
+ * Compatibility discovery reads third-party metadata outside the selected
5
+ * Newmark root. Those manifests can contain provider options, so structured
6
+ * compatibility output must not become a credential exfiltration path.
7
+ */
8
+ export declare function redactCliSecrets<T>(value: T, seen?: WeakSet<object>): T;
2
9
  export declare function runCliCommand(root: string, args: string[]): Promise<boolean>;
10
+ export declare function cliCommandHelp(command: string): string;
3
11
  export declare function cliCommandUsage(): string;
4
12
  //# sourceMappingURL=cli-commands.d.ts.map
@@ -34,7 +34,10 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.CLI_COMMANDS = void 0;
37
+ exports.cliHelpRequested = cliHelpRequested;
38
+ exports.redactCliSecrets = redactCliSecrets;
37
39
  exports.runCliCommand = runCliCommand;
40
+ exports.cliCommandHelp = cliCommandHelp;
38
41
  exports.cliCommandUsage = cliCommandUsage;
39
42
  const path = __importStar(require("path"));
40
43
  const fs = __importStar(require("fs"));
@@ -43,9 +46,102 @@ const config_1 = require("./core/config");
43
46
  const fuzzy_1 = require("./core/fuzzy");
44
47
  const provider_1 = require("./llm/provider");
45
48
  const compat_1 = require("./core/compat");
49
+ const dshCompatibility_1 = require("./core/dshCompatibility");
46
50
  const memoryLab_1 = require("./core/memoryLab");
47
51
  const installUpdate_1 = require("./core/installUpdate");
48
52
  exports.CLI_COMMANDS = ['state', 'tool', 'send', 'validate-models', 'fuzzy-inject', 'skills-market', 'memory-lab', 'install-update', 'compat', 'compat-tool'];
53
+ const CLI_COMMAND_HELP = {
54
+ state: [
55
+ 'Usage: Newmark.exe state [--root <dir>]',
56
+ 'Read the current local state as JSON and exit without a model request.',
57
+ ],
58
+ tool: [
59
+ 'Usage: Newmark.exe tool <tool-name> [json-args | key=value ... | --args-file path] [--mode build|plan|goal|flow] [--root <dir>]',
60
+ 'Execute one policy-checked tool and return its JSON envelope.',
61
+ ],
62
+ send: [
63
+ 'Usage: Newmark.exe send <prompt> [--input-env ENV|--input-file path] [--mode build|plan|goal|flow] [--model <model>] [--language auto|en|zh] [--conversation <id>] [--agent-only] [--root <dir>]',
64
+ 'Send one non-interactive prompt through the selected local model.',
65
+ ],
66
+ 'validate-models': [
67
+ 'Usage: Newmark.exe validate-models [--selected provider/model,model] [--persist] [--root <dir>]',
68
+ 'Validate configured model deployments without changing config by default; --persist writes validation metadata intentionally.',
69
+ 'An explicit selection with no configured matches prints [] and exits with status 1.',
70
+ ],
71
+ 'fuzzy-inject': [
72
+ 'Usage: Newmark.exe fuzzy-inject [--name <provider>] [--env-file <file>|--env-file-env <ENV>] [--endpoint-env <ENV>] [--key-env <ENV>] [--protocol openai|anthropic] [--preview-only] [--root <dir>]',
73
+ 'Discover or import a provider; --preview-only keeps the operation local and read-only.',
74
+ ],
75
+ 'skills-market': [
76
+ 'Usage: Newmark.exe skills-market [--query <text>|--sources|--add-source --name <name> (--url <url>|--path <path>)|--remove-source <id>|--enable-source <id>|--disable-source <id>] [--root <dir>]',
77
+ 'Search or manage local skill-market sources.',
78
+ ],
79
+ 'memory-lab': [
80
+ 'Usage: Newmark.exe memory-lab [--read|--component <name>|--update ...|--reindex] [--root <dir>]',
81
+ 'Read or update the local Memory Lab index and components.',
82
+ ],
83
+ 'install-update': [
84
+ 'Usage: Newmark.exe install-update (--source <path>|--check-github|--from-github) [options] [--root <dir>]',
85
+ 'Inspect or apply a local/GitHub update using the selected install target.',
86
+ ],
87
+ compat: [
88
+ 'Usage: Newmark.exe compat [--target all|tools|plugins|dsh|marketplaces|skills|agents|subagents] [--root <dir>]',
89
+ 'Discover compatible local agent, plugin, marketplace, and skill metadata.',
90
+ ],
91
+ 'compat-tool': [
92
+ 'Usage: Newmark.exe compat-tool --list | --name <opencode-tool> [json-args | --args-file path] [--root <dir>]',
93
+ 'List or run one compatible OpenCode tool.',
94
+ ],
95
+ };
96
+ function cliHelpRequested(args) {
97
+ return args.some(arg => ['--help', '-h'].includes(String(arg).toLowerCase()));
98
+ }
99
+ const CLI_VALUE_FLAGS = new Set([
100
+ '--root', '--input', '--input-env', '--input-file', '--mode', '--model', '--language', '--conversation',
101
+ '--args', '--args-file', '--selected', '--models', '--name', '--url', '--key', '--api-key', '--endpoint',
102
+ '--endpoint-env', '--url-env', '--key-env', '--api-key-env', '--env-file', '--env-file-env',
103
+ '--claude-env-file', '--claude-env-file-env', '--anthropic-env-file', '--anthropic-env-file-env',
104
+ '--candidate-models', '--protocol', '--query', '--type', '--path', '--component', '--source-id',
105
+ '--remove-source', '--enable-source', '--disable-source', '--source', '--target', '--target-file',
106
+ '--expected-version', '--preserve', '--repo', '--tag', '--asset', '--version', '--content-file',
107
+ '--content', '--description', '--tags',
108
+ ]);
109
+ const CLI_BOOLEAN_FLAGS = new Set([
110
+ '--persist', '--agent-only', '--list', '--preview-only', '--sources', '--add-source', '--check-github',
111
+ '--from-github', '--dry-run', '--read', '--index', '--reindex', '--update', '--version', '--folder', '--help', '-h',
112
+ '--branch-communication',
113
+ ]);
114
+ function invalidCliCommandArgument(args) {
115
+ let skipNext = false;
116
+ for (let index = 0; index < args.length; index++) {
117
+ const arg = String(args[index] || '');
118
+ if (skipNext) {
119
+ skipNext = false;
120
+ continue;
121
+ }
122
+ if (!arg || arg === '--' || !arg.startsWith('-'))
123
+ continue;
124
+ const name = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;
125
+ const hasInlineValue = arg.includes('=');
126
+ if (CLI_BOOLEAN_FLAGS.has(name))
127
+ continue;
128
+ if (CLI_VALUE_FLAGS.has(name)) {
129
+ if (hasInlineValue) {
130
+ if (!arg.slice(name.length + 1))
131
+ return `${name} requires a value`;
132
+ }
133
+ else {
134
+ const next = args[index + 1];
135
+ if (!next || String(next).startsWith('-'))
136
+ return `${name} requires a value`;
137
+ skipNext = true;
138
+ }
139
+ continue;
140
+ }
141
+ return arg;
142
+ }
143
+ return undefined;
144
+ }
49
145
  function argValue(args, key) {
50
146
  const idx = args.indexOf(key);
51
147
  return idx >= 0 ? args[idx + 1] : undefined;
@@ -228,6 +324,9 @@ function classifyCliToolOutput(tool, output) {
228
324
  const unavailableHostCapability = tool === 'computer_use' || tool.startsWith('browser_');
229
325
  return { envelope: { ok: false, tool, error: firstLine, route: 'direct' }, exitCode: unavailableHostCapability ? 3 : 2 };
230
326
  }
327
+ if (/^\[(?:context_compress|context_history_manage)]/i.test(firstLine)) {
328
+ return { envelope: { ok: false, tool, error: firstLine, route: 'direct' }, exitCode: 4 };
329
+ }
231
330
  if (/^\[(?:tool disabled|permission|Subagent sandbox)]/i.test(firstLine)) {
232
331
  return { envelope: { ok: false, tool, error: firstLine, route: 'direct' }, exitCode: 3 };
233
332
  }
@@ -382,6 +481,35 @@ function parseFuzzyEnvFile(filePath) {
382
481
  function redactUrlSecret(value) {
383
482
  return value.replace(/([?&](?:key|token|api_key|auth)=)[^&]+/gi, '$1<redacted>');
384
483
  }
484
+ const CLI_SENSITIVE_FIELD = /(?:api.?key|authorization|access.?token|refresh.?token|secret|password|credential|cookie)/i;
485
+ /**
486
+ * Compatibility discovery reads third-party metadata outside the selected
487
+ * Newmark root. Those manifests can contain provider options, so structured
488
+ * compatibility output must not become a credential exfiltration path.
489
+ */
490
+ function redactCliSecrets(value, seen = new WeakSet()) {
491
+ const walk = (current) => {
492
+ if (typeof current === 'string') {
493
+ return current
494
+ .replace(/\bsk-[A-Za-z0-9_.-]{8,}\b/gi, 'sk-***REDACTED***')
495
+ .replace(/\bBearer\s+[A-Za-z0-9_.=:/+_-]{8,}/gi, 'Bearer <redacted>')
496
+ .replace(/([?&](?:key|token|api_key|auth)=)[^&\s]+/gi, '$1<redacted>');
497
+ }
498
+ if (current === null || typeof current !== 'object')
499
+ return current;
500
+ if (seen.has(current))
501
+ return '[CIRCULAR]';
502
+ seen.add(current);
503
+ if (Array.isArray(current))
504
+ return current.map(item => walk(item));
505
+ const output = {};
506
+ for (const [key, nested] of Object.entries(current)) {
507
+ output[key] = CLI_SENSITIVE_FIELD.test(key) ? '[REDACTED]' : walk(nested);
508
+ }
509
+ return output;
510
+ };
511
+ return walk(value);
512
+ }
385
513
  function filterSkillMarket(items, query) {
386
514
  const q = (query || '').trim().toLowerCase();
387
515
  if (!q)
@@ -539,11 +667,22 @@ async function runCliFuzzyInject(agent, name, url, key, protocol, preferredModel
539
667
  };
540
668
  }
541
669
  async function runCliCommand(root, args) {
542
- installCliPipeGuards();
543
670
  const command = args.find(a => exports.CLI_COMMANDS.includes(a));
544
671
  if (!command)
545
672
  return false;
546
- const agent = new agent_1.Agent(root, { agentOnly: args.includes('--agent-only') });
673
+ installCliPipeGuards();
674
+ const invalidArgument = invalidCliCommandArgument(args);
675
+ if (invalidArgument) {
676
+ safeStderr(`Invalid Newmark argument: ${invalidArgument}\n`);
677
+ process.exitCode = 2;
678
+ return true;
679
+ }
680
+ if (cliHelpRequested(args)) {
681
+ safeStdout(cliCommandHelp(command));
682
+ return true;
683
+ }
684
+ const readOnlyValidation = command === 'validate-models' && !args.includes('--persist');
685
+ const agent = new agent_1.Agent(root, { agentOnly: args.includes('--agent-only'), readOnlyConfig: readOnlyValidation });
547
686
  agent.tools.setHostProfile({
548
687
  kind: 'cli',
549
688
  platform: process.platform,
@@ -553,6 +692,8 @@ async function runCliCommand(root, args) {
553
692
  const conversation = argValue(args, '--conversation');
554
693
  if (conversation)
555
694
  agent.setConversation(conversation);
695
+ if (args.includes('--branch-communication'))
696
+ agent.setBranchCommunication(true);
556
697
  const language = argValue(args, '--language');
557
698
  if (language && ['auto', 'en', 'zh'].includes(language))
558
699
  agent.config.set('general', 'language', language);
@@ -599,11 +740,19 @@ async function runCliCommand(root, args) {
599
740
  const toolArgs = parsedArgs.value;
600
741
  const wsDir = agent.workspace.current?.path || root;
601
742
  try {
602
- const result = await agent.tools.execute(toolName, JSON.stringify(toolArgs), wsDir, {
603
- mode: agent.mode,
604
- workspacePath: wsDir,
605
- invocation: 'cli',
606
- });
743
+ // Context management is an Agent-owned capability. Keep the direct CLI
744
+ // route on the same handler as model-dispatched calls instead of sending
745
+ // it through the generic filesystem/native ToolExecutor switch, which
746
+ // intentionally has no access to conversation history.
747
+ const result = toolName === 'context_compress'
748
+ ? (await agent.handleContextCompress(JSON.stringify(toolArgs))).output
749
+ : toolName === 'context_history_manage'
750
+ ? agent.handleContextHistoryManage(JSON.stringify(toolArgs)).output
751
+ : await agent.tools.execute(toolName, JSON.stringify(toolArgs), wsDir, {
752
+ mode: agent.mode,
753
+ workspacePath: wsDir,
754
+ invocation: 'cli',
755
+ });
607
756
  const classified = classifyCliToolOutput(toolName, result);
608
757
  emitCliToolEnvelope(classified.envelope, classified.exitCode);
609
758
  }
@@ -623,17 +772,50 @@ async function runCliCommand(root, args) {
623
772
  return true;
624
773
  }
625
774
  const model = argValue(args, '--model');
626
- if (model)
775
+ if (model) {
627
776
  agent.setModel(model);
628
- const tokens = await agent.process(prompt);
629
- safeStdout(tokens.map(t => t.text || '').join(''));
630
- safeStdout('\n');
777
+ // Reject a bad explicit selection before Agent.process creates a user
778
+ // message/work-run or reaches the provider transport. Qualified
779
+ // provider/model values are normalized by Agent.setModel first.
780
+ if (model !== 'auto' && !agent.activeModelConfig()) {
781
+ safeStdout(`[Error] Model '${model}' is unavailable or not configured. Select a configured model or enable a valid provider before sending.`);
782
+ safeStdout('\n');
783
+ process.exitCode = 1;
784
+ return true;
785
+ }
786
+ }
787
+ try {
788
+ const tokens = await agent.process(prompt);
789
+ const output = tokens.map(t => t.text || '').join('');
790
+ safeStdout(output);
791
+ safeStdout('\n');
792
+ // Keep the diagnostic in stdout for pipes, but make the non-interactive
793
+ // command fail when Agent returned a structured error token.
794
+ if (tokens.some(token => {
795
+ const text = String(token.text || '');
796
+ return agent.isLlmErrorText(text) || /^\s*\[(?:Workspace required|Attachment rejected)\]/i.test(text);
797
+ }))
798
+ process.exitCode = 1;
799
+ }
800
+ catch (error) {
801
+ // The shared GUI/TUI kernel must throw real terminal failures so it
802
+ // cannot synthesize a completed WorkRun. Preserve the CLI's stable
803
+ // stdout diagnostic and non-zero exit contract at this boundary.
804
+ const message = error instanceof Error ? error.message : String(error);
805
+ safeStdout(message.startsWith('[') ? message : `[Error] ${message}`);
806
+ safeStdout('\n');
807
+ process.exitCode = 1;
808
+ }
631
809
  return true;
632
810
  }
633
811
  if (command === 'validate-models') {
634
812
  const selected = splitList(pathArgValue(args, '--selected') || pathArgValue(args, '--models'));
635
- const result = await agent.validateModels(selected.length ? selected : undefined);
813
+ const result = await agent.validateModels(selected.length ? selected : undefined, { persist: args.includes('--persist') });
636
814
  printJson(result);
815
+ if (selected.length && result.length === 0) {
816
+ safeStderr(`No configured model deployments matched --selected: ${selected.join(', ')}\n`);
817
+ process.exitCode = 1;
818
+ }
637
819
  return true;
638
820
  }
639
821
  if (command === 'fuzzy-inject') {
@@ -811,10 +993,11 @@ async function runCliCommand(root, args) {
811
993
  target,
812
994
  compatibility: {
813
995
  tool_schemas: ['openai_chat_completions', 'openai_responses', 'anthropic_input_schema'],
814
- plugin_ecosystems: ['codex', 'claude-code', 'opencode', 'newmark'],
996
+ plugin_ecosystems: ['codex', 'claude-code', 'opencode', 'newmark', 'deepseek-harness'],
815
997
  marketplace_ecosystems: ['codex', 'claude-code', 'newmark'],
816
998
  plugin_execution: 'metadata-only by default; OpenCode JavaScript tools require explicit compat-tool invocation.',
817
999
  mcp_activation: 'discovered from plugin/config metadata but not auto-started.',
1000
+ dsh_compatibility: 'read-only bundle/profile/config discovery; unknown manifest keys are retained as compatibility metadata.',
818
1001
  subagent_return_contract: 'structured NewmarkSubagentRecord embedded in NewmarkToolResult while preserving legacy text output.',
819
1002
  },
820
1003
  };
@@ -829,6 +1012,9 @@ async function runCliCommand(root, args) {
829
1012
  if (target === 'all' || target === 'plugins') {
830
1013
  payload.plugins = plugins;
831
1014
  }
1015
+ if (target === 'all' || target === 'plugins' || target === 'dsh') {
1016
+ payload.dsh = (0, dshCompatibility_1.discoverDshCompatibility)(root);
1017
+ }
832
1018
  if (target === 'all' || target === 'marketplaces') {
833
1019
  payload.marketplaces = (0, compat_1.discoverPluginMarketplaces)(root);
834
1020
  }
@@ -846,12 +1032,12 @@ async function runCliCommand(root, args) {
846
1032
  };
847
1033
  payload.subagents = agent.subagents.listAll().map(s => agent.subagents.toRecord(s.id));
848
1034
  }
849
- printJson(payload);
1035
+ printJson(redactCliSecrets(payload));
850
1036
  return true;
851
1037
  }
852
1038
  if (command === 'compat-tool') {
853
1039
  if (args.includes('--list')) {
854
- printJson({ ok: true, tools: (0, compat_1.discoverOpenCodeTools)(root) });
1040
+ printJson(redactCliSecrets({ ok: true, tools: (0, compat_1.discoverOpenCodeTools)(root) }));
855
1041
  return true;
856
1042
  }
857
1043
  const positional = positionalAfter(args, 'compat-tool');
@@ -867,11 +1053,25 @@ async function runCliCommand(root, args) {
867
1053
  process.exitCode = 1;
868
1054
  return true;
869
1055
  }
870
- printJson(await (0, compat_1.runOpenCodeTool)(root, name, parsedArgs.value));
1056
+ printJson(redactCliSecrets(await (0, compat_1.runOpenCodeTool)(root, name, parsedArgs.value)));
871
1057
  return true;
872
1058
  }
873
1059
  return false;
874
1060
  }
1061
+ function cliCommandHelp(command) {
1062
+ const key = command;
1063
+ const lines = CLI_COMMAND_HELP[key];
1064
+ if (!lines)
1065
+ return `${cliCommandUsage()}\n`;
1066
+ return [
1067
+ `Newmark CLI command: ${command}`,
1068
+ '',
1069
+ ...lines,
1070
+ '',
1071
+ 'Flags:',
1072
+ ' --help, -h Show this command help and exit without network or model work.',
1073
+ ].join('\n') + '\n';
1074
+ }
875
1075
  function cliCommandUsage() {
876
1076
  return [
877
1077
  'Newmark CLI non-interactive commands:',
@@ -0,0 +1,15 @@
1
+ /** Public version spellings accepted by every Newmark entrypoint. */
2
+ export declare function isVersionArgument(args: string[]): boolean;
3
+ /**
4
+ * Validate arguments that are interpreted before a command-specific parser is
5
+ * entered. This keeps malformed launch probes from silently starting a GUI or
6
+ * falling back to the default user root.
7
+ */
8
+ export declare function invalidTopLevelArgument(args: string[]): string | undefined;
9
+ /**
10
+ * Return the first unknown positional top-level token without validating a
11
+ * command's own arguments. Values belonging to documented flags are skipped,
12
+ * so a space-containing --root or --input cannot be mistaken for a command.
13
+ */
14
+ export declare function unknownTopLevelCommand(args: string[]): string | undefined;
15
+ //# sourceMappingURL=cli-discovery.d.ts.map
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isVersionArgument = isVersionArgument;
4
+ exports.invalidTopLevelArgument = invalidTopLevelArgument;
5
+ exports.unknownTopLevelCommand = unknownTopLevelCommand;
6
+ const cli_commands_1 = require("./cli-commands");
7
+ const TOP_LEVEL_COMMANDS = new Set([...cli_commands_1.CLI_COMMANDS, 'flow', 'edit', 'help']);
8
+ const VALUE_FLAGS = new Set([
9
+ '--root',
10
+ '--input',
11
+ '--input-env',
12
+ '--input-file',
13
+ '--mode',
14
+ '--model',
15
+ '--language',
16
+ '--conversation',
17
+ '--args',
18
+ '--args-file',
19
+ '--selected',
20
+ '--models',
21
+ '--name',
22
+ '--url',
23
+ '--key',
24
+ '--api-key',
25
+ '--protocol',
26
+ '--endpoint',
27
+ '--endpoint-env',
28
+ '--url-env',
29
+ '--key-env',
30
+ '--api-key-env',
31
+ '--env-file',
32
+ '--env-file-env',
33
+ '--claude-env-file',
34
+ '--claude-env-file-env',
35
+ '--anthropic-env-file',
36
+ '--anthropic-env-file-env',
37
+ '--candidate-models',
38
+ '--query',
39
+ '--type',
40
+ '--target',
41
+ '--source',
42
+ '--source-id',
43
+ '--remove-source',
44
+ '--enable-source',
45
+ '--disable-source',
46
+ '--target-file',
47
+ '--expected-version',
48
+ '--preserve',
49
+ '--repo',
50
+ '--tag',
51
+ '--asset',
52
+ '--path',
53
+ '--component',
54
+ '--content-file',
55
+ '--content',
56
+ '--description',
57
+ '--tags',
58
+ '--workspace',
59
+ '--remote-debugging-port',
60
+ '--user-data-dir',
61
+ '--disable-features',
62
+ '--enable-features',
63
+ '--remote-debugging-address',
64
+ '--inspect-port',
65
+ '--js-flags',
66
+ '--viewer-request',
67
+ ]);
68
+ const BOOLEAN_FLAGS = new Set([
69
+ '--tui',
70
+ '--gui',
71
+ '--cli',
72
+ '--server',
73
+ '--help',
74
+ '-h',
75
+ '--version',
76
+ '-v',
77
+ '-version',
78
+ '--automation-wake',
79
+ '--newmark-viewer',
80
+ '--allow-multiple-instances',
81
+ '--disable-gpu',
82
+ '--no-sandbox',
83
+ '--no-devtools',
84
+ '--demo',
85
+ '--persist',
86
+ '--agent-only',
87
+ '--list',
88
+ '--preview-only',
89
+ '--sources',
90
+ '--add-source',
91
+ '--check-github',
92
+ '--from-github',
93
+ '--dry-run',
94
+ '--read',
95
+ '--index',
96
+ '--reindex',
97
+ '--update',
98
+ '--folder',
99
+ '--quiet',
100
+ '--json',
101
+ '--limit',
102
+ '--scopes',
103
+ '--web',
104
+ ]);
105
+ /** Public version spellings accepted by every Newmark entrypoint. */
106
+ function isVersionArgument(args) {
107
+ return args.some(arg => ['--version', '-v', '-version'].includes(String(arg).toLowerCase()));
108
+ }
109
+ /**
110
+ * Validate arguments that are interpreted before a command-specific parser is
111
+ * entered. This keeps malformed launch probes from silently starting a GUI or
112
+ * falling back to the default user root.
113
+ */
114
+ function invalidTopLevelArgument(args) {
115
+ let skipNext = false;
116
+ for (let index = 0; index < args.length; index++) {
117
+ const raw = args[index];
118
+ const arg = String(raw || '');
119
+ if (skipNext) {
120
+ skipNext = false;
121
+ continue;
122
+ }
123
+ if (!arg || arg === '--')
124
+ continue;
125
+ if (!arg.startsWith('-'))
126
+ continue;
127
+ const name = (arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg).toLowerCase();
128
+ const hasInlineValue = arg.includes('=');
129
+ if (BOOLEAN_FLAGS.has(name))
130
+ continue;
131
+ if (VALUE_FLAGS.has(name)) {
132
+ if (!hasInlineValue) {
133
+ const next = args[index + 1];
134
+ if (!next || String(next).startsWith('-'))
135
+ return `${name} requires a value`;
136
+ skipNext = true;
137
+ }
138
+ else if (!arg.slice(name.length + 1)) {
139
+ return `${name} requires a value`;
140
+ }
141
+ continue;
142
+ }
143
+ return arg;
144
+ }
145
+ return undefined;
146
+ }
147
+ /**
148
+ * Return the first unknown positional top-level token without validating a
149
+ * command's own arguments. Values belonging to documented flags are skipped,
150
+ * so a space-containing --root or --input cannot be mistaken for a command.
151
+ */
152
+ function unknownTopLevelCommand(args) {
153
+ let skipNext = false;
154
+ for (let index = 0; index < args.length; index++) {
155
+ const raw = args[index];
156
+ const arg = String(raw || '');
157
+ if (skipNext) {
158
+ skipNext = false;
159
+ continue;
160
+ }
161
+ if (!arg)
162
+ continue;
163
+ if (arg.startsWith('--')) {
164
+ const name = (arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg).toLowerCase();
165
+ if (VALUE_FLAGS.has(name) && !arg.includes('='))
166
+ skipNext = true;
167
+ else if (!VALUE_FLAGS.has(name) && !BOOLEAN_FLAGS.has(name))
168
+ return arg;
169
+ continue;
170
+ }
171
+ if (arg.startsWith('-')) {
172
+ if (!BOOLEAN_FLAGS.has(arg))
173
+ return arg;
174
+ continue;
175
+ }
176
+ if (TOP_LEVEL_COMMANDS.has(arg.toLowerCase()))
177
+ return undefined;
178
+ return arg;
179
+ }
180
+ return undefined;
181
+ }
182
+ //# sourceMappingURL=cli-discovery.js.map
@@ -1,2 +1,4 @@
1
+ export declare function newmarkFlowHelpText(): string;
2
+ export declare function newmarkEditHelpText(): string;
1
3
  export declare function newmarkHelpText(version: string): string;
2
4
  //# sourceMappingURL=cli-help.d.ts.map
package/dist/cli-help.js CHANGED
@@ -1,7 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.newmarkFlowHelpText = newmarkFlowHelpText;
4
+ exports.newmarkEditHelpText = newmarkEditHelpText;
3
5
  exports.newmarkHelpText = newmarkHelpText;
4
6
  const cli_commands_1 = require("./cli-commands");
7
+ function newmarkFlowHelpText() {
8
+ return [
9
+ 'Newmark Flow command:',
10
+ '',
11
+ 'Usage: Newmark.exe flow <workflow-name> [start-pc] [--input "text"] [--root <dir>]',
12
+ 'Run a saved Flow workflow from the selected local runtime root.',
13
+ '',
14
+ 'Flags:',
15
+ ' --help, -h Show this Flow help and exit without runtime or model work.',
16
+ ].join('\n') + '\n';
17
+ }
18
+ function newmarkEditHelpText() {
19
+ return [
20
+ 'Newmark editor command:',
21
+ '',
22
+ 'Usage: Newmark.exe edit <file.txt|.json|.tex|.md>',
23
+ 'Open a supported text file in the terminal editor.',
24
+ '',
25
+ 'Flags:',
26
+ ' --help, -h Show this editor help and exit without opening a file.',
27
+ ].join('\n') + '\n';
28
+ }
5
29
  function newmarkHelpText(version) {
6
30
  return [
7
31
  `Newmark Agent ${version}`,
@@ -16,7 +40,7 @@ function newmarkHelpText(version) {
16
40
  '',
17
41
  'Flags:',
18
42
  ' --help, -h Show this help and exit.',
19
- ' --version, -v Show the installed version and exit.',
43
+ ' --version, -v, -version Show the installed version and exit.',
20
44
  ].join('\n');
21
45
  }
22
46
  //# sourceMappingURL=cli-help.js.map
@@ -148,6 +148,27 @@ export interface CapabilityDescriptor {
148
148
  version: number;
149
149
  }
150
150
  export type ToolIdempotency = 'idempotent' | 'conditionally_idempotent' | 'non_idempotent';
151
+ /** 最小执行上下文:承载 DSH 工具 execute 的 exec.signal/agent 等运行时能力。 */
152
+ export interface ToolExecuteContext {
153
+ signal?: AbortSignal;
154
+ agent?: unknown;
155
+ token?: unknown;
156
+ [key: string]: unknown;
157
+ }
158
+ /** DSH ToolDefinition.execute 的运行时执行函数签名(cordis 核功能承载)。 */
159
+ export type ToolExecuteFn = (args: unknown, context: ToolExecuteContext) => Promise<unknown> | unknown;
160
+ /** DSH ToolDefinition.isConcurrencySafe 的运行时并发分类(cordis 核功能承载)。 */
161
+ export type ToolConcurrencySafeFn = (args: unknown) => boolean;
162
+ /** DSH ToolOutputDefinition.render 的模型可见内容投影。 */
163
+ export type ToolRenderFn = (args: unknown, value: unknown) => unknown;
164
+ /** DSH ToolOutputDefinition.presentationMeta 的可回放 UI 状态投影。 */
165
+ export type ToolPresentationMetaFn = (args: unknown, value: unknown) => unknown;
166
+ /** DSH ToolDefinition.finalizeContent 的同步 last-mile 内容变换(可选)。 */
167
+ export type ToolFinalizeContentFn = (context: ToolExecuteContext, result: unknown) => unknown;
168
+ /** DSH ToolDefinition.presentCall 的 PENDING 卡片展示投影(可选)。 */
169
+ export type ToolPresentCallFn = (args: unknown) => unknown;
170
+ /** DSH ToolDefinition.presentResult 的 COMPLETED 卡片展示投影(可选)。 */
171
+ export type ToolPresentResultFn = (args: unknown, result: unknown) => unknown;
151
172
  export interface ToolDescriptor {
152
173
  toolId: string;
153
174
  capabilityId: string;
@@ -166,6 +187,22 @@ export interface ToolDescriptor {
166
187
  implementationHash?: string;
167
188
  cacheGroup: string;
168
189
  enabled: boolean;
190
+ /** DSH ToolDefinition.execute 承载:接入的命令式功能实现(不 import/execute DSH 代码,仅承载已安全注入的函数引用)。 */
191
+ execute?: ToolExecuteFn;
192
+ /** DSH ToolDefinition.isConcurrencySafe 承载:运行时并发分类,静态 riskLevel 的补充。 */
193
+ isConcurrencySafe?: ToolConcurrencySafeFn;
194
+ /** DSH ToolOutputDefinition.render:模型可见内容投影(功能承载)。 */
195
+ render?: ToolRenderFn;
196
+ /** DSH ToolOutputDefinition.presentationMeta:可回放 UI 状态投影(功能承载)。 */
197
+ presentationMeta?: ToolPresentationMetaFn;
198
+ /** DSH ToolDefinition.finalizeContent:同步 last-mile 内容变换(功能承载)。 */
199
+ finalizeContent?: ToolFinalizeContentFn;
200
+ /** DSH ToolDefinition.timeoutMs:协作超时预算(功能承载)。 */
201
+ timeoutMs?: number;
202
+ /** DSH ToolDefinition.presentCall:PENDING 卡片展示投影(功能承载)。 */
203
+ presentCall?: ToolPresentCallFn;
204
+ /** DSH ToolDefinition.presentResult:COMPLETED 卡片展示投影(功能承载)。 */
205
+ presentResult?: ToolPresentResultFn;
169
206
  }
170
207
  export interface ActiveToolManifestEntry {
171
208
  toolId: string;
@@ -20,6 +20,8 @@ exports.CONTEXT_SECTION_ORDER = [
20
20
  'active_toolset_manifest',
21
21
  'build_block_startup_input',
22
22
  'build_block_metadata',
23
+ // Compatibility slot: linked-plan content is tool-retrieved on demand and
24
+ // should remain empty for ordinary model requests.
23
25
  'linked_plan',
24
26
  'active_tasks',
25
27
  'current_work_set',