@michaelschnyder/teams-cli 0.2.0-canary.7.1.g64541e1a → 0.2.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.
- package/README.md +1 -1
- package/dist/build-info.json +15 -17
- package/dist/cli.js +1 -0
- package/dist/commands/version.js +50 -20
- package/dist/skills/teams-cli/SKILL.md +1 -1
- package/dist/update.js +1 -1
- package/dist/upgrade.js +97 -0
- package/docs/releasing.md +4 -2
- package/docs/use/commands.md +3 -1
- package/docs/use/installation.md +9 -7
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ Person, chat, channel, and message commands support `--json`. JSON payloads stay
|
|
|
109
109
|
| Command | Purpose | Examples and details |
|
|
110
110
|
| --- | --- | --- |
|
|
111
111
|
| `login` | Sign in using the default session; alias for `auth login` | [Authentication](docs/use/authentication.md) |
|
|
112
|
-
| `version` | Inspect build provenance,
|
|
112
|
+
| `version` | Inspect build provenance, install updates, or switch stable/canary channels | [Installation and upgrades](docs/use/installation.md) |
|
|
113
113
|
| `skills` | List, locate, install, and refresh the packaged agent skill | [Agent skill installation](docs/use/agent-skills.md) |
|
|
114
114
|
| `doctor` | Diagnose the local runtime, browser, session, and managed skills without changing them | [Installation and upgrades](docs/use/installation.md#troubleshooting) |
|
|
115
115
|
| `auth` | Login, refresh, inspect, export tokens, or logout | [Authentication](docs/use/authentication.md) |
|
package/dist/build-info.json
CHANGED
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.2.0
|
|
4
|
-
"channel": "
|
|
5
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"channel": "stable",
|
|
5
|
+
"builtAt": "2026-09-04T11:47:26.658Z",
|
|
6
6
|
"source": {
|
|
7
|
-
"branch": "
|
|
8
|
-
"commit": "
|
|
9
|
-
"commitUrl": "https://github.com/michaelschnyder/teams-cli/commit/
|
|
10
|
-
"
|
|
11
|
-
"pullRequestUrl": "https://github.com/michaelschnyder/teams-cli/pull/14",
|
|
12
|
-
"author": "michaelschnyder"
|
|
7
|
+
"branch": "main",
|
|
8
|
+
"commit": "0f109289ab1398dbf4c8717bb91df07588a96bc0",
|
|
9
|
+
"commitUrl": "https://github.com/michaelschnyder/teams-cli/commit/0f109289ab1398dbf4c8717bb91df07588a96bc0",
|
|
10
|
+
"author": "Michael Schnyder <michael.schnyder@outlook.com>"
|
|
13
11
|
},
|
|
14
12
|
"trigger": {
|
|
15
|
-
"kind": "
|
|
13
|
+
"kind": "release",
|
|
16
14
|
"actor": "michaelschnyder"
|
|
17
15
|
},
|
|
18
16
|
"runner": {
|
|
19
|
-
"name": "GitHub Actions
|
|
17
|
+
"name": "GitHub Actions 1000001109",
|
|
20
18
|
"os": "Linux",
|
|
21
19
|
"architecture": "X64"
|
|
22
20
|
},
|
|
23
21
|
"workflow": {
|
|
24
|
-
"runId": "
|
|
25
|
-
"runNumber": "
|
|
22
|
+
"runId": "33869547336",
|
|
23
|
+
"runNumber": "11",
|
|
26
24
|
"runAttempt": "1",
|
|
27
|
-
"url": "https://github.com/michaelschnyder/teams-cli/actions/runs/
|
|
25
|
+
"url": "https://github.com/michaelschnyder/teams-cli/actions/runs/33869547336"
|
|
28
26
|
},
|
|
29
27
|
"releaseNotes": {
|
|
30
|
-
"title": "
|
|
31
|
-
"body": "##
|
|
32
|
-
"url": "https://github.com/michaelschnyder/teams-cli/
|
|
28
|
+
"title": "Teams CLI v0.2.0",
|
|
29
|
+
"body": "## Highlights\n\n### Create workspace safeguards visually\n\n`teams-cli policy edit --open` now launches a local policy editor where you can choose which people, group chats, and channels may be read or posted to. You can review the generated policy, save a draft, and activate it when ready.\n\nRead and post access are configured independently, explicit denials take priority, and overlapping active policies can only narrow access. The editor keeps Teams credentials and message content out of the browser UI.\n\n### Get started with fewer identifiers and commands\n\n- `teams-cli login` signs in and discovers the default tenant and user automatically. Most users no longer need to provide tenant IDs, user IDs, or named profiles.\n- `teams-cli message send --person alice@example.com --body \"Hello\"` can find or start a direct conversation without requiring you to discover a chat ID first.\n- `teams-cli chat search \"Alice\" --json` uses bounded, server-ranked search instead of downloading your complete chat collection.\n\n### Set up coding agents more easily\n\nThe packaged guidance is now one consolidated `teams-cli` skill covering authentication, discovery, reading, messaging, and policies. `teams-cli skills install` installs or refreshes it for supported filesystem-based agents and migrates managed skills from version 0.1 automatically.\n\nClaude Desktop users also receive a versioned Cowork skill ZIP that can be uploaded through Cowork's skill settings. Interactive first-time login can offer agent-skill setup before authentication.\n\n### Diagnose local setup problems\n\nThe new `teams-cli doctor` command checks Node.js and browser availability, the selected identity, session health, managed skills, and detected agent environments without changing your configuration or contacting Teams. Use `teams-cli doctor --json` for structured output.\n\n### Try upcoming builds and stay updated\n\nThe CLI now supports stable and canary update channels, plus immutable branch snapshots for targeted testing. `teams-cli version` shows the installed channel, build provenance, release notes, and available updates. Globally installed stable and canary versions can update themselves with `teams-cli version --upgrade`; snapshot builds remain pinned until you explicitly switch channels.\n\n## Upgrade\n\nFor a global npm installation, run:\n\n```console\nteams-cli version --upgrade\n```\n\nYou can also install the release directly:\n\n```console\nnpm install --global @michaelschnyder/teams-cli@latest\n```\n\nIf you created a policy with version 0.1, open `teams-cli policy edit --open` and recreate it using the new people, group-chat, and channel read/post permissions. The previous `messageSend` policy shape is no longer accepted.\n\n> [!WARNING]\n> This project uses unsupported Microsoft Teams private APIs. Microsoft may change or block them without notice. Obtain organizational approval before use.\n",
|
|
30
|
+
"url": "https://github.com/michaelschnyder/teams-cli/releases/tag/v0.2.0"
|
|
33
31
|
}
|
|
34
32
|
}
|
package/dist/cli.js
CHANGED
|
@@ -466,6 +466,7 @@ export function createProgram(options = {}) {
|
|
|
466
466
|
.showHelpAfterError();
|
|
467
467
|
const versionOptions = {
|
|
468
468
|
...(options.storageRoot ? { storageRoot: options.storageRoot } : {}),
|
|
469
|
+
confirm: interactiveAuth.confirm,
|
|
469
470
|
...(options.fetcher ? { fetcher: options.fetcher } : {}),
|
|
470
471
|
...(options.environment ? { environment: options.environment } : {}),
|
|
471
472
|
};
|
package/dist/commands/version.js
CHANGED
|
@@ -2,7 +2,8 @@ import { Option } from "commander";
|
|
|
2
2
|
import { stripVTControlCharacters } from "node:util";
|
|
3
3
|
import { storagePaths } from "../storage.js";
|
|
4
4
|
import { resolveUpdateChannel, saveUpdateChannel } from "../settings.js";
|
|
5
|
-
import { checkForUpdate, isNpxExecution, updateChecksDisabled } from "../update.js";
|
|
5
|
+
import { checkForUpdate, isNpxExecution, latestForChannel, updateChecksDisabled } from "../update.js";
|
|
6
|
+
import { canUpgradeCli, upgradeCli } from "../upgrade.js";
|
|
6
7
|
import { BUILD_INFO, CLI_VERSION, PACKAGE_NAME } from "../version.js";
|
|
7
8
|
function safe(value) {
|
|
8
9
|
return stripVTControlCharacters(value).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "");
|
|
@@ -47,7 +48,7 @@ export function renderVersion(info, channel, candidate, updateStatus = candidate
|
|
|
47
48
|
lines.push(safe(candidate.summary.summary));
|
|
48
49
|
if (candidate.summary?.url)
|
|
49
50
|
lines.push(safe(candidate.summary.url));
|
|
50
|
-
lines.push(`
|
|
51
|
+
lines.push(`For a global npm installation, run \`teams-cli version --upgrade\`. Otherwise update through the package manager and installation scope that installed the CLI, targeting ${PACKAGE_NAME}@${candidate.version}.`);
|
|
51
52
|
}
|
|
52
53
|
else if (updateStatus === "current") {
|
|
53
54
|
lines.push("", "No update is currently available.");
|
|
@@ -58,12 +59,13 @@ async function versionDetails(options) {
|
|
|
58
59
|
const environment = options.environment ?? process.env;
|
|
59
60
|
const stdout = options.stdout ?? process.stdout;
|
|
60
61
|
const stderr = options.stderr ?? process.stderr;
|
|
62
|
+
const buildInfo = options.buildInfo ?? BUILD_INFO;
|
|
61
63
|
const paths = storagePaths(options.storageRoot);
|
|
62
|
-
const channel = await resolveUpdateChannel({ paths, environment, installedChannel:
|
|
64
|
+
const channel = await resolveUpdateChannel({ paths, environment, installedChannel: buildInfo.channel });
|
|
63
65
|
const npx = isNpxExecution(environment);
|
|
64
66
|
let candidate = null;
|
|
65
67
|
let updateStatus = "current";
|
|
66
|
-
if (
|
|
68
|
+
if (buildInfo.channel === "snapshot")
|
|
67
69
|
updateStatus = "pinned";
|
|
68
70
|
else if (npx)
|
|
69
71
|
updateStatus = "npx";
|
|
@@ -71,7 +73,7 @@ async function versionDetails(options) {
|
|
|
71
73
|
updateStatus = "disabled";
|
|
72
74
|
else {
|
|
73
75
|
try {
|
|
74
|
-
candidate = await checkForUpdate(
|
|
76
|
+
candidate = await checkForUpdate(buildInfo.version, channel, options.fetcher);
|
|
75
77
|
updateStatus = candidate ? "available" : "current";
|
|
76
78
|
}
|
|
77
79
|
catch {
|
|
@@ -79,48 +81,76 @@ async function versionDetails(options) {
|
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
if (options.json) {
|
|
82
|
-
stdout.write(`${JSON.stringify({ installed:
|
|
84
|
+
stdout.write(`${JSON.stringify({ installed: buildInfo, updateChannel: channel, update: { status: updateStatus, candidate } }, null, 2)}\n`);
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
|
-
stdout.write(renderVersion(
|
|
87
|
+
stdout.write(renderVersion(buildInfo, channel, candidate, updateStatus));
|
|
86
88
|
if (updateStatus === "pinned")
|
|
87
89
|
stderr.write("Snapshot builds are pinned. Replace this build explicitly through your package manager to leave the snapshot.\n");
|
|
88
90
|
if (updateStatus === "npx")
|
|
89
91
|
stderr.write("This temporary npx execution manages its version through the package spec, not the CLI updater.\n");
|
|
90
92
|
if (updateStatus === "unavailable")
|
|
91
93
|
stderr.write("The npm registry could not be checked; installed build information is still complete.\n");
|
|
94
|
+
if (candidate && options.allowPrompt && options.confirm && await (options.canUpgrade ?? canUpgradeCli)() &&
|
|
95
|
+
await options.confirm(`Install teams-cli ${candidate.version}?`)) {
|
|
96
|
+
stderr.write(`Upgrading teams-cli to ${candidate.version} through npm…\n`);
|
|
97
|
+
await (options.upgrader ?? upgradeCli)({ targetVersion: candidate.version });
|
|
98
|
+
stdout.write("teams-cli and recorded skill installations are up to date.\n");
|
|
99
|
+
}
|
|
92
100
|
}
|
|
93
101
|
async function changeChannel(channel, options) {
|
|
94
102
|
const environment = options.environment ?? process.env;
|
|
95
103
|
if (isNpxExecution(environment)) {
|
|
96
|
-
throw new Error(`Cannot
|
|
104
|
+
throw new Error(`Cannot switch an installation channel from npx. Run \`npx --prefer-online ${PACKAGE_NAME}@${channel === "stable" ? "latest" : "canary"} --version\` instead.`);
|
|
97
105
|
}
|
|
98
106
|
const paths = storagePaths(options.storageRoot);
|
|
99
|
-
await
|
|
100
|
-
|
|
101
|
-
(options.
|
|
102
|
-
|
|
103
|
-
(
|
|
107
|
+
const candidate = await latestForChannel(channel, options.fetcher);
|
|
108
|
+
(options.stderr ?? process.stderr).write(`Switching teams-cli to ${channel} (${candidate.version})…\n`);
|
|
109
|
+
await (options.upgrader ?? upgradeCli)({
|
|
110
|
+
targetVersion: candidate.version,
|
|
111
|
+
onInstalled: () => saveUpdateChannel(paths, channel),
|
|
112
|
+
});
|
|
113
|
+
(options.stdout ?? process.stdout).write(`teams-cli now follows the ${channel} channel at ${candidate.version}.\n`);
|
|
114
|
+
}
|
|
115
|
+
async function upgradeCurrent(options) {
|
|
116
|
+
const environment = options.environment ?? process.env;
|
|
117
|
+
if (isNpxExecution(environment)) {
|
|
118
|
+
throw new Error(`Cannot upgrade a temporary npx execution. Run \`npx --prefer-online ${PACKAGE_NAME}@latest --version\` instead.`);
|
|
119
|
+
}
|
|
120
|
+
const buildInfo = options.buildInfo ?? BUILD_INFO;
|
|
121
|
+
if (buildInfo.channel === "snapshot") {
|
|
122
|
+
throw new Error("Snapshot builds are pinned. Use `teams-cli version --channel stable` or `--channel canary` to leave this snapshot.");
|
|
104
123
|
}
|
|
124
|
+
const paths = storagePaths(options.storageRoot);
|
|
125
|
+
const channel = await resolveUpdateChannel({ paths, environment, installedChannel: buildInfo.channel });
|
|
126
|
+
const candidate = await latestForChannel(channel, options.fetcher);
|
|
127
|
+
(options.stderr ?? process.stderr).write(`Upgrading teams-cli on ${channel} to ${candidate.version}…\n`);
|
|
128
|
+
await (options.upgrader ?? upgradeCli)({ targetVersion: candidate.version });
|
|
129
|
+
(options.stdout ?? process.stdout).write("teams-cli and recorded skill installations are up to date.\n");
|
|
105
130
|
}
|
|
106
131
|
export function registerVersionCommand(program, options = {}) {
|
|
107
132
|
program.command("version")
|
|
108
|
-
.description("Show build provenance
|
|
109
|
-
.
|
|
133
|
+
.description("Show build provenance, manage the update channel, or upgrade a global npm installation")
|
|
134
|
+
.option("--upgrade", "Install the newest version from the effective channel")
|
|
135
|
+
.addOption(new Option("--channel <channel>", "Switch a global npm installation channel").choices(["stable", "canary"]))
|
|
110
136
|
.option("--json", "Output structured build and update information")
|
|
111
137
|
.action(async (commandOptions) => {
|
|
112
|
-
if (commandOptions.
|
|
113
|
-
throw new Error("--
|
|
138
|
+
if (commandOptions.channel && commandOptions.upgrade)
|
|
139
|
+
throw new Error("--channel already installs the newest version and cannot be combined with --upgrade");
|
|
140
|
+
if (commandOptions.json && (commandOptions.channel || commandOptions.upgrade))
|
|
141
|
+
throw new Error("--json cannot be combined with --channel or --upgrade");
|
|
114
142
|
if (commandOptions.channel)
|
|
115
143
|
return changeChannel(commandOptions.channel, options);
|
|
116
|
-
|
|
144
|
+
if (commandOptions.upgrade)
|
|
145
|
+
return upgradeCurrent(options);
|
|
146
|
+
return versionDetails({ ...options, json: commandOptions.json === true, allowPrompt: true });
|
|
117
147
|
});
|
|
118
148
|
}
|
|
119
149
|
export async function showAdaptiveVersion(options = {}) {
|
|
120
150
|
const stdout = options.stdout ?? process.stdout;
|
|
121
151
|
if (!stdout.isTTY) {
|
|
122
|
-
stdout.write(`${CLI_VERSION}\n`);
|
|
152
|
+
stdout.write(`${options.buildInfo?.version ?? CLI_VERSION}\n`);
|
|
123
153
|
return;
|
|
124
154
|
}
|
|
125
|
-
await versionDetails(options);
|
|
155
|
+
await versionDetails({ ...options, allowPrompt: true });
|
|
126
156
|
}
|
package/dist/update.js
CHANGED
|
@@ -135,7 +135,7 @@ export async function prepareUpdateNotification(options) {
|
|
|
135
135
|
if (state && state.channel === channel && state.pendingVersion && isNewerVersion(options.currentVersion, state.pendingVersion)) {
|
|
136
136
|
const description = state.pendingSummary?.title ? ` ${state.pendingSummary.title}.` : "";
|
|
137
137
|
(options.stderr ?? process.stderr).write(`A new teams-cli ${channel} version is available: ${options.currentVersion} → ${state.pendingVersion}.${description} ` +
|
|
138
|
-
`
|
|
138
|
+
`For a global npm installation, run \`teams-cli version --upgrade\`. Otherwise update through the package manager and installation scope that installed it, targeting ${PACKAGE_NAME}@${state.pendingVersion}.\n`);
|
|
139
139
|
const consumed = { ...state };
|
|
140
140
|
delete consumed.pendingVersion;
|
|
141
141
|
delete consumed.pendingSummary;
|
package/dist/upgrade.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve, win32 } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { PACKAGE_NAME } from "./version.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const PACKAGE_ROOT = dirname(fileURLToPath(new URL("../package.json", import.meta.url)));
|
|
9
|
+
export function npmInvocation(platform = process.platform, nodeExecutable = process.execPath, npmExecPath = process.env.npm_execpath) {
|
|
10
|
+
if (npmExecPath)
|
|
11
|
+
return { command: nodeExecutable, args: [npmExecPath] };
|
|
12
|
+
if (platform === "win32") {
|
|
13
|
+
return {
|
|
14
|
+
command: nodeExecutable,
|
|
15
|
+
args: [win32.join(win32.dirname(nodeExecutable), "node_modules", "npm", "bin", "npm-cli.js")],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return { command: "npm", args: [] };
|
|
19
|
+
}
|
|
20
|
+
async function defaultGlobalRoot(npm) {
|
|
21
|
+
const { stdout } = await execFileAsync(npm.command, [...npm.args, "root", "--global"], {
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
windowsHide: true,
|
|
24
|
+
});
|
|
25
|
+
const root = stdout.trim();
|
|
26
|
+
if (!root)
|
|
27
|
+
throw new Error("npm returned no global package root");
|
|
28
|
+
return root;
|
|
29
|
+
}
|
|
30
|
+
function comparablePath(path, platform) {
|
|
31
|
+
const absolute = resolve(path);
|
|
32
|
+
return platform === "win32" ? absolute.toLowerCase() : absolute;
|
|
33
|
+
}
|
|
34
|
+
export async function resolveGlobalNpmInstallation(options = {}) {
|
|
35
|
+
const platform = options.platform ?? process.platform;
|
|
36
|
+
const npm = options.npm ?? npmInvocation(platform);
|
|
37
|
+
let globalRoot;
|
|
38
|
+
try {
|
|
39
|
+
globalRoot = await (options.globalRoot ?? defaultGlobalRoot)(npm);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const detail = error instanceof Error ? `: ${error.message}` : "";
|
|
43
|
+
throw new Error(`Cannot verify the npm global installation scope${detail}`);
|
|
44
|
+
}
|
|
45
|
+
const packageRoot = options.packageRoot ?? PACKAGE_ROOT;
|
|
46
|
+
const expectedRoot = join(globalRoot, ...PACKAGE_NAME.split("/"));
|
|
47
|
+
const canonicalize = options.canonicalize ?? realpathSync;
|
|
48
|
+
let actual;
|
|
49
|
+
let expected;
|
|
50
|
+
try {
|
|
51
|
+
actual = canonicalize(packageRoot);
|
|
52
|
+
expected = canonicalize(expectedRoot);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error("Cannot verify that this teams-cli package belongs to npm's global installation scope");
|
|
56
|
+
}
|
|
57
|
+
if (comparablePath(actual, platform) !== comparablePath(expected, platform)) {
|
|
58
|
+
throw new Error("Automatic upgrade is available only for a global npm installation managed by the active npm executable. " +
|
|
59
|
+
"Update this package through the package manager and installation scope that installed it.");
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
npm,
|
|
63
|
+
globalRoot,
|
|
64
|
+
packageRoot: actual,
|
|
65
|
+
installedCli: join(expectedRoot, "dist", "cli.js"),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function canUpgradeCli(options = {}) {
|
|
69
|
+
try {
|
|
70
|
+
await resolveGlobalNpmInstallation(options);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const defaultRunner = (command, args) => new Promise((resolveRun, reject) => {
|
|
78
|
+
const child = spawn(command, [...args], { stdio: "inherit", shell: false, windowsHide: true });
|
|
79
|
+
child.once("error", reject);
|
|
80
|
+
child.once("exit", (code) => resolveRun(code ?? 1));
|
|
81
|
+
});
|
|
82
|
+
export async function upgradeCli(options = {}) {
|
|
83
|
+
const installation = await resolveGlobalNpmInstallation(options);
|
|
84
|
+
const runner = options.runner ?? defaultRunner;
|
|
85
|
+
const targetVersion = options.targetVersion ?? "latest";
|
|
86
|
+
const installStatus = await runner(installation.npm.command, [...installation.npm.args, "install", "--global", `${PACKAGE_NAME}@${targetVersion}`]);
|
|
87
|
+
if (installStatus !== 0)
|
|
88
|
+
throw new Error(`npm upgrade failed with exit code ${installStatus}`);
|
|
89
|
+
if (!(options.pathExists ?? existsSync)(installation.installedCli)) {
|
|
90
|
+
throw new Error(`The updated CLI was not found at ${installation.installedCli}`);
|
|
91
|
+
}
|
|
92
|
+
await options.onInstalled?.();
|
|
93
|
+
const reinstallStatus = await runner(process.execPath, [installation.installedCli, "skills", "reinstall"]);
|
|
94
|
+
if (reinstallStatus !== 0) {
|
|
95
|
+
throw new Error(`The CLI was upgraded, but skill reinstallation failed with exit code ${reinstallStatus}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/docs/releasing.md
CHANGED
|
@@ -37,7 +37,7 @@ Published npm versions are immutable. If a release is defective, fix it in a new
|
|
|
37
37
|
|
|
38
38
|
## Canary releases
|
|
39
39
|
|
|
40
|
-
Merging a pull request into `main` publishes one prerelease to the `canary` npm tag after the resulting main-branch CI run passes on Ubuntu, macOS, and Windows. The publishing workflow consumes that successful CI result instead of repeating the operating-system matrix. A direct commit to `main` does not publish. Stable releases
|
|
40
|
+
Merging a pull request into `main` publishes one prerelease to the `canary` npm tag after the resulting main-branch CI run passes on Ubuntu, macOS, and Windows. The publishing workflow consumes that successful CI result instead of repeating the operating-system matrix. A direct commit to `main` does not publish. Stable releases run package verification on Ubuntu without repeating the dependency audit that already gates `main`; manually requested snapshots include the audit because their selected branch might not have passed `main` CI. The workflow uses the package version when it is already greater than npm's latest stable release; otherwise it assumes the next patch. Versions include the workflow run, attempt, and source commit, while the package embeds the pull request notes and build provenance.
|
|
41
41
|
|
|
42
42
|
Install or follow this channel with:
|
|
43
43
|
|
|
@@ -46,8 +46,10 @@ npm install --global @michaelschnyder/teams-cli@canary
|
|
|
46
46
|
teams-cli version --channel canary
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
The npm command is useful when installing canary for the first time or upgrading from a release that predates channel switching. Once the channel-aware CLI is installed globally through npm, `version --channel canary` installs the newest canary and records the selection.
|
|
50
|
+
|
|
49
51
|
## Branch snapshots
|
|
50
52
|
|
|
51
53
|
Repository contributors with write, maintain, or admin permission can run the publish workflow from `main` and enter a repository branch to snapshot. Manual runs are automatically classified as snapshot publications. The workflow verifies that the requested branch and checked-out commit belong to this repository; fork refs and dispatches using a modified branch workflow are not accepted. It publishes an immutable `snapshot` prerelease, associates an npm tag with the selected branch, and prints exact global-install and npx commands in its summary. Canary summaries provide both commands as well.
|
|
52
54
|
|
|
53
|
-
Snapshots never update automatically. Testers leave a snapshot
|
|
55
|
+
Snapshots never update automatically and `version --upgrade` refuses to replace them. Testers with a global npm installation can leave a snapshot explicitly with `version --channel stable` or `version --channel canary`; other installation scopes must use their owning package manager.
|
package/docs/use/commands.md
CHANGED
|
@@ -8,9 +8,11 @@ The default session created by `teams-cli login` or `teams-cli auth login` is us
|
|
|
8
8
|
teams-cli --version
|
|
9
9
|
teams-cli version
|
|
10
10
|
teams-cli version --json
|
|
11
|
+
teams-cli version --upgrade
|
|
12
|
+
teams-cli version --channel canary
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
When piped, `--version` prints only semantic version text. In a terminal, version output includes the installed channel, local build provenance, associated release notes, and any available update. The policy editor shows the same exact version in its footer.
|
|
15
|
+
When piped, `--version` prints only semantic version text. In a terminal, version output includes the installed channel, local build provenance, associated release notes, and any available update. A verified global npm installation can accept the interactive update offer or use `version --upgrade`; npx, snapshots, project dependencies, and installations owned by another package manager are not changed automatically. Use an explicit `--channel stable|canary` to replace a global npm installation and persist that channel after installation succeeds. The policy editor shows the same exact version in its footer.
|
|
14
16
|
|
|
15
17
|
## Diagnose the local setup
|
|
16
18
|
|
package/docs/use/installation.md
CHANGED
|
@@ -80,20 +80,18 @@ At startup, the CLI may launch a detached npm registry check. It runs at most on
|
|
|
80
80
|
Stable installations follow npm's `latest` tag. Switch to builds produced from newly merged pull requests with:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
npm install --global @michaelschnyder/teams-cli@canary
|
|
84
83
|
teams-cli version --channel canary
|
|
85
84
|
```
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
For a global npm installation, this installs the newest canary and records the channel in `~/.teams-cli/settings.yaml` only after installation succeeds. Switch back in the same way:
|
|
88
87
|
|
|
89
88
|
```bash
|
|
90
|
-
npm install --global @michaelschnyder/teams-cli@latest
|
|
91
89
|
teams-cli version --channel stable
|
|
92
90
|
```
|
|
93
91
|
|
|
94
92
|
`TEAMS_CLI_UPDATE_CHANNEL=stable|canary` overrides the recorded channel for the current process. Channel settings are user-wide and deliberately separate from Teams profiles and workspace policies.
|
|
95
93
|
|
|
96
|
-
Contributor snapshots are installed using the exact version shown by their GitHub Actions run. Snapshots are pinned
|
|
94
|
+
Contributor snapshots are installed using the exact version shown by their GitHub Actions run. Snapshots are pinned: they do not perform background update checks and `version --upgrade` refuses to replace them. A globally installed snapshot can leave the pinned build through an explicit `teams-cli version --channel stable` or `--channel canary` command.
|
|
97
95
|
|
|
98
96
|
Disable checks with either environment variable:
|
|
99
97
|
|
|
@@ -103,11 +101,15 @@ export NO_UPDATE_NOTIFIER=1
|
|
|
103
101
|
export TEAMS_CLI_DISABLE_UPDATE_CHECK=1
|
|
104
102
|
```
|
|
105
103
|
|
|
106
|
-
Checks are automatically disabled in CI and temporary npx executions. Inspect local build provenance and any associated release notes with `teams-cli version`, or use `teams-cli version --json` for structured output.
|
|
104
|
+
Checks are automatically disabled in CI and temporary npx executions. Inspect local build provenance and any associated release notes with `teams-cli version`, or use `teams-cli version --json` for structured output. An interactive version check offers to install an available update when the running package is verified as a global npm installation. Upgrade explicitly within the effective stable or canary channel with:
|
|
107
105
|
|
|
108
|
-
|
|
106
|
+
```bash
|
|
107
|
+
teams-cli version --upgrade
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Before making changes, the CLI asks the active npm executable for its global package root and verifies that the running package is the `teams-cli` package at that exact location. It then installs the registry's exact selected version without a command shell and refreshes managed agent-skill copies through the newly installed CLI. This prevents a project dependency, another package manager's installation, or a source checkout from being converted into a global npm package. Those installations receive an exact package target and must be updated through their owning package manager and scope.
|
|
109
111
|
|
|
110
|
-
An npx execution cannot change the persistent
|
|
112
|
+
An npx execution cannot upgrade itself or change the persistent channel. Request the desired package explicitly instead:
|
|
111
113
|
|
|
112
114
|
```bash
|
|
113
115
|
npx --prefer-online @michaelschnyder/teams-cli@latest --help
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michaelschnyder/teams-cli",
|
|
3
|
-
"version": "0.2.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A safety-conscious CLI for persistent Microsoft Teams sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"node": ">=22.20.0"
|
|
67
67
|
},
|
|
68
68
|
"teamsCli": {
|
|
69
|
-
"channel": "
|
|
69
|
+
"channel": "stable",
|
|
70
70
|
"releaseSummary": {
|
|
71
|
-
"title": "
|
|
72
|
-
"summary": "##
|
|
73
|
-
"url": "https://github.com/michaelschnyder/teams-cli/
|
|
71
|
+
"title": "Teams CLI v0.2.0",
|
|
72
|
+
"summary": "## Highlights",
|
|
73
|
+
"url": "https://github.com/michaelschnyder/teams-cli/releases/tag/v0.2.0"
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
}
|