Commit Graph

2055 Commits

Author SHA1 Message Date
Koshkoshinsk eba05bb67e add-teams: take the first non-bot conversation member — the aadObjectId select came back empty on a live run
The 1:1 is created with exactly one member (the owner), so first-non-bot is
correct by construction; .aadObjectId is not reliably present in the members
response and its GUID casing varies. Also default the display name.
Live-run evidence (VM run #7): token + create-conversation with the 28: bot
id and an AAD member id both work; only the members select failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 17:55:43 +03:00
Koshkoshinsk 66b0dbd5c7 add-teams: wire the owner inline — the assistant messages the human first
Same move as Slack/Discord: after the app install, open the bot<->owner 1:1
proactively with the bot credentials. The owner is the Teams-CLI account
that created the bot (teams status --json -> username + AAD object id); the
conversation-members fetch converts that to the 29: id inbound senders carry
and doubles as an identity cross-check; the platform id is composed exactly
as the adapter encodes thread ids. An operator note names who gets wired.
runChannelSkill gains wireIfResolved: a fresh create wires + welcomes like
any channel, a drop-through re-run resolves nothing and keeps the deferred
ending. Logout is now the operator's choice (yes/no prompt) instead of
automatic, and runs after the identity resolve.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 17:26:06 +03:00
Koshkoshinsk fc5d7a6b38 add-teams: retire the finish-wiring infobox; the closing What's-left note carries it
The 4-line operator block duplicated the wizard's ending note and was the
'too much for the average joe' feedback. Setup now says it once, at the very
end; the SKILL.md keeps a one-line prose version for agents applying the
skill outside the wizard. The note gains 'with your coding agent'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:22:52 +03:00
Koshkoshinsk 125aec0617 add-teams: drop ngrok references; Cloudflare Tunnel is the suggestive example
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:40:03 +03:00
Koshkoshinsk 72f6c7e8b2 add-teams: drop the install-libsecret guidance; mark the sideloading probe advisory
The libsecret warning fires even with libsecret installed (headless = no
keyring daemon) and the plaintext fallback persists fine — with the logout
step, nothing lingers either way. The warning is now a one-line 'safe to
ignore'; the AUTH_REQUIRED troubleshooting keeps only the real cause (pnpm
workspace install). The login step's sideloading probe flapped between runs
on the same account — documented as advisory; the install link is the
authoritative test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:35:58 +03:00
Koshkoshinsk b45dc2dc42 add-teams: sign out of the Teams CLI once the bot exists
The M365 session is only needed to create the bot — the adapter runs on the
.env app credentials. On a headless box the session is a plaintext token
file, so setup no longer leaves it on disk. teams logout is idempotent;
later CLI maintenance just needs a fresh teams login (device code).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:52:05 +03:00
Koshkoshinsk 0bcc3a74b1 add-teams: note that the login step's 'Azure CLI: not installed' line is informational
The CLI-first flow creates a Teams-managed bot so az is never needed; the
line only matters for --azure bots and the manual portal path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:40:00 +03:00
Koshkoshinsk 8f9ecd9592 setup: on a deferred wire the last box is the remaining action, not 'go say hi'
Teams ended with two conflicting banners: 'What's left: DM your bot' followed
by 'Check your Teams — your assistant is saying hi' (no welcome DM exists on
a deferred wire). The pending flag now gates the ending: What's left moves to
the final slot in the bright banner style, Go say hi only shows for channels
that actually sent a welcome.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:12:26 +03:00
Koshkoshinsk 8772306627 add-teams: default to single-tenant without asking; multi-tenant becomes a manual alternative
The tenant fork cost every user a question that is almost always 'single'.
Create is unconditional --sign-in-audience myOrg again; the prereqs infobox
notes the default and points multi-tenant users at Alternatives, which
regains a manual multi-tenant section (create command + MultiTenant env
pairing without tenant ID).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:41:54 +03:00
Koshkoshinsk 8644e6bedb setup: verify treats a defer-wire channel awaiting its first DM as pending, not failed
Teams can't wire during setup (platform id only exists after the first
inbound), so a fresh teams-only install always ended 'A few things still
need your attention' + a debug offer. Zero groups now passes verify when
every configured channel is defer-wire and service+credentials are healthy;
the block gains WIRING=pending_first_dm and auto.ts prints a one-line
finish-wiring reminder instead. A wire-during-setup channel with zero
groups still fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:48:26 +03:00
Koshkoshinsk 571d72ba47 add-teams: silence pnpm-inherited npm config noise; document benign libsecret warning
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:46:21 +03:00
Koshkoshinsk 37e2d2b2bb add-teams: prompt for app/bot name and single-vs-multi tenant in both flows
The create step hardcoded --name NanoClaw and single-tenant; both are the
human's choice. Two new nc:prompt fences (app_name, tenant) feed a tenant-
branched create + env pairing — when:tenant=multi omits TEAMS_APP_TENANT_ID,
encoding the 401 pairing rule in the branch itself. Client-secret name and a
separate Azure bot name are NOT knobs on the CLI path (secret is auto-named
'default', 2y; --name covers registration+bot+Teams app) — documented, and
the manual portal path now names all four asks explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:13:46 +03:00
Koshkoshinsk ca298d3714 add-teams: invoke the Teams CLI by absolute path — npm's global bin dir is not reliably on PATH
Run #3 on the VM: the global install fully succeeded (bin linked, keytar
binary built — this npm's allowScripts gate is advisory-only), but the box
exposes node via hand-picked symlinks in ~/.local/bin and npm's prefix bin
dir (~/node/bin) is not on PATH, so every 'teams …' step died with command
not found. Classic custom-prefix gotcha, so fix it universally: the login
and create fences call "$(npm prefix -g)/bin/teams"; prose points manual
runs at the same path; new Troubleshooting entry for 'teams: command not
found'. Test matchers updated for the absolute-path command shape.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 01:05:49 +03:00
Koshkoshinsk d9859fd59a add-teams: install the Teams CLI globally via npm — pnpm's build-script policy breaks its credential store
Proven on the VM: as a workspace dep, keytar (msal-node-extensions' native
credential store, required at module load) never gets its binary because
pnpm's supply-chain policy skips dependency install scripts — the whole
store fails to import and teams.cli silently falls back to an in-memory
token cache, so every teams command after login starts logged out
(AUTH_REQUIRED ~1s into create). libsecret alone does not fix it; the
import dies before any keyring is touched.

npm install -g (pinned 3.0.2) runs keytar's install script in the global
env, keeps the workspace's onlyBuiltDependencies policy untouched, and
matches Microsoft's own install instruction. All commands drop the
pnpm exec prefix; REMOVE.md uninstalls globally after teams logout; the
AUTH_REQUIRED troubleshooting entry now names both causes (workspace
install, missing libsecret).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 00:57:04 +03:00
Koshkoshinsk ff557092d8 add-teams: verify sign-in persistence in the login step; diagnose libsecret + user-policy failures
Found on a headless Ubuntu box: teams login succeeded but the session died
with the process — libsecret is absent, so msal-node-extensions silently
falls back to an in-memory cache (debug-level log), and teams app create (a
fresh process) fails in ~1s with AUTH_REQUIRED, two steps away from the
cause.

- The login step now re-reads the session from a fresh process
  (teams status --json | grep loggedIn) before declaring success, so a
  non-persisting cache fails AT the sign-in step with prose naming the fix
  (apt install libsecret-1-0).
- Troubleshooting: new AUTH_REQUIRED-after-login entry; sideloading entry
  now distinguishes tenant-level from per-user App setup policy (the login
  output prints which one is blocking).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 00:31:12 +03:00
Koshkoshinsk f6901e01a4 add-teams: Teams-CLI-first credentials flow in SSF directive grammar
One sign-in and one create command replace the ~7-step Azure portal walk:

- have_creds probe runs FIRST (either credential key in .env skips every
  creation step — prompts included — so re-runs drop straight to Restart;
  either-key semantics prevent a partial .env from pairing a new app with
  stale keys, the guaranteed-401 mismatch).
- teams login runs as nc:run effect:step (browser locally, device code over
  SSH; body emits the terminal status block the streaming exec requires).
- teams app create --json is one effect:external with a five-var JSON
  capture (CLIENT_ID/CLIENT_SECRET/TENANT_ID + teamsAppId + installLink),
  validate:^.+$ so a shape drift bounces instead of writing empty creds.
  Single-tenant (--sign-in-audience myOrg) is the default pairing; the CLI
  registers a Teams-managed bot — no Azure subscription, no manifest zip,
  no manual sideload.
- Webhook endpoint corrected everywhere: /webhook/teams (was
  /api/webhooks/teams, which silently receives nothing).
- Portal walk + multi-tenant variant moved to prose Alternatives; RSC via
  teams app rsc add (CLI path) or manifest --rsc re-sideload (manual path).
- REMOVE.md: teams logout before CLI uninstall (MSAL cache outlives the
  package), Entra deletion required on both paths (it revokes the secret),
  drop the retired data/env mirror step.
- Parity tests rewritten: drop-through fixture (creds present → no create,
  no prompts, fail() spy), runSkill-level fresh-create fixture (injected
  execStream; proves capture→env-set chain + substituted install-link URL
  offer), probe semantics executed from the shipped document, policy gate
  inventory updated (3 operators, 1 barrier).
- claude-assist: point teams handoff file lists at files that exist on
  this branch.

Known deferrals (engine-owned, flagged for the SSF branch owner):
reuseFromEnv offers capture-var env keys on re-runs (needs a one-line
promptShape guard); effect:external is not run-health gated; captures
cannot be marked secret. docs/skill-engine-seam.md line anchors into the
old teams SKILL.md are stale (pre-existing anchoring style).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 00:12:28 +03:00
Koshkoshinsk 36a7e3cf81 teams-manifest: in-process zip writer, --rsc, independent-reader tests
- Write the app-package zip in-process (stored entries, byte-deterministic,
  fixed DOS timestamp) instead of shelling out to an external `zip` binary.
- Add the rsc option: authorization.permissions.resourceSpecific +
  webApplicationInfo (RSC consent binds to webApplicationInfo.id, not
  bots[].botId) and a manifest version bump so a re-upload supersedes the
  original package. Plumbed through teams-manifest-build.ts as --rsc.
- New test suite parses the zip with an independent minimal reader
  (EOCD → central directory → local headers) so a structure Teams would
  reject goes red; builds run in beforeAll with tmpdir cleanup.

Ported from the parked main-based commit (tag backup/teams-cli-main-cf56c10).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 00:12:03 +03:00
gavrielc 2242f6c997 feat(skills): port Slack Socket Mode into add-slack — when:-guarded delivery modes
Upstream added Socket Mode to the guided setup (cf8478ff) in the bespoke
setup/channels/slack.ts this branch deleted. The port expresses it the way
the engine was built for: a `connection` prompt (socket|webhook) with
when:-guarded branches —

- socket: app-level token walkthrough (connections:write scope, Socket Mode
  toggle), `nc:prompt app_token` (xapp-, reuse:SLACK_APP_TOKEN),
  SLACK_APP_TOKEN env-set. The adapter enables Socket Mode purely from the
  token's presence, so no public URL and no signing secret.
- webhook: the existing signing-secret + Event Subscriptions path, now
  guard-scoped to its branch.

Gate-policy parity holds: all three operator blocks remain prompt-barriered
(no confirms), matching the §5.1 rules; the placeholder-URL negative fixture
moves to operator index 2. Structure-tracking tests updated (directive
order, operator/prompt/env-set inventories, Option-A inputs gain
connection:webhook).

Suite 827 passed | 1 skipped; add-slack lint exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 08:32:19 +03:00
gavrielc 40b65521c0 refactor(skills): retire nc:env-sync — the data/env/env mirror is dead
Upstream removed every setup-side writer of data/env/env (c82f062d) because
nothing has read it since the container mount was dropped — before this
branch even forked. Our engine codified the dead pattern as a directive:
every apply copied the full .env (live tokens included) into a file nothing
consumes.

- engine: env-sync handler removed from selfStatus + applyOne
- grammar: dropped from KNOWN; a new RETIRED table gives a targeted lint
  error ("delete the fence, the adapter reads .env directly") instead of a
  generic unknown-directive message
- skills: fence stripped from the 14 converted skills; orphaned "sync to the
  container" prose cleaned (incl. add-deltachat/add-wechat old-format prose
  upstream's sweep missed); teams troubleshooting entry rewritten
- policy/spec doc lists updated

Suite 827 passed | 1 skipped; all nc: skills lint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 08:27:40 +03:00
gavrielc 81fea1d7ec Merge origin/main (185 commits) into feat/structured-skill-format
Conflict resolutions:
- 9 SKILL.mds we rewrote in the nc: format: kept ours, then bumped every
  @chat-adapter pin 4.26.0 -> 4.29.0 to match the merged chat core (the
  lockstep lint enforces equality; pin-test expectation updated).
- 14 setup/add-*.sh, install-*.sh + setup/channels/{slack,signal,whatsapp}.ts:
  stay deleted — replaced by the directive engine + runChannelSkill. Upstream's
  Slack Socket Mode (cf8478ff, setup-side) will be ported into add-slack's
  SKILL.md as a when:-guarded mode in a follow-up commit.
- src/cli/resources/groups.ts: fused create — upstream's --template branch
  first, else our idempotent-on-folder create with ensureContainerConfig.
- src/cli/registry.ts + dispatch.test.ts: both sides' additions kept
  (hostOnly field/doc + upstream's resource doc and approval-context fixture).

Known follow-ups (next commits): remove the now-dead nc:env-sync directive
(upstream removed the data/env/env mirror writers; the reader died pre-fork),
port Slack Socket Mode into the SKILL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 08:21:49 +03:00
glifocat b6cb53e21c Merge pull request #2953 from nanocoai/docs-staleness-fixes
docs: correct stale mount topology row + removed env var
2026-07-04 23:06:27 +02:00
gavrielc 5a7e75f854 Apply suggestion from @gavrielc 2026-07-04 23:36:05 +03:00
glifocat d770e56596 docs: correct stale mount topology + removed env var vs code 2026-07-04 19:39:13 +00:00
github-actions[bot] 08a1ac9753 chore: bump version to 2.1.38 2026-07-04 16:58:45 +00:00
gavrielc 273489badf Merge pull request #2931 from nanocoai/cleanup/async-image-build
Build agent images asynchronously instead of blocking the host
2026-07-04 19:58:34 +03:00
gavrielc 504651633f Merge branch 'main' into cleanup/async-image-build 2026-07-04 19:58:25 +03:00
github-actions[bot] 694ab74aa1 chore: bump version to 2.1.37 2026-07-04 16:55:14 +00:00
gavrielc aae81321e9 Merge pull request #2948 from nanocoai/cleanup/arch-scheduling-provider-docs
Fix stale architecture, scheduling, provider-config, and overlay docs
2026-07-04 19:55:02 +03:00
gavrielc 6c46b1e43d Merge branch 'main' into cleanup/arch-scheduling-provider-docs 2026-07-04 19:54:49 +03:00
gavrielc 71453707ba Apply suggestion from @gavrielc 2026-07-04 19:54:15 +03:00
gavrielc 0aa9e668f6 Apply suggestion from @gavrielc 2026-07-04 19:53:24 +03:00
gavrielc 023128def5 Merge pull request #2946 from nanocoai/cleanup/remove-env-secrets-mirror
Remove the dead data/env/env secrets mirror
2026-07-04 19:52:00 +03:00
gavrielc c4a1679666 Merge branch 'main' into cleanup/remove-env-secrets-mirror 2026-07-04 19:51:30 +03:00
gavrielc 2e40e17155 Merge pull request #2945 from nanocoai/cleanup/security-docs-v2
Rewrite the security docs to match the v2 perimeter
2026-07-04 19:51:10 +03:00
gavrielc f896caefa0 Merge branch 'main' into cleanup/security-docs-v2 2026-07-04 19:50:59 +03:00
gavrielc 55c003c5f4 Apply suggestion from @gavrielc 2026-07-04 19:50:43 +03:00
gavrielc 20f2bae5cd Apply suggestion from @gavrielc 2026-07-04 19:50:10 +03:00
gavrielc d6b82e6473 Apply suggestion from @gavrielc 2026-07-04 19:47:01 +03:00
gavrielc fea5ac5f2c Apply suggestion from @gavrielc 2026-07-04 19:45:37 +03:00
gavrielc 2b86bbef19 Apply suggestion from @gavrielc 2026-07-04 19:45:04 +03:00
gavrielc 9dc0a7e62f Apply suggestion from @gavrielc 2026-07-04 19:44:33 +03:00
gavrielc 2035033397 Delete docs/docker-sandboxes.md 2026-07-04 19:44:00 +03:00
gavrielc 1c294ff9a5 Delete docs/APPLE-CONTAINER-NETWORKING.md 2026-07-04 19:43:27 +03:00
github-actions[bot] 43198310e1 chore: bump version to 2.1.36 2026-07-04 16:41:48 +00:00
gavrielc b7d6eebf4d Merge pull request #2943 from nanocoai/cleanup/mount-allowlist-readonly-and-cache
Mount allowlist: honor the readOnly key and stop caching parse errors
2026-07-04 19:41:35 +03:00
gavrielc 803f3413ec Merge branch 'main' into cleanup/mount-allowlist-readonly-and-cache 2026-07-04 19:41:26 +03:00
github-actions[bot] a8b7da7bcf docs: update token count to 208k tokens · 104% of context window 2026-07-04 16:40:39 +00:00
github-actions[bot] 0b6ad5550d chore: bump version to 2.1.35 2026-07-04 16:40:37 +00:00
gavrielc c1965cfcaf Merge pull request #2942 from nanocoai/cleanup/a2a-batch-stamp-crossprocess
Fix the agent-to-agent in_reply_to stamp (cross-process no-op)
2026-07-04 19:40:23 +03:00
gavrielc 3cefbfccf4 Merge branch 'main' into cleanup/a2a-batch-stamp-crossprocess 2026-07-04 19:38:09 +03:00