Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
156707 stories
·
33 followers

Mailbox requirement set 1.16 now available for Outlook add-ins

1 Share

Mailbox requirement set 1.16 is now generally available for Outlook add-ins. This release reflects our continued investment in closing the gap between COM/VSTO and web add-ins, with a focus on message and information security.

Mailbox 1.16 introduces APIs and platform updates that enable your add-in to:

  • Decrypt protected messages and attachments in an event-based workflow.
  • Determine whether Exchange Web Services (EWS) tokens are supported in an organization.
  • Easily identify inline attachments in mail items.
  • Retrieve a larger number of recipients from mail items.
  • Store more session-scoped state and data with a larger SessionData limit.

Handle message decryption with ease

Mailbox requirement set 1.16 introduces the OnMessageDecrypt event, which enables Outlook add-ins to automatically decrypt protected messages when a user opens them. The event-based workflow identifies encrypted messages, decrypts messages, displays the decrypted message content, and surfaces error notifications when needed. This workflow handles the operational steps so that you can focus on defining and implementing encryption and decryption protocols that meet your organization’s security requirements in the add-in.

To learn more about implementing decryption in your add-in, see Create an encryption Outlook add-in. To see a sample decryption add-in in action, try out the Encrypt and decrypt messages in Outlook sample.

Detect support for EWS tokens in an organization

While EWS tokens have been turned off for Exchange Online environments, some organizations still run on-premises environments. With the introduction of the Office.context.mailbox.diagnostics.ews.getTokenStatusAsync API, your add-in can now identify whether EWS callback tokens are supported in an organization. This enables your add-in to run the recommended authentication solutions when available while maintaining backward compatibility when needed.

Enhance data loss prevention and content processing workflows

Mailbox 1.16 also enhances existing APIs to support data loss prevention and content processing scenarios.

  • The contentId property expands the attachment API so your add-in can easily identify inline attachments in mail items during content inspection and rendering workflows.
  • The getAsync method of the Recipients API now returns up to 1,000 recipients from any recipient field of a mail item. This expanded limit helps your data loss prevention solutions evaluate larger recipient lists in a single operation.
  • The SessionData object now supports up to 2,621,440 characters per add-in, so that your add-in can store and retrieve data more seamlessly within a single session.

Try the new Mailbox 1.16 capabilities in your Outlook add-in today. Happy coding!

The post Mailbox requirement set 1.16 now available for Outlook add-ins appeared first on Microsoft 365 Developer Blog.

Read the whole story
alvinashcraft
24 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

MSIX Per-User vs All Users: Install, Provision, and Uninstall Packages

1 Share

MSIX supports making a package available to all users; the formal term is provisioning. Provisioning a package family makes it available to all users, whereas registration makes a package available to a single user.

Per-User vs All Users

Traditional installers often provide a “per-machine” installation mode to make software available to all users. In MSIX, the equivalent user experience is achieved through provisioning.

To install a package for all users, first stage the package on the machine and then register it for each user. To facilitate this, Deployment manages a ‘list of provisioned package families’ and ensures provisioned packages are automatically registered for all users.

NOTE: Deployment provisions package families, not specific packages. But ‘list of provisioned package families’ is a mouthful, so it’s often referred to as the ‘list of provisioned packages’, or simply ‘provisioned packages’. Likewise, ‘provisioned package family’ is wordy, thus often referred to as ‘provisioned package’. Regardless of the phrasing, package families are what’s provisioned.

User Experience

At logon before the desktop appears, Deployment compares the user’s registered packages against those staged on the machine. If a newer version is present, Deployment registers it for the user.

The provisioned list is also checked at this time. Deployment registers the latest version in each provisioned family if the user has no packages in that family, i.e. add the package for the user. This ensures users have all provisioned packages registered and available for use, regardless of whether it’s a new user’s first logon or previously existing user’s Nth logon.

How does provisioning work?

At logon, Deployment determines what the user should have versus what they currently have, and updates accordingly. The logic amounts to:

Package[] todo = new Package[]

// Are there newer versions of packages the user has registered?
Package[] current = PackageManager.FindPackagesForUser("")
FOREACH (pcurrent IN current)
  Package ptodo = null

  // What packages in the family exist on the machine?
  FOREACH (p IN PackageManager.FindPackages(p))

    // Is this package newer than the registered packaged?
    IF p.Version > pcurrent.Version

      // Is this package a newer version than the previously found package (if any)
      IF (ptodo == null) OR (p.Version > ptodo.Version)
        // New 'better' fit
        ptodo = p
    ENDIF
  ENDIF

  // Did we find a newer package we should register?
  IF (ptodo != null)
    todo += ptodo
  ENDIF
NEXT

// Any provisioned package families the user doesn't have registered?
Package[] provisioned = PackageManager.FindProvisionedPackages()
FOREACH (p IN provisioned)
  IF (p.PackageFamilyName NOT IN current)
    pmax = FindHighestVersionPackageInFamily(p.PackageFamilyName)
    todo += pmax
  ENDIF
NEXT

// Register the newer and provisioned packages the user should have but doesn't
FOREACH (p IN todo)
  PackageDeploymentManager.RegisterPackage(p)
NEXT

Deployment determines the desired packages the user should have by comparing the provisioned list plus packages on the machine versus packages registered for the user:

  • If a desired package is registered => Nothing to do
  • If an older version is registered => Register the desired (newer) package (aka update)
  • If no package in the family is registered => Register the desired package (aka add)

Deployment updates users to the latest version of provisioned packages during user logon, before the desktop appears. From the user’s perspective they’re automagically updated to the latest version of their installed software.

HOWTO Install Per-User vs All Users

Installation for all users differs from installation for the current user.

Per-User

A package needs to be staged and registered to be accessed by a user. This can be simplified as an Add operation, as explained in There is no Install – it’s ‘Stage’ and ‘Register’ and Add vs Stage and Register.

var packageDeploymentManager = new Microsoft.Windows.Management.Deployment.PackageDeploymentManager();
var packageUri = new Uri("https://contoso.com/ContosoParts-v1.2.3.4-x64.msix");
var options = new Microsoft.Windows.Management.Deployment.AddPackageOptions();
var result = await packageManager.AddPackageByUriAsync(packageUri, options);

All Users

You must stage a package on the system before you can provision it. For a new package family not yet present on a system this requires staging a package and then provisioning its package family via ProvisionPackageAsync():

var packageDeploymentManager = new Microsoft.Windows.Management.Deployment.PackageDeploymentManager();
var packageUri = new Uri("https://contoso.com/ContosoParts-v1.2.3.4-x64.msix");
var options = new Microsoft.Windows.Management.Deployment.StagePackageOptions();
var result = await packageDeploymentManager.StagePackageByUriAsync(packageUri, options);

string packageFamilyName = "Contoso.Parts_1234567890abc";
result = await packageDeploymentManager.ProvisionPackageAsync(packageFamilyName);

.ProvisionPackageAsync() will…

  1. Add the package family to the provisioned list
  2. Register the package for the current user, if necessary AND current user is not LocalSystem1

Deployment registers the newly provisioned package family for other users at their next logon.

HOWTO Uninstall Per-User vs All Users

Uninstall for all users vs current user is similar to installation.

Per-User

Uninstalling a package for a user is a simple Remove operation.

var packageDeploymentManager = new Microsoft.Windows.Management.Deployment.PackageDeploymentManager();
string packageFamilyName = "Contoso.Parts_1234567890abc";
var options = new Microsoft.Windows.Management.Deployment.RemovePackageOptions();
var result = await packageDeploymentManager.RemovePackageAsync(packageFamilyName, options);

RemovePackage*Async() has multiple method overloads. The simplest is to remove by package family name, as above.

Alternatively, one could specify a PackageFullName for a specific package to remove, but the package may have been updated since the initial install. RemovePackageAsync(pkgfullname,...) will fail if the exact package is not currently registered.

Remove operations implicitly include ForceTargetAppShutdown, causing running processes to quit, so the package can be cleanly deregistered.

In the simplest case there’s (now) no references to the package, so it will also be destaged.

All Users

To remove a package for all users, first remove the package family from the provisioned list via DeprovisionPackageAsync() AND deregistered for all users. The latter requires RemoveForAllUsers option.

var packageDeploymentManager = new Microsoft.Windows.Management.Deployment.PackageDeploymentManager();
string packageFamilyName = "Contoso.Parts_1234567890abc";
result = await packageDeploymentManager.DeprovisionPackageAsync(packageFamilyName);

var packageDeploymentManager = new Microsoft.Windows.Management.Deployment.PackageDeploymentManager();
var options = new Microsoft.Windows.Management.Deployment.RemovePackageOptions();
options.RemoveForAllUsers = true;
var result = await packageDeploymentManager.RemovePackageByFamilyNameAsync(packageFamilyName, options);

WARNING: .Deprovision...() should be called before .Remove...(). If not, new (unexpected) registrations could occur after .Remove...() but before .Deprovision...() removes the package family from the provisioned list.

Do I need to reprovision after staging a newer package?

If v1 is provisioned and I stage v2, do I need to reprovision?

No.

Provisioning tracks package families, not individual packages. You do not provision a specific package version; you provision a package family. As a result, newer versions do not need to be reprovisioned. Simply stage the newer package. Because provisioning tracks package families rather than package versions, Deployment will register the highest available version in the family at user logon.

Security

MSIX allows users to query and change their package inventory, but requires admin privilege to see or impact other users or machine-wide data.

Thus ProvisionPackageAsync(), DeprovisionPackageAsync() and RemoveForAllUsers require admin privilege.

Recap

The canonical operations are:

  • Per-user: Add → Remove
  • All users: Stage + Provision → Deprovision + RemoveForAllUsers

Provisioning is the MSIX mechanism that provides the traditional “install for all users” experience.


1 Deployment can register packages for any user except LocalSystem. This is a known limitation, and lifting this restriction is tracked in our backlog.

The post MSIX Per-User vs All Users: Install, Provision, and Uninstall Packages appeared first on Inside MSIX.

Read the whole story
alvinashcraft
41 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Compose your API surface with Data API builder custom paths

1 Share

In May, Data API builder (DAB) 2.0 was released to preview, and in June it went generally available. With this new release, DAB introduced a new feature for REST endpoints: the ability to customize endpoints with compound paths. This feature allows developers to compose a sophisticated API surface dedicated to their business structure, not their database topology. Let’s take a look.

Generating REST endpoints

With Data API builder (DAB), developers can safely expose their production SQL database as a REST, GraphQL, and MCP endpoint. In this article, we focus on REST. These endpoints are dynamically generated by the DAB engine with rich capabilities like native pagination, filtering, projection, caching, and throttling. These are the same types of features you would add to your custom endpoints, but without the engineering cost or time.

Exposing REST endpoints

A REST endpoint path is constructed from three parts. The first is the host name where Data API builder is hosted. For example, this could be localhost in the inner developer loop or an Azure domain when hosted in Azure Container Apps. The second part is the global runtime setting runtime.rest.path, which defaults to /api, a typical starting segment for most API endpoints.

The third part of the REST path is our new feature, compound paths. It is individually configured for every entity. For example, if you have a Customer entity exposed, your default path might coalesce to localhost/api/Customer, which works great for many deployments and has worked great for years.

However, entity path values like /external/Customer were not supported until release 2.0. With this new flexibility, different entities can be grouped by some business mnemonic to help clarify usage and enable better intuition around endpoint usage. Supporting as many subsegments as you need, Data API builder lets you compose your API surface in whatever direction best serves your business.

Entity configuration examples

Every entity provides its final REST endpoint path. This is the segment that now supports compound paths, letting you build out a tailored, intuitive API surface. In the examples below, we’ll show some scenarios with our example Customer entity.

Scenario 1: a simple endpoint

{
  "runtime": {
    "rest": {
      "enabled": true,
      "path": "/api"
    }
  },
  "entities": {
    "Customer": {
      "source": {
        "object": "dbo.Customer",
        "type": "table"
      },
      "rest": {
        "enabled": true,
        "path": "/Customer"
      }
    }
  }
}

The resulting REST path is https://localhost/api/Customer.

Or if you had several entities, you could see this:
https://localhost/api/Customer
https://localhost/api/Order
https://localhost/api/Invoice
https://localhost/api/CustomerAddress
https://localhost/api/Payment

Scenario 2: show the business in the path

You can use compound paths to organize endpoints by business area. This can make the API easier to understand, especially when many entities are exposed.

{
  "runtime": {
    "rest": {
      "enabled": true,
      "path": "/api"
    }
  },
  "entities": {
    "Customer": {
      "source": {
        "object": "dbo.Customer",
        "type": "table"
      },
      "rest": {
        "enabled": true,
        "path": "/sales/Customer"
      }
    }
  }
}

The resulting REST path is https://localhost/api/sales/Customer.

Or if you had several entities, you could see this:
https://localhost/api/sales/Customer
https://localhost/api/sales/Order
https://localhost/api/sales/Invoice
https://localhost/api/accounting/Payment
https://localhost/api/support/CustomerCase

Scenario 3: show the schema in the path

You can also use compound paths to reflect database schema or ownership. This can be useful when the API surface needs to preserve a familiar structure for developers.

{
  "runtime": {
    "rest": {
      "enabled": true,
      "path": "/api"
    }
  },
  "entities": {
    "Customer": {
      "source": {
        "object": "sales.Customer",
        "type": "table"
      },
      "rest": {
        "enabled": true,
        "path": "/sales/Customer"
      }
    }
  }
}

The resulting REST path is https://localhost/api/sales/Customer.

Or if you had several entities, you could see this:
https://localhost/api/dbo/Customer
https://localhost/api/sales/Order
https://localhost/api/sales/Invoice
https://localhost/api/billing/Payment
https://localhost/api/support/CustomerCase

Conclusion

Compound REST paths make it easier to shape a Data API builder API around your application and business needs. You can keep simple paths when they are enough, or add structure when it helps developers understand and use the API. Data API builder still handles the endpoint generation, security, and query behavior for you.

Best of luck!

The post Compose your API surface with Data API builder custom paths appeared first on Azure SQL Dev Corner.

Read the whole story
alvinashcraft
58 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

1.0.66

1 Share

2026-06-30

  • Use a non-blinking block cursor during interactive sessions, restoring your terminal's default cursor on exit
  • Add support for Claude Opus 4.8 Fast and deprecate Claude Opus 4.6 Fast
  • MCP add/edit form accepts HTTP-style Key: value headers
  • Keep LSP servers from starting twice during startup
  • Avoid blocking commands that contain Windows-style path fragments
  • Let Copilot read output from and stop detached background shell commands
  • Large output handling now respects custom output directories and a disable setting
  • Prevent PR description generation from crashing on empty assistant responses
  • Render the timeline as a compact "highlight reel" with single-line tool and reasoning rows for all users
  • Add @ file and # GitHub ref completions in relay sessions
  • Show the correct session age when filesystem birthtime is missing
  • Prevent duplicate final assistant messages for GPT models
  • Terminal title updates work in more terminals
  • Show a (sandboxed) badge on compact Search timeline entries
  • Git commands work in sandboxed linked worktrees
  • Show the current pull request link as a status-line item
  • Show quota snapshots for WebSocket Responses requests
  • Show accurate Anthropic reasoning token counts
  • Let grep and glob retry blocked searches after sandbox approval
  • Format terminal titles with the session title and GitHub Copilot suffix
  • Skip synchronized output under tmux to avoid mouse pointer flicker
  • Session limits now apply across the current conversation, reset on /clear, and use the sessionLimits option key.
  • Hide excluded built-in agents from agent selection
  • BYOK sessions using Anthropic models no longer hit HTTP 400 errors from adaptive-thinking mismatches — neither from injecting adaptive thinking on models that don't support it, nor from sending standard thinking to models that require adaptive. Thinking-mode selection for dual-mode models is unchanged.
  • Allow skills with the same name from different plugins to coexist
  • Let integrations read and write CLI user settings
  • View LSP server logs in /lsp logs and read_agent
  • Prompt to install gh CLI when it is missing in GitHub repositories
  • Add GitHub attachment variants to prompt rendering
  • Extension toggles preserve the selected mode
  • Return to the prompt after cancelling attached shell commands
  • Keep background git status checks from disrupting concurrent git commands
  • Recover corrupted session history on load
  • Preserve newlines in /after and /every scheduled prompts
  • Keep multi-line /worktree tasks intact when starting them
  • Make /cd path completion keep Enter, Escape, and Tab behavior in sync
  • Keep session-store searches and context lookups responsive
  • Show desktop notifications on macOS from the CLI
  • Paste WSL images when Windows env vars are unavailable
  • Keep selection on the adjacent task after removing one
  • read_agent since_turn: 0 now correctly returns all turns including turn 0
  • Filter non-JSON stdout lines from MCP servers during startup
  • Perform tokenizer warmup in parallel on a background thread for better startup performance
  • Show submit times next to user prompts in the timeline
  • Improve /share to manage synced session visibility
  • Expand @-style imports in AGENTS.md, CLAUDE.md, and Copilot instruction files
  • Make /pr auto keep working through CI, review, and merge queue
  • Clicking to expand a compact timeline entry holds it in place and reveals its content downward
  • Configure subagent concurrency and depth limits in /settings (usage-based billing users)
  • Add /chronicle skills review for reviewing proposed draft skill changes, with options to accept, reject, or defer each draft
  • Add desktop notifications for attention prompts and idle sessions
  • Make /share use Mission Control links for session sharing
  • Snapshot creation retries transient HEAD lookup failures instead of crashing
  • Keep /chronicle reindex responsive and show progress in the timeline
  • Return to the last open GitHub issue, pull request, or gist view when switching tabs
  • Resolve package argument placeholders when installing MCP registry entries
  • Keep queued messages from getting stuck behind background work
  • Retry managed settings fetch after transient connection-pool errors
  • Stop showing broken-pipe errors when a sandboxed MCP server exits mid-request
  • Properly recover MCP host-delegated connections when OAuth tokens expire or need broader scopes
  • CLI git checks skip optional locks so status and branch lookups keep working in busy repositories
  • Collapse multi-line sub-items into one inline line in compact timeline rows
  • Inline hook settings now handle nested Claude-style hook groups correctly
  • Keep the CLI responsive during secret filtering
  • Search inputs match queries that have leading or trailing whitespace
  • Keep idle agents available after you cancel a turn
  • Show sandbox-bypass warnings and label bypassed commands
  • /pr auto now starts a self-paced loop that fixes one thing per run and paces itself around CI to drive the PR to green; /pr automerge keeps going until the PR is merged. Manage or stop it from /loop or /every.
  • Enable /rename in remote-hosted (cloud and relay) sessions
  • Add toggle to enable or disable MCP servers in the CLI from MCP list view
  • Add experimental response limits controls to CLI settings
  • Let managed settings configure OpenTelemetry export
  • MCP tools on OAuth-authenticated remote servers now recover automatically after a mid-session token expiry, matching the existing OIDC retry behaviour. A 401 during a tool call triggers a non-interactive reconnect, and servers needing interactive re-auth are retried at the start of the next turn.
  • Add persisted dynamicRetrieval setting (and --dynamic-retrieval skills=<on|off> flag) to enable or disable embeddings-based retrieval of skills
  • Let custom agents set reasoning effort in their definitions
  • Pass a task to /worktree (e.g. 'fix the login redirect') to name the branch for that task and run the sentence as the first prompt in the new worktree
  • Added runtime telemetry for the MCP host token-injection OAuth flow, recording when an OAuth broadcast is emitted to the host and how the host responds (token or cancelled) with response latency
  • Show merge status for each pull request in the Pull requests tab, and refresh the cached statuses on demand by pressing r
  • Fix a soft hang where the CLI stopped responding to input if a startup prompt (folder trust, screen reader, or Copilot free signup) opened while a non-Main home tab was focused
  • Guide the agent to format cross-repository issue/PR references as owner/repo#number (reserving bare #number for the current repo) so they don't mislink to the current repository
  • Keep /restart working when shutdown teardown takes too long
  • Copy text to the clipboard on WSL when cmd.exe is not on PATH
  • COPILOT_HOME and --config-dir stop loading skills from ~/.agents/skills
  • Keep per-extension disabled selections when switching extension mode in /extensions
  • Copying wrapped text from the scroll view keeps spacing correct
  • Voice mode turns itself off when the engine fails to start at boot
  • Quit cleanly with Ctrl+D during startup before authentication completes
  • Keep framed user messages from clipping trailing characters at the right edge
  • Inline images stop writing to the shell after exit
  • Display descriptions for slash command subcommands
  • Refresh MCP server headers automatically after authentication changes
  • LSP commands and tools resolve project configs and server paths more reliably
  • Add --allow-all-mcp-server-instructions to optionally include instructions from all MCP servers in system prompts
  • Auto-accept opt-in MCP consent prompts in --yolo sessions while still showing system permission prompts
  • Use the full terminal height in full-screen views
  • Use clearer icons for shell and search timeline entries
  • Match the terminal text color to the GitHub theme canvas
  • Show the active agent mode in the working footer text
  • /worktree keeps a valid branch name exactly as typed, e.g. feature/JIRA-123, instead of flattening it to a slug like feature-jira-123
  • With no argument, /worktree names the branch from your uncommitted changes and recent conversation using your active model instead of a fixed small one
  • Consolidate color palette settings under /settings theme
  • Store CLI settings and session state more reliably
Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

How ChatGPT adoption has expanded

1 Share
New OpenAI Signals data shows how ChatGPT adoption is growing globally, with users increasing usage, exploring more capabilities, and driving growth across regions and languages.
Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Introducing Claude Sonnet 5

1 Share
Introducing Claude Sonnet 5
Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories