@ekanos/cli 0.15.0 → 0.17.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 +103 -8
- package/dist/auth/ekanos-api.d.ts +23 -0
- package/dist/auth/ekanos-api.js +33 -6
- package/dist/auth/ekanos-api.js.map +1 -1
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +118 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/agents.js +3 -2
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/apps.d.ts +11 -3
- package/dist/commands/apps.js +86 -28
- package/dist/commands/apps.js.map +1 -1
- package/dist/commands/audiences.d.ts +31 -0
- package/dist/commands/audiences.js +239 -0
- package/dist/commands/audiences.js.map +1 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +41 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/catalog.d.ts +4 -2
- package/dist/commands/catalog.js +166 -35
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.js +43 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/codegen.d.ts +2 -0
- package/dist/commands/codegen.js +49 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/contract.d.ts +52 -0
- package/dist/commands/contract.js +300 -0
- package/dist/commands/contract.js.map +1 -0
- package/dist/commands/dev.d.ts +7 -0
- package/dist/commands/dev.js +186 -12
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/index-experience.d.ts +31 -0
- package/dist/commands/index-experience.js +21 -0
- package/dist/commands/index-experience.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.js +12 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +17 -0
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/new.d.ts +2 -0
- package/dist/commands/new.js +39 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/publish.d.ts +59 -0
- package/dist/commands/publish.js +118 -65
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/runs.d.ts +7 -3
- package/dist/commands/runs.js +21 -5
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/scope-notice.d.ts +13 -0
- package/dist/commands/scope-notice.js +12 -4
- package/dist/commands/scope-notice.js.map +1 -1
- package/dist/commands/sources-roles.d.ts +5 -0
- package/dist/commands/sources-roles.js +235 -0
- package/dist/commands/sources-roles.js.map +1 -0
- package/dist/commands/sources.d.ts +5 -0
- package/dist/commands/sources.js +8 -1
- package/dist/commands/sources.js.map +1 -1
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +150 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/team-agent-readiness.d.ts +18 -2
- package/dist/commands/team-agent-readiness.js +39 -39
- package/dist/commands/team-agent-readiness.js.map +1 -1
- package/dist/commands/team-agents-agents.d.ts +5 -2
- package/dist/commands/team-agents-agents.js +152 -15
- package/dist/commands/team-agents-agents.js.map +1 -1
- package/dist/commands/team-agents-define.d.ts +31 -0
- package/dist/commands/team-agents-define.js +176 -0
- package/dist/commands/team-agents-define.js.map +1 -0
- package/dist/commands/team-agents-mcp.js +112 -10
- package/dist/commands/team-agents-mcp.js.map +1 -1
- package/dist/commands/team-agents-triggers.d.ts +1 -1
- package/dist/commands/team-agents-triggers.js +137 -5
- package/dist/commands/team-agents-triggers.js.map +1 -1
- package/dist/commands/team-agents.d.ts +4 -1
- package/dist/commands/team-agents.js +17 -4
- package/dist/commands/team-agents.js.map +1 -1
- package/dist/commands/team-llm-key.d.ts +14 -0
- package/dist/commands/team-llm-key.js +122 -0
- package/dist/commands/team-llm-key.js.map +1 -0
- package/dist/commands/teams-audience.d.ts +12 -0
- package/dist/commands/teams-audience.js +144 -0
- package/dist/commands/teams-audience.js.map +1 -0
- package/dist/commands/teams-connect.js +123 -31
- package/dist/commands/teams-connect.js.map +1 -1
- package/dist/commands/teams-lifecycle.d.ts +90 -0
- package/dist/commands/teams-lifecycle.js +457 -0
- package/dist/commands/teams-lifecycle.js.map +1 -0
- package/dist/commands/teams-onboard.d.ts +14 -0
- package/dist/commands/teams-onboard.js +62 -13
- package/dist/commands/teams-onboard.js.map +1 -1
- package/dist/commands/teams-overview.js +6 -2
- package/dist/commands/teams-overview.js.map +1 -1
- package/dist/commands/teams-scope.js +4 -0
- package/dist/commands/teams-scope.js.map +1 -1
- package/dist/commands/teams.d.ts +25 -5
- package/dist/commands/teams.js +106 -39
- package/dist/commands/teams.js.map +1 -1
- package/dist/commands/workflows.d.ts +37 -0
- package/dist/commands/workflows.js +589 -0
- package/dist/commands/workflows.js.map +1 -0
- package/dist/compatibility.d.ts +10 -1
- package/dist/compatibility.js +10 -1
- package/dist/compatibility.js.map +1 -1
- package/dist/connect-fields.d.ts +22 -0
- package/dist/connect-fields.js +115 -0
- package/dist/connect-fields.js.map +1 -0
- package/dist/context.d.ts +12 -0
- package/dist/context.js +32 -9
- package/dist/context.js.map +1 -1
- package/dist/dev-experience.d.ts +125 -0
- package/dist/dev-experience.js +128 -0
- package/dist/dev-experience.js.map +1 -0
- package/dist/experience/boundary.d.ts +12 -0
- package/dist/experience/boundary.js +260 -0
- package/dist/experience/boundary.js.map +1 -0
- package/dist/experience/build.d.ts +16 -0
- package/dist/experience/build.js +90 -0
- package/dist/experience/build.js.map +1 -0
- package/dist/experience/checks.d.ts +29 -0
- package/dist/experience/checks.js +133 -0
- package/dist/experience/checks.js.map +1 -0
- package/dist/experience/contract-sources.d.ts +36 -0
- package/dist/experience/contract-sources.js +111 -0
- package/dist/experience/contract-sources.js.map +1 -0
- package/dist/experience/definition-checks.d.ts +26 -0
- package/dist/experience/definition-checks.js +201 -0
- package/dist/experience/definition-checks.js.map +1 -0
- package/dist/experience/definition-shape.d.ts +60 -0
- package/dist/experience/definition-shape.js +2 -0
- package/dist/experience/definition-shape.js.map +1 -0
- package/dist/experience/init.d.ts +10 -0
- package/dist/experience/init.js +64 -0
- package/dist/experience/init.js.map +1 -0
- package/dist/experience/integrations-codegen.d.ts +17 -0
- package/dist/experience/integrations-codegen.js +51 -0
- package/dist/experience/integrations-codegen.js.map +1 -0
- package/dist/experience/json-schema-to-ts.d.ts +1 -0
- package/dist/experience/json-schema-to-ts.js +90 -0
- package/dist/experience/json-schema-to-ts.js.map +1 -0
- package/dist/experience/load-experience.d.ts +23 -0
- package/dist/experience/load-experience.js +115 -0
- package/dist/experience/load-experience.js.map +1 -0
- package/dist/experience/overrides.d.ts +8 -0
- package/dist/experience/overrides.js +21 -0
- package/dist/experience/overrides.js.map +1 -0
- package/dist/experience/pin-integration.d.ts +8 -0
- package/dist/experience/pin-integration.js +17 -0
- package/dist/experience/pin-integration.js.map +1 -0
- package/dist/experience/pin-ops.d.ts +12 -0
- package/dist/experience/pin-ops.js +36 -0
- package/dist/experience/pin-ops.js.map +1 -0
- package/dist/experience/pins.d.ts +35 -0
- package/dist/experience/pins.js +91 -0
- package/dist/experience/pins.js.map +1 -0
- package/dist/experience/project.d.ts +52 -0
- package/dist/experience/project.js +149 -0
- package/dist/experience/project.js.map +1 -0
- package/dist/experience/publish.d.ts +51 -0
- package/dist/experience/publish.js +144 -0
- package/dist/experience/publish.js.map +1 -0
- package/dist/experience/regenerate.d.ts +10 -0
- package/dist/experience/regenerate.js +33 -0
- package/dist/experience/regenerate.js.map +1 -0
- package/dist/experience/report.d.ts +9 -0
- package/dist/experience/report.js +23 -0
- package/dist/experience/report.js.map +1 -0
- package/dist/harness-scaffold.d.ts +52 -18
- package/dist/harness-scaffold.js +189 -9
- package/dist/harness-scaffold.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +494 -127
- package/dist/index.js.map +1 -1
- package/dist/invocation.d.ts +31 -0
- package/dist/invocation.js +58 -0
- package/dist/invocation.js.map +1 -0
- package/dist/project-checks.d.ts +12 -0
- package/dist/project-checks.js +46 -0
- package/dist/project-checks.js.map +1 -1
- package/dist/project.d.ts +14 -0
- package/dist/project.js +10 -0
- package/dist/project.js.map +1 -1
- package/dist/repo/publish.d.ts +42 -0
- package/dist/repo/publish.js +225 -0
- package/dist/repo/publish.js.map +1 -0
- package/dist/repo/scaffold.d.ts +30 -0
- package/dist/repo/scaffold.js +165 -0
- package/dist/repo/scaffold.js.map +1 -0
- package/dist/runs-api.js +8 -3
- package/dist/runs-api.js.map +1 -1
- package/dist/safe-fs.d.ts +18 -0
- package/dist/safe-fs.js +57 -0
- package/dist/safe-fs.js.map +1 -1
- package/dist/secret-form.d.ts +48 -0
- package/dist/secret-form.js +212 -0
- package/dist/secret-form.js.map +1 -0
- package/dist/secret-input.d.ts +96 -0
- package/dist/secret-input.js +299 -0
- package/dist/secret-input.js.map +1 -0
- package/dist/team-connect-api.d.ts +78 -3
- package/dist/team-connect-api.js +17 -2
- package/dist/team-connect-api.js.map +1 -1
- package/dist/team-lifecycle-api.d.ts +435 -0
- package/dist/team-lifecycle-api.js +301 -0
- package/dist/team-lifecycle-api.js.map +1 -0
- package/dist/teams-api.d.ts +49 -1
- package/dist/teams-api.js +149 -27
- package/dist/teams-api.js.map +1 -1
- package/dist/unknown-command.d.ts +18 -0
- package/dist/unknown-command.js +50 -0
- package/dist/unknown-command.js.map +1 -0
- package/dist/validate-findings.js +2 -1
- package/dist/validate-findings.js.map +1 -1
- package/dist/workflows-api.d.ts +69 -0
- package/dist/workflows-api.js +182 -0
- package/dist/workflows-api.js.map +1 -0
- package/package.json +3 -3
- package/templates/AGENTS.md.tmpl +6 -4
- package/templates/claude-skill.md.tmpl +4 -1
- package/templates/ekanos.json.tmpl +1 -0
- package/templates/experience/AGENTS.md.tmpl +22 -0
- package/templates/experience/ekanos.json.tmpl +7 -0
- package/templates/experience/ekanos.lock.json.tmpl +4 -0
- package/templates/experience/eslint.config.mjs.tmpl +25 -0
- package/templates/experience/gitignore.tmpl +17 -0
- package/templates/experience/package.json.tmpl +41 -0
- package/templates/experience/src/.ekanos/integrations.d.ts.tmpl +3 -0
- package/templates/experience/src/experience.ts.tmpl +30 -0
- package/templates/experience/src/widgets/hello-widget.tsx.tmpl +40 -0
- package/templates/experience/tsconfig.json.tmpl +20 -0
- package/templates/harness/app/%5F%5Fekanos/api/[...path]/route.ts.tmpl +9 -0
- package/templates/harness/app/[slug]/activation/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/tile/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/triggers/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/widgets/[widgetId]/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/widgets/page.tsx.tmpl +1 -1
- package/templates/harness/app/experience/layout.tsx.tmpl +17 -0
- package/templates/harness/app/experience/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/pages/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/review-queue/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/runs/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/widgets/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/widgets/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/workflows/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/workflows/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/connect/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/events/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/health/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/operations/[kind]/[name]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/operations/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/activation/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/layout.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/tile/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/triggers/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/widgets/[widgetId]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/widgets/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/runs/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/layout.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/page.tsx.tmpl +1 -0
- package/templates/harness/app/page.experience.tsx.tmpl +5 -0
- package/templates/harness/repo/app/%5F%5Fekanos/api/[...path]/route.ts.tmpl +11 -0
- package/templates/harness/repo/app/(repo)/connections/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/(repo)/layout.tsx.tmpl +1 -0
- package/templates/harness/repo/app/(repo)/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/experiences/[name]/connect/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/experiences/[name]/layout.tsx.tmpl +9 -0
- package/templates/harness/repo/app/experiences/page.tsx.tmpl +5 -0
- package/templates/harness/repo/app/harness-shell.tsx.tmpl +9 -0
- package/templates/harness/repo/app/integrations/[slug]/layout.tsx.tmpl +1 -0
- package/templates/harness/repo/app/integrations/page.tsx.tmpl +5 -0
- package/templates/harness/repo/app/repo-experiences.ts.tmpl +5 -0
- package/templates/harness/styles/globals.css.tmpl +15 -1
- package/templates/package.json.tmpl +4 -4
- package/templates/skills/build-agent/SKILL.md +43 -10
- package/templates/skills/build-agent/references/agent-json.md +4 -1
- package/templates/skills/build-agent/references/app-setup.md +14 -7
- package/templates/skills/build-agent/references/rollout.md +26 -2
- package/templates/skills/build-agent/references/set-up-an-integration.md +46 -29
- package/templates/skills/build-integration/references/widget-design.md +1 -1
- package/templates/skills/ekanos-platform/SKILL.md +66 -14
- package/templates/skills/polish-widgets/references/patterns.md +3 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ConsoleLayout } from '@ekanos/harness/routes';
|
|
4
|
+
|
|
5
|
+
import experience from __EXPERIENCE_ENTRY__;
|
|
6
|
+
|
|
7
|
+
export default function ExperienceLayout(props: { children: React.ReactNode }) {
|
|
8
|
+
return (
|
|
9
|
+
<ConsoleLayout
|
|
10
|
+
experience={{
|
|
11
|
+
widgets: experience.widgets ?? [],
|
|
12
|
+
pages: experience.pages ?? [],
|
|
13
|
+
}}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceSummaryPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperiencePageHost as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceReviewQueuePage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceRunsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceWidgetPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceWidgetsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceWorkflowPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceWorkflowsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationConnectPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationEventsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationHealthPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationOperationPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationOperationsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationOverviewPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ActivationPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PreviewLayout as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PreviewIndexPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TilePage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TriggersPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SingleWidgetPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { WidgetsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationRunsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ConsoleLayout as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IntegrationsListPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRepoApiHandlers } from '@ekanos/harness/api';
|
|
2
|
+
|
|
3
|
+
// Next treats a leading underscore folder as private, so this directory is
|
|
4
|
+
// literally named `%5F%5Fekanos` and serves /__ekanos/api/*. At a repo root it
|
|
5
|
+
// answers the repo overview and forwards `packages/<kind>/<name>/…` to that
|
|
6
|
+
// package's own harness API.
|
|
7
|
+
const handlers = createRepoApiHandlers();
|
|
8
|
+
|
|
9
|
+
export const GET = handlers.GET;
|
|
10
|
+
export const POST = handlers.POST;
|
|
11
|
+
export const PUT = handlers.PUT;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RepoConnectionsPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RepoLayout as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RepoHomePage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExperienceConnectPage as default } from '@ekanos/harness/routes';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { RepoExperienceLayout } from '@ekanos/harness/routes';
|
|
4
|
+
|
|
5
|
+
import { experienceEntries } from '../../repo-experiences';
|
|
6
|
+
|
|
7
|
+
export default function ExperienceLayout(props: { children: React.ReactNode }) {
|
|
8
|
+
return <RepoExperienceLayout entries={experienceEntries} {...props} />;
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { RootLayout } from '@ekanos/harness/app';
|
|
4
|
+
|
|
5
|
+
import { harnessIntegrations } from '../../../harness.config';
|
|
6
|
+
|
|
7
|
+
export default function HarnessShell(props: { children: React.ReactNode }) {
|
|
8
|
+
return <RootLayout integrations={harnessIntegrations} repo {...props} />;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RepoIntegrationLayout as default } from '@ekanos/harness/routes';
|
|
@@ -6,7 +6,21 @@
|
|
|
6
6
|
* `@ekanos/ui`, `@ekanos/sdk` — is already accounted for inside
|
|
7
7
|
* `@ekanos/harness/styles.css`, so nothing about the harness needs a glob here.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
/*
|
|
10
|
+
* `source(none)` turns OFF Tailwind v4's automatic source detection. Left on,
|
|
11
|
+
* it scans everything under this directory — including `.next/`, whose
|
|
12
|
+
* Turbopack cache holds binary `.sst` blocks that contain fragments of our
|
|
13
|
+
* own sources split by control bytes. Those become garbage candidates such as
|
|
14
|
+
* `var(--icon-glyph<ctrl>,16px)`, and the CSS parser then fails with "Parsing
|
|
15
|
+
* CSS source code failed": every page a build-error overlay and every
|
|
16
|
+
* harness API route an HTML 500, recurring whenever the cache is rewritten.
|
|
17
|
+
* Every directory worth scanning is named by an exact `@source` below or
|
|
18
|
+
* inside the harness stylesheet.
|
|
19
|
+
*/
|
|
20
|
+
@import '@ekanos/harness/styles.css' source(none);
|
|
21
|
+
|
|
22
|
+
/* The generated shell's own pages — explicit, so `.next/` is never matched. */
|
|
23
|
+
@source '../app/**/*.tsx';
|
|
10
24
|
|
|
11
25
|
/*
|
|
12
26
|
* Your integration source, and the registry that lists it. A missing @source
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"prepare": "node scripts/setup-hooks.mjs"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ekanos/sdk": "^0.
|
|
16
|
-
"@ekanos/ui": "^0.
|
|
15
|
+
"@ekanos/sdk": "^0.19.0",
|
|
16
|
+
"@ekanos/ui": "^0.19.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@ekanos/cli": "^0.
|
|
20
|
-
"@ekanos/harness": "^0.
|
|
19
|
+
"@ekanos/cli": "^0.17.0",
|
|
20
|
+
"@ekanos/harness": "^0.19.0",
|
|
21
21
|
"@hookform/resolvers": "^5.2.2",
|
|
22
22
|
"@tailwindcss/postcss": "^4.3.3",
|
|
23
23
|
"@tanstack/react-query": "^5.101.4",
|
|
@@ -39,9 +39,15 @@ installed — so check it, every time (§ 4, "Make it reachable").
|
|
|
39
39
|
## Hard rules
|
|
40
40
|
|
|
41
41
|
- Never ask for, accept or write a secret (API key, client secret, webhook
|
|
42
|
-
signing secret)
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
signing secret), and never read one from a file or a variable yourself.
|
|
43
|
+
The user enters it, and it never passes through you: run the command with
|
|
44
|
+
`--browser` (`apps set`, `apps connect`, `teams app set`, `teams connect`,
|
|
45
|
+
`teams mcp token`, `teams llm-key set` take it) and the CLI opens a
|
|
46
|
+
one-time form in their browser on this computer — tell them to fill it in
|
|
47
|
+
there. If they would rather, they put it in an environment variable or a
|
|
48
|
+
file only they can read, and you pass `--secret-env <NAME>` or
|
|
49
|
+
`--secret-file <path>`. Or they type it at their own terminal, or a team
|
|
50
|
+
enters it in the Ekanos app. A secret is never a value on the command line.
|
|
45
51
|
- Never `publish`, `rollback` or `archive` without the user's explicit yes to
|
|
46
52
|
that version or agent, after they have seen it. `--yes` records that
|
|
47
53
|
consent; it is never a way past a question.
|
|
@@ -105,7 +111,8 @@ list` to find the role holding `agents.review` for reviewers — see the
|
|
|
105
111
|
`ekanos-platform` skill, "Onboarding a team"), and send the member who will
|
|
106
112
|
sign in the link from `ekanos teams connect <team> <product>`. For the
|
|
107
113
|
Source's app itself, `references/app-setup.md` has the console walk-through.
|
|
108
|
-
Secrets are only ever entered
|
|
114
|
+
Secrets are only ever entered by the user — in the `--browser` form, at
|
|
115
|
+
their terminal, or in the app — never through you.
|
|
109
116
|
|
|
110
117
|
## 2. The interview
|
|
111
118
|
|
|
@@ -208,6 +215,32 @@ in parentheses are the recommendation when the user has no preference.
|
|
|
208
215
|
team pilots
|
|
209
216
|
it first, and do § 4 with them.
|
|
210
217
|
|
|
218
|
+
## 3b. Only one team, or only the user: a team's own or a personal agent
|
|
219
|
+
|
|
220
|
+
When the agent is for one team only, or for the user alone (§ 2's rollout
|
|
221
|
+
question, `references/rollout.md`), skip the template: the same files make a
|
|
222
|
+
team's own agent, or with `--personal` the user's own.
|
|
223
|
+
|
|
224
|
+
1. On their go: `npx @ekanos/cli teams agents create <team> --from agents/<key> --source <slug> --json`
|
|
225
|
+
(add `--personal` for the user's own). The user becomes its creator, so
|
|
226
|
+
they must be an active member of that team; a `NOT_A_TEAM_MEMBER` refusal
|
|
227
|
+
names the command that adds them. Skill folders beside it are pushed as
|
|
228
|
+
that team's skills. Drop any field only a template has (exit 3 lists them).
|
|
229
|
+
2. It starts as a draft:
|
|
230
|
+
`npx @ekanos/cli teams agents enable <team> <key> --source <slug> --json`.
|
|
231
|
+
Confirm what it may use only with the user's yes (`--confirm-access` on
|
|
232
|
+
`create` or `enable`, or `teams agents confirm <team> <key>`); a personal
|
|
233
|
+
agent's creator alone may.
|
|
234
|
+
3. Start it from a schedule or a webhook:
|
|
235
|
+
`npx @ekanos/cli teams triggers add <team> <key> schedule --cron "0 8 * * 1-5" --timezone <zone> --prompt "…" --json`
|
|
236
|
+
or `… webhook --prompt "…"`. The webhook's token is saved to a file only
|
|
237
|
+
the user can read — never open or print it; tell them a personal agent's
|
|
238
|
+
token lets whoever holds it make the agent act as them.
|
|
239
|
+
4. Later changes: edit the files and
|
|
240
|
+
`npx @ekanos/cli teams agents apply <team> agents/<key> --base-version <n> --json`
|
|
241
|
+
(`<n>` from `teams agents show`). Never `--overwrite` a conflict you have
|
|
242
|
+
not shown the user.
|
|
243
|
+
|
|
211
244
|
## 4. Make it reachable, and prove it end to end
|
|
212
245
|
|
|
213
246
|
For each team that turns on an agent with a channel trigger, start with
|
|
@@ -225,12 +258,12 @@ screen). For the detail behind it:
|
|
|
225
258
|
and `agent` (`credentialsSaved`, `connected` = installed, `neededBy`),
|
|
226
259
|
and the `agent-events` webhook in `teamApps[].webhooks` must have an
|
|
227
260
|
`endpoint`. Read the state back to the user in those words.
|
|
228
|
-
3. Not installed:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
waits. No webhook URL yet: `npx @ekanos/cli teams webhook <team> linear
|
|
261
|
+
3. Not installed: run
|
|
262
|
+
`npx @ekanos/cli teams connect <team> linear --connection agent --browser --source <slug>`
|
|
263
|
+
(or the user runs it without `--browser` in their own terminal). If the
|
|
264
|
+
app's client ID, secret or webhook signing secret is missing, it opens a
|
|
265
|
+
form in the user's browser for them to fill — you never handle those —
|
|
266
|
+
then opens the install (a Linear workspace admin approves it) and waits. No webhook URL yet: `npx @ekanos/cli teams webhook <team> linear
|
|
234
267
|
agent-events --source <slug>` (shown once, and saved to a file only the
|
|
235
268
|
user can read — the output names it; the user copies it into the Linear
|
|
236
269
|
app. Never open or print that file yourself).
|
|
@@ -56,7 +56,10 @@ conflicting change unless `--overwrite`. Unknown fields are refused.
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
The tool names above are illustrations. Take real ones from
|
|
59
|
-
`ekanos catalog --json
|
|
59
|
+
`ekanos catalog --json`; `ekanos catalog <product> --json` gives each tool's
|
|
60
|
+
`inputSchema` (when a tool needs an id, another tool of the product returns
|
|
61
|
+
it) and the product's `connection` (`connectedBy`, `runsUse`,
|
|
62
|
+
`sourceConnection`).
|
|
60
63
|
|
|
61
64
|
## Fields
|
|
62
65
|
|
|
@@ -41,23 +41,30 @@ working from those rather than from Ekanos.
|
|
|
41
41
|
the provider's docs rather than guessing.
|
|
42
42
|
- The last console step is always "copy the client ID and the secret".
|
|
43
43
|
**Never ask them to paste the secret into the chat.** For the Source's app,
|
|
44
|
-
|
|
44
|
+
run this yourself, and tell them a form is opening in their browser:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
npx @ekanos/cli apps set <product> --source <slug>
|
|
47
|
+
npx @ekanos/cli apps set <product> --browser --source <slug>
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
The form asks for the client ID and the secret; a field left empty keeps
|
|
51
|
+
its saved value, so either can be changed on its own. What they type goes
|
|
52
|
+
from their browser to the CLI and on to Ekanos, never to you. (Or they run
|
|
53
|
+
`npx @ekanos/cli apps set <product> --source <slug>` in their own terminal,
|
|
54
|
+
which asks with hidden input.) For a team's app,
|
|
55
|
+
`npx @ekanos/cli teams app set <team> <product> --browser --source <slug>`
|
|
56
|
+
does the same, or they enter the fields in the team's setup panel in the
|
|
57
|
+
Ekanos app.
|
|
53
58
|
- Then check: `apps show <product> --source <slug> --json` should say
|
|
54
59
|
`configured: true`, and the catalog's step should be `done`. Tell them
|
|
55
60
|
teams can now connect, and what the team-side steps are.
|
|
56
61
|
|
|
57
62
|
## When it goes wrong
|
|
58
63
|
|
|
59
|
-
- `apps set` says
|
|
60
|
-
|
|
64
|
+
- `apps set` says there is no terminal to ask at: add `--browser`. If
|
|
65
|
+
`--browser` is refused (CI, SSH, no display), ask them to run it in a
|
|
66
|
+
terminal tab themselves. The form gives up after five minutes; run it
|
|
67
|
+
again for a fresh one.
|
|
61
68
|
- `apps set` asks which host: they are signed in to more than one Ekanos;
|
|
62
69
|
add `--host <url>` (the Source's site) or log out of the other.
|
|
63
70
|
- Sign-in later fails with a redirect mismatch: the app is missing one of the
|
|
@@ -65,11 +65,35 @@ plan is ready.
|
|
|
65
65
|
|
|
66
66
|
## A team's own agent
|
|
67
67
|
|
|
68
|
-
Built
|
|
69
|
-
|
|
68
|
+
Built for one team, in the app (Agents → New) or from the terminal with the
|
|
69
|
+
same `agent.json` a template uses:
|
|
70
|
+
`ekanos teams agents create <team> --from agents/<key>` (then
|
|
71
|
+
`ekanos teams agents enable <team> <key>` — it starts as a draft), and
|
|
72
|
+
`ekanos teams agents apply <team> agents/<key> --base-version <n>` to change
|
|
73
|
+
it from the file later. Only that team has it; the Source cannot update or
|
|
74
|
+
roll it back, and nothing about it is visible to other teams. Whoever creates
|
|
75
|
+
it is its creator — its tools run as them — so they must be a member of the
|
|
76
|
+
team who manages its agents. A field only a template has (`connections`,
|
|
77
|
+
`mcpServers`, `teamCustomization`, `triggers`, `links`, `teamOverrides`) is
|
|
78
|
+
refused; add triggers with `ekanos teams triggers add`.
|
|
70
79
|
|
|
71
80
|
Good for: one team's own process; experiments a team owns.
|
|
72
81
|
|
|
82
|
+
## A personal agent
|
|
83
|
+
|
|
84
|
+
One person's agent for themselves: `ekanos teams agents create <team> --from
|
|
85
|
+
agents/<key> --personal`, by a member of that team. It acts for its creator,
|
|
86
|
+
with their own connections, on every trigger, so it is theirs alone: nobody
|
|
87
|
+
else changes it, runs it, decides its approvals or cancels its runs — not a
|
|
88
|
+
team manager, not the Source admin (`PERSONAL_AGENT_CREATOR_ONLY`). Others see
|
|
89
|
+
that it exists, not what its runs read or did. It starts from a schedule or a
|
|
90
|
+
webhook (`ekanos teams triggers add <team> <key> schedule --cron "…" --prompt
|
|
91
|
+
"…"`); whoever holds its webhook token can make it act as its creator, so the
|
|
92
|
+
token goes to a file only they can read, never into a chat.
|
|
93
|
+
|
|
94
|
+
Good for: "brief me on my day", "draft replies to my inbox" — one person's
|
|
95
|
+
own work on their own accounts.
|
|
96
|
+
|
|
73
97
|
## Questions that decide it
|
|
74
98
|
|
|
75
99
|
- How many teams do this work? The same way?
|
|
@@ -60,19 +60,32 @@ connect nothing for it.
|
|
|
60
60
|
`teams show` (or `catalog`) and say what changed ("Ekanos sees the client ID
|
|
61
61
|
and secret now"). If the check disagrees with what they said, look at the
|
|
62
62
|
difference with them; don't move on.
|
|
63
|
-
- **Secrets never pass through the chat.** Client secrets
|
|
64
|
-
secrets go in
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
- **Secrets never pass through the chat, or through you.** Client secrets
|
|
64
|
+
and signing secrets go in through a form in the user's browser that you
|
|
65
|
+
start with `--browser` (`ekanos apps set <product> --browser`,
|
|
66
|
+
`ekanos teams app set <team> <product> --browser`), at the user's own
|
|
67
|
+
terminal with hidden input, or in the team's page in the app. Never read
|
|
68
|
+
one from a file or an environment variable yourself; if the user has put
|
|
69
|
+
one there, pass its name with `--secret-env <NAME>` or its path with
|
|
70
|
+
`--secret-file <path>` and let the CLI read it. If they paste one into the
|
|
71
|
+
chat anyway, tell them to rotate it in the provider's console and enter
|
|
72
|
+
the new one through the form.
|
|
73
|
+
- **Connect with `teams connect <team> <product>`** — add `--browser` when
|
|
74
|
+
you run it, so any field it needs opens as a form in the user's browser;
|
|
75
|
+
without it the user runs it in their own terminal. It does whatever the
|
|
76
|
+
integration needs: asks a form's fields
|
|
70
77
|
(secrets hidden), runs the team-app prompts first when the team's own app is
|
|
71
78
|
missing, or opens a one-time sign-in link and waits until the team is
|
|
72
|
-
connected.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
connected. Non-secret fields of any type can be passed with
|
|
80
|
+
`--set <field>=<value>` (a list as `a,b`; secrets and JSON values only at a prompt), so
|
|
81
|
+
it also runs in a script; optional ones can be left out. The provider's
|
|
82
|
+
consent is still a person's click, by a member of the team (owner/admin for
|
|
83
|
+
a team-wide connection): the user when they are one, else `--as <email>`
|
|
84
|
+
prints a link to send that member. A Source admin who is not on the team
|
|
85
|
+
joins it first with `ekanos teams members add <team> --self` (no email). A
|
|
86
|
+
personal product (each person connects their own, such as ROAM) connects
|
|
87
|
+
the account of whoever runs `teams connect`. `--link-only` prints just the
|
|
88
|
+
team's page. Tell them who should sign in: the account the
|
|
76
89
|
integration acts as. If the product is not enabled for the Source, a
|
|
77
90
|
super-admin enables it (`sources products` shows what the Source has). A dedicated seat such as "Support agent" makes its replies easy
|
|
78
91
|
to recognise.
|
|
@@ -88,11 +101,12 @@ pilot), the team-side steps can be done from the CLI:
|
|
|
88
101
|
1. `npx @ekanos/cli teams show <team> <product> --source <slug>`: the
|
|
89
102
|
callback URL to register and the integration's steps.
|
|
90
103
|
2. They create the app in the provider's console, step by step as above.
|
|
91
|
-
3.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
104
|
+
3. Run `npx @ekanos/cli teams app set <team> <product> --browser --source <slug>`
|
|
105
|
+
and tell them a form is opening in their browser: it has every field,
|
|
106
|
+
secrets as password inputs, and a field left empty keeps its saved value.
|
|
107
|
+
What they type never reaches you. (Without `--browser`, they run it in
|
|
108
|
+
their own terminal, which asks for each field and hides the secret ones.)
|
|
109
|
+
To change one value later, they need not re-enter the rest:
|
|
96
110
|
`teams app set <team> <product> --field <name>` asks for just that field
|
|
97
111
|
(names are in brackets in `teams show`), `--set <name>=<value>` sets a
|
|
98
112
|
non-secret field (a subdomain, a client ID) without a prompt — you may run
|
|
@@ -122,10 +136,11 @@ mentions arrive. When the agent has any Linear trigger:
|
|
|
122
136
|
redirect URIs, webhooks on with **Agent session events** and **Issues**.
|
|
123
137
|
3. Its webhook URL: `teams webhook <team> linear agent-events` (once; paste
|
|
124
138
|
it into the Linear app's webhook URL).
|
|
125
|
-
4.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
139
|
+
4. `npx @ekanos/cli teams connect <team> linear --connection agent --browser --source <slug>`
|
|
140
|
+
— opens a form in the user's browser for the client ID, secret and
|
|
141
|
+
webhook signing secret if any is missing (without `--browser`, the user
|
|
142
|
+
runs it in their own terminal and it asks there), opens the install for a
|
|
143
|
+
Linear workspace admin to approve, and
|
|
129
144
|
waits until it is installed. (`teams connect <team> linear` with no
|
|
130
145
|
`--connection` offers this itself once the personal connection is made,
|
|
131
146
|
when the team has agents with Linear triggers.)
|
|
@@ -146,11 +161,12 @@ the Source's connection.
|
|
|
146
161
|
1. **Connect, once, as the Source.** For an integration where each customer
|
|
147
162
|
brings its own app (Zendesk), first create that app in the shared account,
|
|
148
163
|
exactly as in the worked example below (OAuth client, Confidential), but
|
|
149
|
-
once, for the Source. Then
|
|
150
|
-
`npx @ekanos/cli apps connect <product> --source <slug
|
|
164
|
+
once, for the Source. Then run
|
|
165
|
+
`npx @ekanos/cli apps connect <product> --browser --source <slug>` (or the
|
|
166
|
+
user runs it without `--browser` in their own terminal). It asks for the
|
|
151
167
|
app's fields it doesn't have yet (Zendesk: subdomain, client ID, client
|
|
152
|
-
secret, webhook signing secret
|
|
153
|
-
|
|
168
|
+
secret, webhook signing secret) in a form in the user's browser — never
|
|
169
|
+
through you, never as values on the command line — prints the redirect URL to register and the
|
|
154
170
|
consent link, then waits up to ten minutes until it is connected. Whoever
|
|
155
171
|
clicks the link is the account the integration acts as for every team, so
|
|
156
172
|
suggest a dedicated seat ("Support agent"). `apps list` shows every
|
|
@@ -201,9 +217,9 @@ from `teams show zendesk`.
|
|
|
201
217
|
Center › Apps and integrations › Webhooks › Create webhook › Trigger or
|
|
202
218
|
automation: that URL, POST, JSON, no authentication. Open it and Reveal
|
|
203
219
|
secret.
|
|
204
|
-
3. **Credentials into Ekanos.** `ekanos teams app set <team> zendesk`
|
|
205
|
-
their
|
|
206
|
-
secret. Any of them can be entered or changed later on its own
|
|
220
|
+
3. **Credentials into Ekanos.** `ekanos teams app set <team> zendesk --browser`
|
|
221
|
+
(a form in their browser; or without `--browser`, in their terminal):
|
|
222
|
+
subdomain, client ID, client secret, webhook signing secret. Any of them can be entered or changed later on its own
|
|
207
223
|
(`--field <name>`); `teams show` says which are saved.
|
|
208
224
|
4. **Connect.** `npx @ekanos/cli teams connect <team> zendesk --source <slug>`
|
|
209
225
|
opens the sign-in and waits; whoever approves it should be the Zendesk
|
|
@@ -244,5 +260,6 @@ from `teams show zendesk`.
|
|
|
244
260
|
not installed for this team", or no webhook URL) and the command that
|
|
245
261
|
fixes it. Installed and still silent: the Linear app's webhook must send
|
|
246
262
|
**Agent session events** to the latest URL from `teams webhook`.
|
|
247
|
-
- **A command says
|
|
248
|
-
|
|
263
|
+
- **A command says there is no terminal to ask at:** run it again with
|
|
264
|
+
`--browser`. If `--browser` is refused (CI, SSH, no display), ask them to
|
|
265
|
+
run it in a terminal tab themselves.
|
|
@@ -185,7 +185,7 @@ mock switch) so the harness can show all four; remove it before publish.
|
|
|
185
185
|
`border-border`, `bg-primary`, `text-destructive`. NEVER raw palette
|
|
186
186
|
classes (`bg-white`, `text-gray-500`, `bg-amber-400`) or hex/oklch
|
|
187
187
|
literals — they break in dark mode and off-brand tenants.
|
|
188
|
-
- **Accent discipline**: the primary (
|
|
188
|
+
- **Accent discipline**: the `primary` token (the Source's accent) on ≤10% of the widget —
|
|
189
189
|
one CTA, one highlighted value, one active state. Semantic status colors
|
|
190
190
|
(success/warning/destructive) are not accents.
|
|
191
191
|
- **Depth via shadow, not borders** where a surface needs lift.
|