@tessl/cli 0.27.0 â 0.28.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/dist/bundle.mjs +105 -99
- package/package.json +1 -1
package/dist/bundle.mjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import*as fs$7 from"node:fs";import fs__default,{watch,existsSync,writeFileSync as writeFileSync$1,mkdirSync as mkdirSync$1,readFileSync as readFileSync$1,statSync,appendFileSync,createWriteStream as createWriteStream$1,createReadStream}from"node:fs";import*as path$6 from"path";import path__default,{join as join$1,dirname,basename,normalize as normalize$3,resolve as resolve$3,relative,sep as sep$1,posix as posix$1}from"path";import*as Url$1 from"url";import Url__default,{fileURLToPath,URL as URL$2}from"url";import fs$8,{readFileSync,existsSync as existsSync$1,mkdirSync,writeFileSync,realpathSync as realpathSync$1,readlinkSync,readdirSync,readdir as readdir$1,lstatSync,createWriteStream,promises}from"fs";import*as require$$0$7 from"os";import require$$0__default,{arch,hostname as hostname$1,release,platform as platform$1}from"os";import crypto$3,{randomUUID,createHash,randomFillSync}from"crypto";import os$2,{homedir as homedir$1,EOL,constants as constants$g}from"node:os"
|
|
3
3
|
;import*as path$7 from"node:path";import path__default$1,{join,dirname as dirname$1,win32,posix,basename as basename$1,resolve as resolve$2,relative as relative$1}from"node:path";import require$$0$9 from"@grpc/grpc-js";import{performance as performance$1}from"perf_hooks";import require$$2$4,{TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,ATTR_TELEMETRY_SDK_VERSION,ATTR_TELEMETRY_SDK_LANGUAGE,ATTR_TELEMETRY_SDK_NAME,ATTR_SERVICE_NAME,ATTR_EXCEPTION_TYPE,ATTR_EXCEPTION_MESSAGE,ATTR_EXCEPTION_STACKTRACE}from"@opentelemetry/semantic-conventions";import*as require$$1$6 from"util";import require$$1__default,{inspect,types as types$4}from"util";import*as zlib$2 from"zlib";import zlib__default,{createGunzip as createGunzip$1}from"zlib";import require$$0$e,{Readable}from"stream";import require$$1$7,{JsonTraceSerializer,JsonMetricsSerializer,ProtobufMetricsSerializer,ProtobufTraceSerializer}from"@opentelemetry/otlp-transformer";import require$$0$b from"diagnostics_channel"
|
|
4
4
|
;import require$$1$b,{logs}from"@opentelemetry/api-logs";import require$$1$8 from"module";import require$$0$a from"tty";import require$$3$1 from"worker_threads";import require$$4$1 from"@opentelemetry/sdk-logs";import require$$1$a,{AggregationTemporality,InstrumentType,AggregationType}from"@opentelemetry/sdk-metrics";import require$$1$9 from"async_hooks";import require$$0$c,{EventEmitter as EventEmitter$1}from"events";import*as process$4 from"process";import process__default from"process";import require$$5$3 from"@opentelemetry/exporter-logs-otlp-http";import require$$6$1 from"@opentelemetry/exporter-logs-otlp-grpc";import require$$7 from"@opentelemetry/exporter-logs-otlp-proto";import*as http$2 from"http";import http__default from"http";import*as require$$1$5 from"https";import require$$1__default$1 from"https"
|
|
5
|
-
;import{ATTR_K8S_POD_UID,ATTR_K8S_NAMESPACE_NAME,ATTR_K8S_POD_NAME,ATTR_VCS_REF_BASE_NAME,ATTR_VCS_CHANGE_ID,ATTR_USER_ID,ATTR_USER_EMAIL}from"@opentelemetry/semantic-conventions/incubating";import*as require$$0$8 from"child_process";import require$$0__default$1,{execSync}from"child_process";import readline$4,{createInterface}from"readline";import fsp,{realpath,readlink,readdir,lstat,access,readFile as readFile$1,mkdir,writeFile,chmod}from"node:fs/promises";import{dirname as dirname$2}from"path/posix";import{fileURLToPath as fileURLToPath$1,URL as URL$1}from"node:url";import require$$0$i,{EventEmitter,once as once$1,addAbortListener,on,setMaxListeners}from"node:events";import require$$0$d,{PassThrough,Stream as Stream$2,Readable as Readable$1,Transform as Transform$2,getDefaultHighWaterMark,Duplex,Writable}from"node:stream";import{StringDecoder}from"node:string_decoder";import process$5,{env as env$2,cwd,platform as platform$2,hrtime,execPath,execArgv}from"node:process"
|
|
6
|
-
;import tty$2 from"node:tty";import require$$5$5,{performance as performance$2}from"node:perf_hooks";import require$$0$f from"assert";import require$$0$n,{Buffer as Buffer$1}from"node:buffer";import{pipeline,finished}from"node:stream/promises";import require$$0$o,{createGunzip,createGzip}from"node:zlib";import require$$0$g from"buffer";import{createHash as createHash$1,randomUUID as randomUUID$1}from"node:crypto";import require$$2$6,{setTimeout as setTimeout$1}from"node:timers";import cp,{execFile,ChildProcess,spawnSync,spawn}from"node:child_process";import require$$1$c from"string_decoder";import{tsImport}from"tsx/esm/api";import{mkdir as mkdir$1,
|
|
5
|
+
;import{ATTR_K8S_POD_UID,ATTR_K8S_NAMESPACE_NAME,ATTR_K8S_POD_NAME,ATTR_VCS_REF_BASE_NAME,ATTR_VCS_CHANGE_ID,ATTR_USER_ID,ATTR_USER_EMAIL}from"@opentelemetry/semantic-conventions/incubating";import*as require$$0$8 from"child_process";import require$$0__default$1,{execSync}from"child_process";import readline$4,{createInterface}from"readline";import fsp,{realpath,readlink,readdir,lstat,access,readFile as readFile$1,mkdir,writeFile,rm,chmod}from"node:fs/promises";import{dirname as dirname$2}from"path/posix";import{fileURLToPath as fileURLToPath$1,URL as URL$1}from"node:url";import require$$0$i,{EventEmitter,once as once$1,addAbortListener,on,setMaxListeners}from"node:events";import require$$0$d,{PassThrough,Stream as Stream$2,Readable as Readable$1,Transform as Transform$2,getDefaultHighWaterMark,Duplex,Writable}from"node:stream";import{StringDecoder}from"node:string_decoder";import process$5,{env as env$2,cwd,platform as platform$2,hrtime,execPath,execArgv}from"node:process"
|
|
6
|
+
;import tty$2 from"node:tty";import require$$5$5,{performance as performance$2}from"node:perf_hooks";import require$$0$f from"assert";import require$$0$n,{Buffer as Buffer$1}from"node:buffer";import{pipeline,finished}from"node:stream/promises";import require$$0$o,{createGunzip,createGzip}from"node:zlib";import require$$0$g from"buffer";import{createHash as createHash$1,randomUUID as randomUUID$1}from"node:crypto";import require$$2$6,{setTimeout as setTimeout$1}from"node:timers";import cp,{execFile,ChildProcess,spawnSync,spawn}from"node:child_process";import require$$1$c from"string_decoder";import{tsImport}from"tsx/esm/api";import{mkdir as mkdir$1,rm as rm$1,unlink,readFile as readFile$2}from"fs/promises";import{pipeline as pipeline$1}from"stream/promises";import open from"open";import*as readline$3 from"node:readline";import{createInterface as createInterface$1}from"node:readline";import require$$1$e,{AsyncLocalStorage,AsyncResource}from"node:async_hooks"
|
|
7
7
|
;import require$$0$l,{stripVTControlCharacters,promisify,styleText,debuglog,inspect as inspect$1,callbackify,aborted as aborted$1}from"node:util";import require$$0$h from"net";import{setTimeout as setTimeout$2,scheduler as scheduler$1,setImmediate as setImmediate$1}from"node:timers/promises";import{serialize}from"node:v8";import{createRequire}from"node:module";import{setTimeout as setTimeout$3}from"timers/promises";import require$$0$j from"node:assert";import require$$0$k from"node:net";import require$$2$5 from"node:http";import require$$5$4 from"node:querystring";import require$$0$m from"node:diagnostics_channel";import require$$4$3 from"node:tls";import require$$8$1 from"node:util/types";import require$$1$d from"node:worker_threads";import require$$1$f from"node:console";import require$$1$g from"node:dns";import{levels,pino}from"pino";import"pino-pretty";import require$$4$2 from"tls"
|
|
8
8
|
;var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function getDefaultExportFromCjs(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function getAugmentedNamespace(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var r=function e(){var r=!1;try{r=this instanceof e}catch{}return r?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}),r}var main$2={exports:{}},version$6="17.2.1",require$$4={version:version$6},hasRequiredMain;function requireMain(){if(hasRequiredMain)return main$2.exports;hasRequiredMain=1
|
|
9
9
|
;const e=fs$8,t=path__default,r=require$$0__default,n=crypto$3,i=require$$4.version,s=["đ encrypt with Dotenvx: https://dotenvx.com","đ prevent committing .env to code: https://dotenvx.com/precommit","đ prevent building .env in docker: https://dotenvx.com/prebuild","đĄ observe env with Radar: https://dotenvx.com/radar","đĄ auto-backup env with Radar: https://dotenvx.com/radar","đĄ version env with Radar: https://dotenvx.com/radar","đ ī¸ run anywhere with `dotenvx run -- yourcommand`","âī¸ specify custom .env file path with { path: '/custom/path/.env' }","âī¸ enable debug logging with { debug: true }","âī¸ override existing env vars with { override: true }","âī¸ suppress all logs with { quiet: true }","âī¸ write to custom object with { processEnv: myObject }","âī¸ load multiple .env files with { path: ['.env.local', '.env'] }"];function o(e){return"string"==typeof e?!["false","0","no","off",""].includes(e.toLowerCase()):Boolean(e)}function a(e){
|
|
@@ -88,7 +88,7 @@ return globalThis.Object.getOwnPropertyNames(e).reduce((t,r)=>({...t,[r]:Compute
|
|
|
88
88
|
function Void(e){return CreateType({[Kind]:"Void",type:"void"},e)}var TypeBuilder=Object.freeze({__proto__:null,Any:Any$1,Argument,Array:Array$1,AsyncIterator,Awaited,BigInt:BigInt$1,Boolean:Boolean$1,Capitalize,Composite,Const,Constructor,ConstructorParameters,Date:Date$1,Enum,Exclude,Extends,Extract,Function:Function$1,Index,InstanceType,Instantiate,Integer,Intersect:Intersect$1,Iterator,KeyOf,Literal,Lowercase,Mapped,Module,Never,Not,Null,Number:Number$1,Object:Object$1,Omit,Optional,Parameters,Partial,Pick,Promise:Promise$1,Readonly,ReadonlyOptional,Record,Recursive,Ref,RegExp:RegExp$1,Required,Rest,ReturnType,String:String$1,Symbol:Symbol$1,TemplateLiteral,Transform:Transform$1,Tuple,Uint8Array:Uint8Array$1,Uncapitalize,Undefined,Union:Union$1,Unknown,Unsafe,Uppercase,Void});const Type=TypeBuilder;function _nullishCoalesce$V(e,t){return null!=e?e:t()}const ProjectConfigSchema=Type.Object({name:Type.Optional(Type.String({description:"Project name"}))
|
|
89
89
|
}),CONFIG_DIR_NAME=".tessl",AGENTS_MD_FILENAME="AGENTS.md",SYSTEM_PROMPT_FILENAME="tessl-system-prompt.md",TESSL_CONFIG_FILE_NAME="tessl-config.jsonc",TMP_DIR_NAME="tmp",DEFAULT_TESSL_DIRS={customToolDirectory:join(CONFIG_DIR_NAME,"tools"),frameworkDirectory:join(CONFIG_DIR_NAME,"framework"),tmpDirectory:join(CONFIG_DIR_NAME,TMP_DIR_NAME),testRunnerDirectory:join(CONFIG_DIR_NAME,TMP_DIR_NAME,"test-runners"),testResultsDirectory:join(CONFIG_DIR_NAME,TMP_DIR_NAME,"test-results"),sessionDataDirectory:join(CONFIG_DIR_NAME,TMP_DIR_NAME,"session-data"),toolOutputLogsDirectory:join(CONFIG_DIR_NAME,TMP_DIR_NAME,"tool-output-logs")};function getDefaultGlobalConfigDir(e,t){const r=_nullishCoalesce$V(t,()=>os$2.homedir()),n=_nullishCoalesce$V(_nullishCoalesce$V(e,()=>"production"),()=>"development");return path__default.join(r,"production"===n?".tessl":`.tessl_${n}`)}function getProvisionedEnvPath(e,t){return join$1(getDefaultGlobalConfigDir(e,t),"dotenv")}function getLocalCliEnvPath(){
|
|
90
90
|
const e=fileURLToPath(import.meta.url),t=dirname(e),r=join$1(t,"..","..","..","..");return join$1(r,".cli.env")}function loadEnvAndWatch(){loadEnv(),setupFileWatchers()}function loadEnvFile(e){fs__default.existsSync(e)&&mainExports.config({path:e,override:!0,quiet:!0})}function loadEnv(){loadEnvFile(getProvisionedEnvPath("production")),process.env.TESSL_LLM_API_KEY?process.env.ANTHROPIC_AUTH_TOKEN=process.env.TESSL_LLM_API_KEY:delete process.env.ANTHROPIC_AUTH_TOKEN,process.env.TESSL_LLM_BASE_URL?process.env.ANTHROPIC_BASE_URL=process.env.TESSL_LLM_BASE_URL:delete process.env.ANTHROPIC_BASE_URL;const e=getClaudeCodeSdkModels();process.env.ANTHROPIC_MODEL=e.DEFAULT,process.env.ANTHROPIC_SMALL_FAST_MODEL=e.SMALL_FAST}let localCliWatcher=null,provisionedEnvWatcher=null,cleanupRegistered=!1;function createFileWatcher(e,t){const r=dirname(e),n=basename(e);if(!fs__default.existsSync(r))return null;const i=watch(r,(e,r)=>{r!==n||"change"!==e&&"rename"!==e||t()});return i.on("error",()=>{}),
|
|
91
|
-
i.unref(),i}function cleanup(){localCliWatcher&&(localCliWatcher.close(),localCliWatcher=null),provisionedEnvWatcher&&(provisionedEnvWatcher.close(),provisionedEnvWatcher=null)}function setupFileWatchers(){cleanup(),localCliWatcher=createFileWatcher(getLocalCliEnvPath(),loadEnv),provisionedEnvWatcher=createFileWatcher(getProvisionedEnvPath("production"),loadEnv),cleanupRegistered||(process.on("SIGINT",cleanup),process.on("SIGTERM",cleanup),cleanupRegistered=!0)}function getTesslCmdName(){return"tessl"}process.env={...process.env,ROLLUP_BUNDLING_CLI:!0,NODE_ENV:"production",GLOBAL_CONFIG_DIR:".tessl",STAMPED_REVISION:"
|
|
91
|
+
i.unref(),i}function cleanup(){localCliWatcher&&(localCliWatcher.close(),localCliWatcher=null),provisionedEnvWatcher&&(provisionedEnvWatcher.close(),provisionedEnvWatcher=null)}function setupFileWatchers(){cleanup(),localCliWatcher=createFileWatcher(getLocalCliEnvPath(),loadEnv),provisionedEnvWatcher=createFileWatcher(getProvisionedEnvPath("production"),loadEnv),cleanupRegistered||(process.on("SIGINT",cleanup),process.on("SIGTERM",cleanup),cleanupRegistered=!0)}function getTesslCmdName(){return"tessl"}process.env={...process.env,ROLLUP_BUNDLING_CLI:!0,NODE_ENV:"production",GLOBAL_CONFIG_DIR:".tessl",STAMPED_REVISION:"34789165bafc29ec61d0106a1ecb2d85973c6030",STAMPED_RELEASE_DATE:"2025-10-17T12:23:23.485Z",STAMPED_VERSION:"v0.28.0",TESSL_BASE_API_URL:"https://api.tessl.io",WORKOS_CLIENT_ID:"client_01HXSHDD9KV92A4892CWHZZDDR",POSTHOG_API_KEY:"phc_S8tHJaPxa5ORnP0RVyyTaJHeCcft6XMqfjx9ZlJWvkO",POSTHOG_FEEDBACK_SURVEY_ID:"0197d0d3-6704-0000-e36e-569911acb8ee",
|
|
92
92
|
POSTHOG_FEEDBACK_SURVEY_QUESTION_ID:"e34e48fc-938a-4af1-b255-3c55d6bdcbc7"},loadEnvAndWatch();var _globalThis$1="object"==typeof globalThis?globalThis:global,VERSION$8="1.9.0",re$2=/^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;function _makeCompatibilityCheck(e){var t=new Set([e]),r=new Set,n=e.match(re$2);if(!n)return function(){return!1};var i=+n[1],s=+n[2],o=+n[3];if(null!=n[4])return function(t){return t===e};function a(e){return r.add(e),!1}function c(e){return t.add(e),!0}return function(e){if(t.has(e))return!0;if(r.has(e))return!1;var n=e.match(re$2);if(!n)return a(e);var u=+n[1],l=+n[2],d=+n[3];return null!=n[4]||i!==u?a(e):0===i?s===l&&o<=d?c(e):a(e):s<=l?c(e):a(e)}}var isCompatible=_makeCompatibilityCheck(VERSION$8),major=VERSION$8.split(".")[0],GLOBAL_OPENTELEMETRY_API_KEY=Symbol.for("opentelemetry.js.api."+major),_global=_globalThis$1;function registerGlobal(e,t,r,n){var i;void 0===n&&(n=!1)
|
|
93
93
|
;var s=_global[GLOBAL_OPENTELEMETRY_API_KEY]=null!==(i=_global[GLOBAL_OPENTELEMETRY_API_KEY])&&void 0!==i?i:{version:VERSION$8};if(!n&&s[e]){var o=new Error("@opentelemetry/api: Attempted duplicate registration of API: "+e);return r.error(o.stack||o.message),!1}if(s.version!==VERSION$8){o=new Error("@opentelemetry/api: Registration of version v"+s.version+" for "+e+" does not match previously registered API v"+VERSION$8);return r.error(o.stack||o.message),!1}return s[e]=t,r.debug("@opentelemetry/api: Registered a global for "+e+" v"+VERSION$8+"."),!0}function getGlobal(e){var t,r,n=null===(t=_global[GLOBAL_OPENTELEMETRY_API_KEY])||void 0===t?void 0:t.version;if(n&&isCompatible(n))return null===(r=_global[GLOBAL_OPENTELEMETRY_API_KEY])||void 0===r?void 0:r[e]}function unregisterGlobal(e,t){t.debug("@opentelemetry/api: Unregistering a global for "+e+" v"+VERSION$8+".");var r=_global[GLOBAL_OPENTELEMETRY_API_KEY];r&&delete r[e]}var __read$4=function(e,t){
|
|
94
94
|
var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,i,s=r.call(e),o=[];try{for(;(void 0===t||t-- >0)&&!(n=s.next()).done;)o.push(n.value)}catch(e){i={error:e}}finally{try{n&&!n.done&&(r=s.return)&&r.call(s)}finally{if(i)throw i.error}}return o},__spreadArray$3=function(e,t,r){if(r||2===arguments.length)for(var n,i=0,s=t.length;i<s;i++)!n&&i in t||(n||(n=Array.prototype.slice.call(t,0,i)),n[i]=t[i]);return e.concat(n||Array.prototype.slice.call(t))},DiagComponentLogger=function(){function e(e){this._namespace=e.namespace||"DiagComponentLogger"}return e.prototype.debug=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return logProxy("debug",this._namespace,e)},e.prototype.error=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return logProxy("error",this._namespace,e)},e.prototype.info=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return logProxy("info",this._namespace,e)},e.prototype.warn=function(){
|
|
@@ -299,10 +299,10 @@ t):(r.forEach(r=>{if("otlp"===r){const r=process.env.OTEL_EXPORTER_OTLP_METRICS_
|
|
|
299
299
|
})):"prometheus"===r?t.push(new d.PrometheusExporter):e.diag.warn(`Unsupported OTEL_METRICS_EXPORTER value: "${r}". Supported values are: otlp, console, prometheus, none.`)}),t)):t}();if(this._meterProviderConfig||o.length>0){const t=[];this._meterProviderConfig?.readers&&t.push(...this._meterProviderConfig.readers),0===t.length&&o.forEach(e=>t.push(e));const r=new p.MeterProvider({resource:this._resource,views:this._meterProviderConfig?.views??[],readers:t});this._meterProvider=r,e.metrics.setGlobalMeterProvider(r);for(const t of this._instrumentations)t.setMeterProvider(e.metrics.getMeterProvider())}}shutdown(){const e=[];return this._tracerProvider&&e.push(this._tracerProvider.shutdown()),this._loggerProvider&&e.push(this._loggerProvider.shutdown()),this._meterProvider&&e.push(this._meterProvider.shutdown()),Promise.all(e).then(()=>{})}configureLoggerProviderFromEnv(){const t=(0,g.getStringListFromEnv)("OTEL_LOGS_EXPORTER")??[]
|
|
300
300
|
;if(0===t.length&&(e.diag.debug("OTEL_LOGS_EXPORTER is empty. Using default otlp exporter."),t.push("otlp")),t.includes("none"))return void e.diag.info('OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.');const r=[];t.forEach(t=>{if("otlp"===t){const t=((0,g.getStringFromEnv)("OTEL_EXPORTER_OTLP_LOGS_PROTOCOL")??(0,g.getStringFromEnv)("OTEL_EXPORTER_OTLP_PROTOCOL"))?.trim();switch(t){case"grpc":r.push(new o.OTLPLogExporter);break;case"http/json":r.push(new s.OTLPLogExporter);break;case"http/protobuf":case void 0:case"":r.push(new a.OTLPLogExporter);break;default:e.diag.warn(`Unsupported OTLP logs protocol: "${t}". Using http/protobuf.`),r.push(new a.OTLPLogExporter)}}else"console"===t?r.push(new i.ConsoleLogRecordExporter):e.diag.warn(`Unsupported OTEL_LOGS_EXPORTER value: "${t}". Supported values are: otlp, console, none.`)}),r.length>0&&(this._loggerProviderConfig={
|
|
301
301
|
logRecordProcessors:r.map(e=>e instanceof i.ConsoleLogRecordExporter?new i.SimpleLogRecordProcessor(e):new i.BatchLogRecordProcessor(e))})}},sdk$1}function requireSrc$2(){return hasRequiredSrc$2||(hasRequiredSrc$2=1,function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.NodeSDK=e.tracing=e.resources=e.node=e.metrics=e.logs=e.core=e.contextBase=e.api=void 0,e.api=require$$0$6,e.contextBase=require$$0$6,e.core=require$$1$4,e.logs=require$$4$1,e.metrics=require$$1$a,e.node=requireSrc$5(),e.resources=require$$5$1,e.tracing=require$$6;var t=requireSdk();Object.defineProperty(e,"NodeSDK",{enumerable:!0,get:function(){return t.NodeSDK}})}(src$6)),src$6}var srcExports$3=requireSrc$2(),srcExports$2=requireSrc$5();let bag;function execSyncFailsafe(e){try{return execSync(e,{stdio:["ignore","pipe","ignore"],encoding:"utf-8",cwd:import.meta.dirname}).trim()}catch(e){return"unknown"}}function isGitDirty(){return"clean"}function initSysinfo(e={}){bag||(bag={}),
|
|
302
|
-
bag.gitRevision="
|
|
303
|
-
;return t&&"unknown"!==t?`${UNRELEASED_VERSION}+${t.substring(0,7)}`:UNRELEASED_VERSION}return t}catch(e){return"error getting version"}}function getResourceAttributes(){const e={"service.name":"stepper","service.version":getTelemetryVersion()};return process.env.INJECTED_POD_NAME&&(e["k8s.pod.name"]=process.env.INJECTED_POD_NAME),process.env.INJECTED_POD_NAMESPACE&&(e["k8s.namespace.name"]=process.env.INJECTED_POD_NAMESPACE),process.env.INJECTED_POD_UID&&(e["k8s.pod.uid"]=process.env.INJECTED_POD_UID),e["vcs.change.id"]="
|
|
304
|
-
[ATTR_SERVICE_NAME]:"stepper",[ATTR_K8S_POD_NAME]:process.env.INJECTED_POD_NAME,[ATTR_K8S_NAMESPACE_NAME]:process.env.INJECTED_POD_NAMESPACE,[ATTR_K8S_POD_UID]:process.env.INJECTED_POD_UID,[ATTR_VCS_CHANGE_ID]:"
|
|
305
|
-
;let currentUser;function setOtelUser(e){currentUser=e;const t=trace$1.getActiveSpan();currentUser&&t&&(t.setAttribute(ATTR_USER_ID,currentUser.id),t.setAttribute(ATTR_USER_EMAIL,currentUser.email))}async function withSpan(e,t){return tracer$1.startActiveSpan(e,async e=>{currentUser&&(e.setAttribute(ATTR_USER_ID,currentUser.id),e.setAttribute(ATTR_USER_EMAIL,currentUser.email));try{return await t(e)}catch(t){throw annotateSpanWithError(e,t),t}finally{e.end()}})}function annotateSpanWithError(e,t){let r;someErrorIs(t,e=>isAbortError$3(e))&&e.setAttribute("cancelled",!0),t instanceof Error&&(r=t.message),e.setStatus({code:SpanStatusCode.ERROR,message:r})}const GLOBAL_DIR_NAME=".tessl",PROJECTS_DIR_NAME="projects";function getGlobalDir(){const e=process.env.TESSL_GLOBAL_DIR;if(e&&""!==e.trim())return e;let t=GLOBAL_DIR_NAME;return join(homedir$1(),t)}function getProjectCacheDir(){const e=process.env.TESSL_PROJECT_CACHE_DIR;if(e&&""!==e.trim())return e
|
|
302
|
+
bag.gitRevision="34789165bafc29ec61d0106a1ecb2d85973c6030",bag.gitDirty=isGitDirty(),bag.releaseDate="2025-10-17T12:23:23.485Z",bag.version="v0.28.0",bag.osImplementation=os$2.type(),bag.osRelease=os$2.release(),bag.argv=JSON.stringify(process.argv),bag.nodeVersion=process.version,bag.nodeExecPath=process.execPath,bag.nodeFirstPath=execSyncFailsafe("which node"),Object.assign(bag,e)}function getSysinfo(){if(!bag)throw new Error("Sysinfo not initialized");return{...bag}}const DASH0_OTLP_ENDPOINT="https://7530.tessl.io:443",UNRELEASED_VERSION="0.0.0-UNRELEASED";function getOtlpAuthHeader(){if(!process.env.TELEMETRY_USER||!process.env.TELEMETRY_PASSWORD)return;const e=`${process.env.TELEMETRY_USER}:${process.env.TELEMETRY_PASSWORD}`;return`Basic ${Buffer.from(e).toString("base64")}`}function getTelemetryVersion(){try{const e=getSysinfo(),t=e.version||UNRELEASED_VERSION;if("unknown"===t||t===UNRELEASED_VERSION){const t=e.gitRevision
|
|
303
|
+
;return t&&"unknown"!==t?`${UNRELEASED_VERSION}+${t.substring(0,7)}`:UNRELEASED_VERSION}return t}catch(e){return"error getting version"}}function getResourceAttributes(){const e={"service.name":"stepper","service.version":getTelemetryVersion()};return process.env.INJECTED_POD_NAME&&(e["k8s.pod.name"]=process.env.INJECTED_POD_NAME),process.env.INJECTED_POD_NAMESPACE&&(e["k8s.namespace.name"]=process.env.INJECTED_POD_NAMESPACE),process.env.INJECTED_POD_UID&&(e["k8s.pod.uid"]=process.env.INJECTED_POD_UID),e["vcs.change.id"]="34789165bafc29ec61d0106a1ecb2d85973c6030",e["vcs.ref.base.name"]="34789165bafc29ec61d0106a1ecb2d85973c6030",e}function register$1(){const e=getOtlpAuthHeader();e&&(process.env.OTEL_EXPORTER_OTLP_ENDPOINT=DASH0_OTLP_ENDPOINT,process.env.OTEL_EXPORTER_OTLP_PROTOCOL="http/json",process.env.OTEL_EXPORTER_OTLP_HEADERS=`Authorization=${e}`);const t=[];t.push(new srcExports$4.UndiciInstrumentation);const r=new srcExports$3.NodeSDK({resource:resourceFromAttributes({
|
|
304
|
+
[ATTR_SERVICE_NAME]:"stepper",[ATTR_K8S_POD_NAME]:process.env.INJECTED_POD_NAME,[ATTR_K8S_NAMESPACE_NAME]:process.env.INJECTED_POD_NAMESPACE,[ATTR_K8S_POD_UID]:process.env.INJECTED_POD_UID,[ATTR_VCS_CHANGE_ID]:"34789165bafc29ec61d0106a1ecb2d85973c6030",[ATTR_VCS_REF_BASE_NAME]:"34789165bafc29ec61d0106a1ecb2d85973c6030"}),instrumentations:t,spanProcessors:[new srcExports$2.SimpleSpanProcessor(process.env.TELEMETRY_USER?new OTLPTraceExporter$1:new srcExports$5.OTLPTraceExporter)]});return r.start(),{shutdown:async()=>{await r.shutdown()}}}"yes"===process.env.TESSL_DEBUG_MONITORING&&diag.setLogger(new DiagConsoleLogger,DiagLogLevel.INFO);const sdk=register$1();function isAbortError$3(e){return"object"==typeof e&&null!==e&&"AbortError"===e.name}function someErrorIs(e,t,r=32){return!(r<=0)&&(!!t(e)||(!!(e instanceof AggregateError&&e.errors.some(e=>someErrorIs(e,t,r-1)))||!!(e instanceof Error&&"cause"in e&&someErrorIs(e.cause,t,r-1))))}const tracer$1=trace$1.getTracer("stepper/otel")
|
|
305
|
+
;let currentUser;function setOtelUser(e){currentUser=e;const t=trace$1.getActiveSpan();currentUser&&t&&(t.setAttribute(ATTR_USER_ID,currentUser.id),t.setAttribute(ATTR_USER_EMAIL,currentUser.email))}async function withSpan(e,t,r){const n=r?{startTime:r}:{};return tracer$1.startActiveSpan(e,n,async e=>{currentUser&&(e.setAttribute(ATTR_USER_ID,currentUser.id),e.setAttribute(ATTR_USER_EMAIL,currentUser.email));try{return await t(e)}catch(t){throw annotateSpanWithError(e,t),t}finally{e.end()}})}function annotateSpanWithError(e,t){let r;someErrorIs(t,e=>isAbortError$3(e))&&e.setAttribute("cancelled",!0),t instanceof Error&&(r=t.message),e.setStatus({code:SpanStatusCode.ERROR,message:r})}const GLOBAL_DIR_NAME=".tessl",PROJECTS_DIR_NAME="projects";function getGlobalDir(){const e=process.env.TESSL_GLOBAL_DIR;if(e&&""!==e.trim())return e;let t=GLOBAL_DIR_NAME;return join(homedir$1(),t)}function getProjectCacheDir(){const e=process.env.TESSL_PROJECT_CACHE_DIR;if(e&&""!==e.trim())return e
|
|
306
306
|
;const t=getGlobalDir(),r=getProjectDir().replace(/[/\\:]/g,"-").replace(/^-+/,"");return join(t,PROJECTS_DIR_NAME,r)}function getProjectDir(e=!1){const t=process.env.TESSL_PROJECT_DIR;if(t&&""!==t.trim())return t;let r=process.cwd();for(;;){const t=join(r,CONFIG_DIR_NAME);if(existsSync(t))return r;const n=dirname$1(r);if(n===r||n===homedir$1()){if(e)throw new Error("Tessl project root not found");return process.cwd()}r=n}}const T_AND_C_FILE="terms-and-conditions",T_AND_C_URL="https://tessl.io/policies/terms",T_AND_C_QUESTION=`You'll need to review and accept our Terms of Service at ${T_AND_C_URL} before running Tessl.\n\nAccept Terms of Service? [Y/n] `;async function checkLegal(){const e=getGlobalDir(),t=join$1(e,T_AND_C_FILE);if(!existsSync$1(t)||"accepted"!==readFileSync(t,"utf-8")){const e=createInterface({input:process.stdin,output:process.stdout}),r=await new Promise(t=>{e.question(T_AND_C_QUESTION,r=>{e.close(),t(r.toLowerCase())})});if("n"!==r){const e=dirname(t)
|
|
307
307
|
;return existsSync$1(e)||mkdirSync(e,{recursive:!0}),writeFileSync(t,"accepted","utf-8"),!0}return!1}return!0}const balanced=(e,t,r)=>{const n=e instanceof RegExp?maybeMatch(e,r):e,i=t instanceof RegExp?maybeMatch(t,r):t,s=null!==n&&null!=i&&range$3(n,i,r);return s&&{start:s[0],end:s[1],pre:r.slice(0,s[0]),body:r.slice(s[0]+n.length,s[1]),post:r.slice(s[1]+i.length)}},maybeMatch=(e,t)=>{const r=t.match(e);return r?r[0]:null},range$3=(e,t,r)=>{let n,i,s,o,a,c=r.indexOf(e),u=r.indexOf(t,c+1),l=c;if(c>=0&&u>0){if(e===t)return[c,u];for(n=[],s=r.length;l>=0&&!a;){if(l===c)n.push(l),c=r.indexOf(e,l+1);else if(1===n.length){const e=n.pop();void 0!==e&&(a=[e,u])}else i=n.pop(),void 0!==i&&i<s&&(s=i,o=u),u=r.indexOf(t,l+1);l=c<u&&c>=0?c:u}n.length&&void 0!==o&&(a=[s,o])}return a
|
|
308
308
|
},escSlash="\0SLASH"+Math.random()+"\0",escOpen="\0OPEN"+Math.random()+"\0",escClose="\0CLOSE"+Math.random()+"\0",escComma="\0COMMA"+Math.random()+"\0",escPeriod="\0PERIOD"+Math.random()+"\0",escSlashPattern=new RegExp(escSlash,"g"),escOpenPattern=new RegExp(escOpen,"g"),escClosePattern=new RegExp(escClose,"g"),escCommaPattern=new RegExp(escComma,"g"),escPeriodPattern=new RegExp(escPeriod,"g"),slashPattern=/\\\\/g,openPattern=/\\{/g,closePattern=/\\}/g,commaPattern=/\\,/g,periodPattern=/\\./g;function numeric(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function escapeBraces(e){return e.replace(slashPattern,escSlash).replace(openPattern,escOpen).replace(closePattern,escClose).replace(commaPattern,escComma).replace(periodPattern,escPeriod)}function unescapeBraces(e){return e.replace(escSlashPattern,"\\").replace(escOpenPattern,"{").replace(escClosePattern,"}").replace(escCommaPattern,",").replace(escPeriodPattern,".")}function parseCommaParts(e){if(!e)return[""]
|
|
@@ -444,7 +444,7 @@ void 0!==r.key&&(s=""+r.key),t.type&&t.type.defaultProps)var c=t.type.defaultPro
|
|
|
444
444
|
react_production_min.memo=function(e,t){return{$$typeof:u,type:e,compare:void 0===t?null:t}},react_production_min.startTransition=function(e){var t=x.transition;x.transition={};try{e()}finally{x.transition=t}},react_production_min.unstable_act=F,react_production_min.useCallback=function(e,t){return T.current.useCallback(e,t)},react_production_min.useContext=function(e){return T.current.useContext(e)},react_production_min.useDebugValue=function(){},react_production_min.useDeferredValue=function(e){return T.current.useDeferredValue(e)},react_production_min.useEffect=function(e,t){return T.current.useEffect(e,t)},react_production_min.useId=function(){return T.current.useId()},react_production_min.useImperativeHandle=function(e,t,r){return T.current.useImperativeHandle(e,t,r)},react_production_min.useInsertionEffect=function(e,t){return T.current.useInsertionEffect(e,t)},react_production_min.useLayoutEffect=function(e,t){return T.current.useLayoutEffect(e,t)},
|
|
445
445
|
react_production_min.useMemo=function(e,t){return T.current.useMemo(e,t)},react_production_min.useReducer=function(e,t,r){return T.current.useReducer(e,t,r)},react_production_min.useRef=function(e){return T.current.useRef(e)},react_production_min.useState=function(e){return T.current.useState(e)},react_production_min.useSyncExternalStore=function(e,t,r){return T.current.useSyncExternalStore(e,t,r)},react_production_min.useTransition=function(){return T.current.useTransition()},react_production_min.version="18.3.1",react_production_min}function requireReact(){return hasRequiredReact||(hasRequiredReact=1,react.exports=requireReact_production_min()),react.exports}function requireReactJsxRuntime_production_min(){if(hasRequiredReactJsxRuntime_production_min)return reactJsxRuntime_production_min;hasRequiredReactJsxRuntime_production_min=1
|
|
446
446
|
;var e=requireReact(),t=Symbol.for("react.element"),r=Symbol.for("react.fragment"),n=Object.prototype.hasOwnProperty,i=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,s={key:!0,ref:!0,__self:!0,__source:!0};function o(e,r,o){var a,c={},u=null,l=null;for(a in void 0!==o&&(u=""+o),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(l=r.ref),r)n.call(r,a)&&!s.hasOwnProperty(a)&&(c[a]=r[a]);if(e&&e.defaultProps)for(a in r=e.defaultProps)void 0===c[a]&&(c[a]=r[a]);return{$$typeof:t,type:e,key:u,ref:l,props:c,_owner:i.current}}return reactJsxRuntime_production_min.Fragment=r,reactJsxRuntime_production_min.jsx=o,reactJsxRuntime_production_min.jsxs=o,reactJsxRuntime_production_min}function requireJsxRuntime(){return hasRequiredJsxRuntime||(hasRequiredJsxRuntime=1,jsxRuntime.exports=requireReactJsxRuntime_production_min()),jsxRuntime.exports}var jsxRuntimeExports=requireJsxRuntime()
|
|
447
|
-
;const isUpKey=e=>"up"===e.name,isDownKey=e=>"down"===e.name,isSpaceKey=e=>"space"===e.name,isBackspaceKey=e=>"backspace"===e.name,isNumberKey=e=>"1234567890".includes(e.name),isEnterKey=e=>"enter"===e.name||"return"===e.name;class AbortPromptError extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}}class CancelPromptError extends Error{name="CancelPromptError";message="Prompt was canceled"}class ExitPromptError extends Error{name="ExitPromptError"}class HookError extends Error{name="HookError"}let ValidationError$1=class extends Error{name="ValidationError"};const hookStorage=new AsyncLocalStorage;function createStore(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function withHooks(e,t){const r=createStore(e);return hookStorage.run(r,()=>t(function(e){r.handleChange=()=>{r.index=0,e()},r.handleChange()}))}function getStore(){const e=hookStorage.getStore()
|
|
447
|
+
;const isUpKey=e=>"up"===e.name,isDownKey=e=>"down"===e.name,isSpaceKey=e=>"space"===e.name,isBackspaceKey=e=>"backspace"===e.name,isTabKey=e=>"tab"===e.name,isNumberKey=e=>"1234567890".includes(e.name),isEnterKey=e=>"enter"===e.name||"return"===e.name;class AbortPromptError extends Error{name="AbortPromptError";message="Prompt was aborted";constructor(e){super(),this.cause=e?.cause}}class CancelPromptError extends Error{name="CancelPromptError";message="Prompt was canceled"}class ExitPromptError extends Error{name="ExitPromptError"}class HookError extends Error{name="HookError"}let ValidationError$1=class extends Error{name="ValidationError"};const hookStorage=new AsyncLocalStorage;function createStore(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function withHooks(e,t){const r=createStore(e);return hookStorage.run(r,()=>t(function(e){r.handleChange=()=>{r.index=0,e()},r.handleChange()}))}function getStore(){const e=hookStorage.getStore()
|
|
448
448
|
;if(!e)throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");return e}function readline(){return getStore().rl}function withUpdates(e){return AsyncResource.bind((...t)=>{const r=getStore();let n=!1;const i=r.handleChange;r.handleChange=()=>{n=!0};const s=e(...t);return n&&i(),r.handleChange=i,s})}function withPointer(e){const t=getStore(),{index:r}=t,n=e({get:()=>t.hooks[r],set(e){t.hooks[r]=e},initialized:r in t.hooks});return t.index++,n}function handleChange(){getStore().handleChange()}const effectScheduler={queue(e){const t=getStore(),{index:r}=t;t.hooksEffect.push(()=>{t.hooksCleanup[r]?.();const n=e(readline());if(null!=n&&"function"!=typeof n)throw new ValidationError$1("useEffect return value must be a cleanup function or nothing.");t.hooksCleanup[r]=n})},run(){const e=getStore();withUpdates(()=>{e.hooksEffect.forEach(e=>{e()}),e.hooksEffect.length=0})()},clearAll(){const e=getStore();e.hooksCleanup.forEach(e=>{e?.()}),e.hooksEffect.length=0,
|
|
449
449
|
e.hooksCleanup.length=0}};function useState(e){return withPointer(t=>{const r=AsyncResource.bind(function(e){t.get()!==e&&(t.set(e),handleChange())});if(t.initialized)return[t.get(),r];const n="function"==typeof e?e():e;return t.set(n),[n,r]})}function useEffect(e,t){withPointer(r=>{const n=r.get(),i=!Array.isArray(n)||t.some((e,t)=>!Object.is(e,n[t]));i&&effectScheduler.queue(e),r.set(t)})}var yoctocolorsCjs,hasRequiredYoctocolorsCjs;function requireYoctocolorsCjs(){if(hasRequiredYoctocolorsCjs)return yoctocolorsCjs;hasRequiredYoctocolorsCjs=1;const e=tty$2,t=e?.WriteStream?.prototype?.hasColors?.()??!1,r=(e,r)=>{if(!t)return e=>e;const n=`[${e}m`,i=`[${r}m`;return e=>{const t=e+"";let r=t.indexOf(i);if(-1===r)return n+t+i;let s=n,o=0;for(;-1!==r;)s+=t.slice(o,r)+n,o=r+i.length,r=t.indexOf(i,o);return s+=t.slice(o)+i,s}},n={};return n.reset=r(0,0),n.bold=r(1,22),n.dim=r(2,22),n.italic=r(3,23),n.underline=r(4,24),n.overline=r(53,55),n.inverse=r(7,27),n.hidden=r(8,28),
|
|
450
450
|
n.strikethrough=r(9,29),n.black=r(30,39),n.red=r(31,39),n.green=r(32,39),n.yellow=r(33,39),n.blue=r(34,39),n.magenta=r(35,39),n.cyan=r(36,39),n.white=r(37,39),n.gray=r(90,39),n.bgBlack=r(40,49),n.bgRed=r(41,49),n.bgGreen=r(42,49),n.bgYellow=r(43,49),n.bgBlue=r(44,49),n.bgMagenta=r(45,49),n.bgCyan=r(46,49),n.bgWhite=r(47,49),n.bgGray=r(100,49),n.redBright=r(91,39),n.greenBright=r(92,39),n.yellowBright=r(93,39),n.blueBright=r(94,39),n.magentaBright=r(95,39),n.cyanBright=r(96,39),n.whiteBright=r(97,39),n.bgRedBright=r(101,49),n.bgGreenBright=r(102,49),n.bgYellowBright=r(103,49),n.bgBlueBright=r(104,49),n.bgMagentaBright=r(105,49),n.bgCyanBright=r(106,49),n.bgWhiteBright=r(107,49),yoctocolorsCjs=n}var yoctocolorsCjsExports=requireYoctocolorsCjs(),colors=getDefaultExportFromCjs(yoctocolorsCjsExports);function isUnicodeSupported$2(){
|
|
@@ -485,11 +485,11 @@ get columns(){return this.#gt("columns")}mute(){this.muted=!0}unmute(){this.mute
|
|
|
485
485
|
var libExports=requireLib$c(),MuteStream=getDefaultExportFromCjs(libExports);const signals$2=[];signals$2.push("SIGHUP","SIGINT","SIGTERM"),"win32"!==process.platform&&signals$2.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&signals$2.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");const processOk=e=>!!e&&"object"==typeof e&&"function"==typeof e.removeListener&&"function"==typeof e.emit&&"function"==typeof e.reallyExit&&"function"==typeof e.listeners&&"function"==typeof e.kill&&"number"==typeof e.pid&&"function"==typeof e.on,kExitEmitter=Symbol.for("signal-exit emitter"),global$3=globalThis,ObjectDefineProperty=Object.defineProperty.bind(Object);class Emitter{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(global$3[kExitEmitter])return global$3[kExitEmitter];ObjectDefineProperty(global$3,kExitEmitter,{value:this,writable:!1,enumerable:!1,
|
|
486
486
|
configurable:!1})}on(e,t){this.listeners[e].push(t)}removeListener(e,t){const r=this.listeners[e],n=r.indexOf(t);-1!==n&&(0===n&&1===r.length?r.length=0:r.splice(n,1))}emit(e,t,r){if(this.emitted[e])return!1;this.emitted[e]=!0;let n=!1;for(const i of this.listeners[e])n=!0===i(t,r)||n;return"exit"===e&&(n=this.emit("afterExit",t,r)||n),n}}class SignalExitBase{}const signalExitWrap=e=>({onExit:(t,r)=>e.onExit(t,r),load:()=>e.load(),unload:()=>e.unload()});class SignalExitFallback extends SignalExitBase{onExit(){return()=>{}}load(){}unload(){}}class SignalExit extends SignalExitBase{#yt="win32"===process$1.platform?"SIGINT":"SIGHUP";#Et=new Emitter;#bt;#Ct;#vt;#It={};#_t=!1;constructor(e){super(),this.#bt=e,this.#It={};for(const t of signals$2)this.#It[t]=()=>{const r=this.#bt.listeners(t);let{count:n}=this.#Et;const i=e;if("object"==typeof i.__signal_exit_emitter__&&"number"==typeof i.__signal_exit_emitter__.count&&(n+=i.__signal_exit_emitter__.count),r.length===n){this.unload()
|
|
487
487
|
;const r=this.#Et.emit("exit",null,t),n="SIGHUP"===t?this.#yt:t;r||e.kill(e.pid,n)}};this.#vt=e.reallyExit,this.#Ct=e.emit}onExit(e,t){if(!processOk(this.#bt))return()=>{};!1===this.#_t&&this.load();const r=t?.alwaysLast?"afterExit":"exit";return this.#Et.on(r,e),()=>{this.#Et.removeListener(r,e),0===this.#Et.listeners.exit.length&&0===this.#Et.listeners.afterExit.length&&this.unload()}}load(){if(!this.#_t){this.#_t=!0,this.#Et.count+=1;for(const e of signals$2)try{const t=this.#It[e];t&&this.#bt.on(e,t)}catch(e){}this.#bt.emit=(e,...t)=>this.#St(e,...t),this.#bt.reallyExit=e=>this.#Dt(e)}}unload(){this.#_t&&(this.#_t=!1,signals$2.forEach(e=>{const t=this.#It[e];if(!t)throw new Error("Listener not defined for signal: "+e);try{this.#bt.removeListener(e,t)}catch(e){}}),this.#bt.emit=this.#Ct,this.#bt.reallyExit=this.#vt,this.#Et.count-=1)}#Dt(e){return processOk(this.#bt)?(this.#bt.exitCode=e||0,this.#Et.emit("exit",this.#bt.exitCode,null),this.#vt.call(this.#bt,this.#bt.exitCode)):0}
|
|
488
|
-
#St(e,...t){const r=this.#Ct;if("exit"===e&&processOk(this.#bt)){"number"==typeof t[0]&&(this.#bt.exitCode=t[0]);const n=r.call(this.#bt,e,...t);return this.#Et.emit("exit",this.#bt.exitCode,null),n}return r.call(this.#bt,e,...t)}}const process$1=globalThis.process,{onExit}=signalExitWrap(processOk(process$1)?new SignalExit(process$1):new SignalExitFallback),ESC$1="[",cursorLeft$1=ESC$1+"G",cursorShow=ESC$1+"?25h",cursorUp$1=(e=1)=>e>0?`${ESC$1}${e}A`:"",cursorDown=(e=1)=>e>0?`${ESC$1}${e}B`:"",cursorTo=(e,t)=>`${ESC$1}${e+1}G`,eraseLine$1=ESC$1+"2K",eraseLines$1=e=>e>0?(eraseLine$1+cursorUp$1(1)).repeat(e-1)+eraseLine$1+cursorLeft$1:"",height=e=>e.split("\n").length,lastLine=e=>e.split("\n").pop()??"";class ScreenManager{height=0;extraLinesUnderPrompt=0;cursorPos;rl;constructor(e){this.rl=e,this.cursorPos=e.getCursorPos()}write(e){this.rl.output.unmute(),this.rl.output.write(e),this.rl.output.mute()}render(e,t=""){
|
|
489
|
-
;this.rl.line.length>0&&(i=i.slice(0,-this.rl.line.length)),this.rl.setPrompt(i),this.cursorPos=this.rl.getCursorPos();const s=readlineWidth();e=breakLines(e,s),t=breakLines(t,s),n.length%s===0&&(e+="\n");let o=e+(t?"\n"+t:"");const a=Math.floor(n.length/s)-this.cursorPos.rows+(t?height(t):0);a>0&&(o+=cursorUp$1(a)),o+=cursorTo(this.cursorPos.cols),this.write(cursorDown(this.extraLinesUnderPrompt)+eraseLines$1(this.height)+o),this.extraLinesUnderPrompt=a,this.height=height(o)}checkCursorPos(){const e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(cursorTo(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt("");let t=cursorDown(this.extraLinesUnderPrompt);t+=e?eraseLines$1(this.height):"\n",t+=cursorShow,this.write(t),this.rl.close()}}class PromisePolyfill extends Promise{static withResolver(){let e,t;return{promise:new Promise((r,n)=>{e=r,t=n}),resolve:e,reject:t}}}function getCallSites(){
|
|
490
|
-
Error.prepareStackTrace=(e,r)=>{const n=r.slice(1);return t=n,n},(new Error).stack}catch{return t}return Error.prepareStackTrace=e,t}function createPrompt(e){const t=getCallSites();return(r,n={})=>{const{input:i=process.stdin,signal:s}=n,o=new Set,a=new MuteStream;a.pipe(n.output??process.stdout);const c=readline$3.createInterface({terminal:!0,input:i,output:a}),u=new ScreenManager(c),{promise:l,resolve:d,reject:p}=PromisePolyfill.withResolver(),h=()=>p(new CancelPromptError);if(s){const e=()=>p(new AbortPromptError({cause:s.reason}));if(s.aborted)return e(),Object.assign(l,{cancel:h});s.addEventListener("abort",e),o.add(()=>s.removeEventListener("abort",e))}o.add(onExit((e,t)=>{p(new ExitPromptError(`User force closed the prompt with ${e} ${t}`))}));const A=()=>p(new ExitPromptError("User force closed the prompt with SIGINT"));c.on("SIGINT",A),o.add(()=>c.removeListener("SIGINT",A));const f=()=>u.checkCursorPos()
|
|
491
|
-
o.add(()=>c.input.removeListener("keypress",f)),withHooks(c,i=>{const s=AsyncResource.bind(()=>effectScheduler.clearAll());return c.on("close",s),o.add(()=>c.removeListener("close",s)),i(()=>{try{const n=e(r,e=>{setImmediate(()=>d(e))});if(void 0===n){const e=t[1]?.getFileName();throw new Error(`Prompt functions must return a string.\n at ${e}`)}const[i,s]="string"==typeof n?[n]:n;u.render(i,s),effectScheduler.run()}catch(e){p(e)}}),Object.assign(l.then(e=>(effectScheduler.clearAll(),e),e=>{throw effectScheduler.clearAll(),e}).finally(()=>{o.forEach(e=>e()),u.done({clearContent:Boolean(n.clearPromptOnDone)}),a.end()}).then(()=>l),{cancel:h})})}}class Separator{separator=colors.dim(Array.from({length:15}).join(figures$1.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return Boolean(e&&"object"==typeof e&&"type"in e&&"separator"===e.type)}}var arg_1,hasRequiredArg;function requireArg(){if(hasRequiredArg)return arg_1
|
|
492
|
-
;const e=Symbol("arg flag");class t extends Error{constructor(e,r){super(e),this.name="ArgError",this.code=r,Object.setPrototypeOf(this,t.prototype)}}function r(r,{argv:n=process.argv.slice(2),permissive:i=!1,stopAtPositional:s=!1}={}){if(!r)throw new t("argument specification object is required","ARG_CONFIG_NO_SPEC");const o={_:[]},a={},c={};for(const n of Object.keys(r)){if(!n)throw new t("argument key cannot be an empty string","ARG_CONFIG_EMPTY_KEY");if("-"!==n[0])throw new t(`argument key must start with '-' but found: '${n}'`,"ARG_CONFIG_NONOPT_KEY");if(1===n.length)throw new t(`argument key must have a name; singular '-' keys are not allowed: ${n}`,"ARG_CONFIG_NONAME_KEY");if("string"==typeof r[n]){a[n]=r[n];continue}let i=r[n],s=!1;if(Array.isArray(i)&&1===i.length&&"function"==typeof i[0]){const[t]=i;i=(e,r,n=[])=>(n.push(t(e,r,n[n.length-1])),n),s=t===Boolean||!0===t[e]}else{
|
|
488
|
+
#St(e,...t){const r=this.#Ct;if("exit"===e&&processOk(this.#bt)){"number"==typeof t[0]&&(this.#bt.exitCode=t[0]);const n=r.call(this.#bt,e,...t);return this.#Et.emit("exit",this.#bt.exitCode,null),n}return r.call(this.#bt,e,...t)}}const process$1=globalThis.process,{onExit}=signalExitWrap(processOk(process$1)?new SignalExit(process$1):new SignalExitFallback),ESC$1="[",cursorLeft$1=ESC$1+"G",cursorHide=ESC$1+"?25l",cursorShow=ESC$1+"?25h",cursorUp$1=(e=1)=>e>0?`${ESC$1}${e}A`:"",cursorDown=(e=1)=>e>0?`${ESC$1}${e}B`:"",cursorTo=(e,t)=>`${ESC$1}${e+1}G`,eraseLine$1=ESC$1+"2K",eraseLines$1=e=>e>0?(eraseLine$1+cursorUp$1(1)).repeat(e-1)+eraseLine$1+cursorLeft$1:"",height=e=>e.split("\n").length,lastLine=e=>e.split("\n").pop()??"";class ScreenManager{height=0;extraLinesUnderPrompt=0;cursorPos;rl;constructor(e){this.rl=e,this.cursorPos=e.getCursorPos()}write(e){this.rl.output.unmute(),this.rl.output.write(e),this.rl.output.mute()}render(e,t=""){
|
|
489
|
+
const r=lastLine(e),n=stripVTControlCharacters(r);let i=n;this.rl.line.length>0&&(i=i.slice(0,-this.rl.line.length)),this.rl.setPrompt(i),this.cursorPos=this.rl.getCursorPos();const s=readlineWidth();e=breakLines(e,s),t=breakLines(t,s),n.length%s===0&&(e+="\n");let o=e+(t?"\n"+t:"");const a=Math.floor(n.length/s)-this.cursorPos.rows+(t?height(t):0);a>0&&(o+=cursorUp$1(a)),o+=cursorTo(this.cursorPos.cols),this.write(cursorDown(this.extraLinesUnderPrompt)+eraseLines$1(this.height)+o),this.extraLinesUnderPrompt=a,this.height=height(o)}checkCursorPos(){const e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(cursorTo(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt("");let t=cursorDown(this.extraLinesUnderPrompt);t+=e?eraseLines$1(this.height):"\n",t+=cursorShow,this.write(t),this.rl.close()}}class PromisePolyfill extends Promise{static withResolver(){let e,t;return{promise:new Promise((r,n)=>{e=r,t=n}),resolve:e,reject:t}}}function getCallSites(){
|
|
490
|
+
const e=Error.prepareStackTrace;let t=[];try{Error.prepareStackTrace=(e,r)=>{const n=r.slice(1);return t=n,n},(new Error).stack}catch{return t}return Error.prepareStackTrace=e,t}function createPrompt(e){const t=getCallSites();return(r,n={})=>{const{input:i=process.stdin,signal:s}=n,o=new Set,a=new MuteStream;a.pipe(n.output??process.stdout);const c=readline$3.createInterface({terminal:!0,input:i,output:a}),u=new ScreenManager(c),{promise:l,resolve:d,reject:p}=PromisePolyfill.withResolver(),h=()=>p(new CancelPromptError);if(s){const e=()=>p(new AbortPromptError({cause:s.reason}));if(s.aborted)return e(),Object.assign(l,{cancel:h});s.addEventListener("abort",e),o.add(()=>s.removeEventListener("abort",e))}o.add(onExit((e,t)=>{p(new ExitPromptError(`User force closed the prompt with ${e} ${t}`))}));const A=()=>p(new ExitPromptError("User force closed the prompt with SIGINT"));c.on("SIGINT",A),o.add(()=>c.removeListener("SIGINT",A));const f=()=>u.checkCursorPos()
|
|
491
|
+
;return c.input.on("keypress",f),o.add(()=>c.input.removeListener("keypress",f)),withHooks(c,i=>{const s=AsyncResource.bind(()=>effectScheduler.clearAll());return c.on("close",s),o.add(()=>c.removeListener("close",s)),i(()=>{try{const n=e(r,e=>{setImmediate(()=>d(e))});if(void 0===n){const e=t[1]?.getFileName();throw new Error(`Prompt functions must return a string.\n at ${e}`)}const[i,s]="string"==typeof n?[n]:n;u.render(i,s),effectScheduler.run()}catch(e){p(e)}}),Object.assign(l.then(e=>(effectScheduler.clearAll(),e),e=>{throw effectScheduler.clearAll(),e}).finally(()=>{o.forEach(e=>e()),u.done({clearContent:Boolean(n.clearPromptOnDone)}),a.end()}).then(()=>l),{cancel:h})})}}class Separator{separator=colors.dim(Array.from({length:15}).join(figures$1.line));type="separator";constructor(e){e&&(this.separator=e)}static isSeparator(e){return Boolean(e&&"object"==typeof e&&"type"in e&&"separator"===e.type)}}var arg_1,hasRequiredArg;function requireArg(){if(hasRequiredArg)return arg_1
|
|
492
|
+
;hasRequiredArg=1;const e=Symbol("arg flag");class t extends Error{constructor(e,r){super(e),this.name="ArgError",this.code=r,Object.setPrototypeOf(this,t.prototype)}}function r(r,{argv:n=process.argv.slice(2),permissive:i=!1,stopAtPositional:s=!1}={}){if(!r)throw new t("argument specification object is required","ARG_CONFIG_NO_SPEC");const o={_:[]},a={},c={};for(const n of Object.keys(r)){if(!n)throw new t("argument key cannot be an empty string","ARG_CONFIG_EMPTY_KEY");if("-"!==n[0])throw new t(`argument key must start with '-' but found: '${n}'`,"ARG_CONFIG_NONOPT_KEY");if(1===n.length)throw new t(`argument key must have a name; singular '-' keys are not allowed: ${n}`,"ARG_CONFIG_NONAME_KEY");if("string"==typeof r[n]){a[n]=r[n];continue}let i=r[n],s=!1;if(Array.isArray(i)&&1===i.length&&"function"==typeof i[0]){const[t]=i;i=(e,r,n=[])=>(n.push(t(e,r,n[n.length-1])),n),s=t===Boolean||!0===t[e]}else{
|
|
493
493
|
if("function"!=typeof i)throw new t(`type missing or not a function or valid array type: ${n}`,"ARG_CONFIG_VAD_TYPE");s=i===Boolean||!0===i[e]}if("-"!==n[1]&&n.length>2)throw new t(`short argument keys (with a single hyphen) must have only one character: ${n}`,"ARG_CONFIG_SHORTOPT_TOOLONG");c[n]=[i,s]}for(let e=0,r=n.length;e<r;e++){const r=n[e];if(s&&o._.length>0){o._=o._.concat(n.slice(e));break}if("--"===r){o._=o._.concat(n.slice(e+1));break}if(r.length>1&&"-"===r[0]){const s="-"===r[1]||2===r.length?[r]:r.slice(1).split("").map(e=>`-${e}`);for(let r=0;r<s.length;r++){const u=s[r],[l,d]="-"===u[1]?u.split(/=(.*)/,2):[u,void 0];let p=l;for(;p in a;)p=a[p];if(!(p in c)){if(i){o._.push(u);continue}throw new t(`unknown or unexpected option: ${l}`,"ARG_UNKNOWN_OPTION")}const[h,A]=c[p];if(!A&&r+1<s.length)throw new t(`option requires argument (but was followed by another short argument): ${l}`,"ARG_MISSING_REQUIRED_SHORTARG");if(A)o[p]=h(!0,p,o[p]);else if(void 0===d){
|
|
494
494
|
if(n.length<e+2||n[e+1].length>1&&"-"===n[e+1][0]&&(!n[e+1].match(/^-?\d*(\.(?=\d))?\d*$/)||h!==Number&&("undefined"==typeof BigInt||h!==BigInt))){throw new t(`option requires argument: ${l}${l===p?"":` (alias for ${p})`}`,"ARG_MISSING_REQUIRED_LONGARG")}o[p]=h(n[e+1],p,o[p]),++e}else o[p]=h(d,p,o[p])}}else o._.push(r)}return o}return r.flag=t=>(t[e]=!0,t),r.COUNT=r.flag((e,t,r)=>(r||0)+1),r.ArgError=t,arg_1=r}var argExports=requireArg(),arg=getDefaultExportFromCjs(argExports),reactExports=requireReact(),React=getDefaultExportFromCjs(reactExports);function debounce$1(e,t=0,r={}){"object"!=typeof r&&(r={});let n,i=null,s=null,o=null,a=0,c=null;const{leading:u=!1,trailing:l=!0,maxWait:d}=r,p="maxWait"in r,h=p?Math.max(Number(d)||0,t):0,A=t=>(null!==i&&(n=e.apply(s,i)),i=s=null,a=t,n),f=e=>(c=null,l&&null!==i?A(e):n),g=e=>{if(null===o)return!0;const r=e-o;return r>=t||r<0||p&&e-a>=h},m=()=>{const e=Date.now();if(g(e))return f(e);c=setTimeout(m,(e=>{const r=t-(null===o?0:e-o),n=h-(e-a)
|
|
495
495
|
;return p?Math.min(r,n):r})(e))},y=function(...e){const r=Date.now(),l=g(r);if(i=e,s=this,o=r,l){if(null===c)return(e=>(a=e,c=setTimeout(m,t),u&&null!==i?A(e):n))(r);if(p)return clearTimeout(c),c=setTimeout(m,t),A(r)}return null===c&&(c=setTimeout(m,t)),n};return y.cancel=()=>{null!==c&&clearTimeout(c),a=0,o=i=s=c=null},y.flush=()=>null===c?n:f(Date.now()),y}function throttle$2(e,t=0,r={}){const{leading:n=!0,trailing:i=!0}=r;return debounce$1(e,t,{leading:n,maxWait:t,trailing:i})}const isBrowser=void 0!==globalThis.window?.document;globalThis.process,globalThis.process,globalThis.Deno,globalThis.process,globalThis.navigator?.userAgent?.includes("jsdom");const platform=globalThis.navigator?.userAgentData?.platform;"macOS"===platform||"MacIntel"===globalThis.navigator?.platform||!0===globalThis.navigator?.userAgent?.includes(" Mac ")||globalThis.process,"Windows"===platform||"Win32"===globalThis.navigator?.platform||globalThis.process,
|
|
@@ -953,9 +953,9 @@ e===this._stream&&(this._stream=null,this._finalizing&&this.finalize(),this._pen
|
|
|
953
953
|
return pack=function(e){return new c(e)}}function requireTarStream(){return hasRequiredTarStream||(hasRequiredTarStream=1,tarStream.extract=requireExtract(),tarStream.pack=requirePack()),tarStream}var tarStreamExports=requireTarStream(),tar=getDefaultExportFromCjs(tarStreamExports);function _optionalChain$10(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}const WELL_KNOWN_PACKAGE_TILE_MANIFEST_FILENAME="package.tile.json";function parsePackageTileManifest(e){const t=JSON.parse(e);return _optionalChain$10([t,"optionalAccess",e=>e.spec])?t:void 0}function findPackageTileManifest(e){const t=e[WELL_KNOWN_PACKAGE_TILE_MANIFEST_FILENAME];return t?parsePackageTileManifest(t):void 0}function getPackageSpec(e,t){if(_optionalChain$10([t,"optionalAccess",e=>e.spec])){const r=e[t.spec]
|
|
954
954
|
;if(r)return{path:t.spec,content:r}}}function _optionalChain$$(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}async function extractFilesFromNpmPackage(e,{npmRegistryUrl:t}){const r=purlToNpmTarballUrl(e,t),n=await fetchFilesFromTarGz(r);if(!n.ok)return n;const i=n.files["package.json"],s=findPackageTileManifest(n.files),o=getPackageSpec(n.files,s),a=findReadme(n.files),c={};return i&&(c["package.json"]=i),s&&(c[WELL_KNOWN_PACKAGE_TILE_MANIFEST_FILENAME]=JSON.stringify(s)),o&&(c[o.path]=o.content),{ok:!0,packageTileManifest:s,packageSpec:_optionalChain$$([o,"optionalAccess",e=>e.content]),readme:a,files:c}}async function fetchFilesFromTarGz(e){const t=validateFetchResponse(await fetch(e));if(!t.ok)return t;const r={},n=tar.extract();return n.on("entry",(e,t,n)=>{
|
|
955
955
|
if(shouldCollectFile(e)){let i="";t.on("data",e=>i+=e.toString()),t.on("end",()=>{r[e.name.replace(/^package\//,"")]=i,n()})}else t.resume(),t.on("end",n)}),await pipeline(Readable$1.fromWeb(t.body),createGunzip(),n),{ok:!0,files:r}}function shouldCollectFile({type:e,name:t}){if("file"!==e)return!1;if("package/package.json"===t)return!0;if(t===`package/${WELL_KNOWN_PACKAGE_TILE_MANIFEST_FILENAME}`)return!0;if("package/readme.md"===t.toLowerCase())return!0;return[".md",".markdown",".mdown"].some(e=>t.toLowerCase().endsWith(e))}function purlToNpmTarballUrl(e,t){return`${t}/${e.namespace?`${e.namespace}/${e.name}`:e.name}/-/${e.name}-${e.version}.tgz`}function validateFetchResponse(e){return e.ok&&e.body?{ok:!0,body:e.body}:404===e.status?{ok:!1,reason:`Tarball not found at ${e.url}`}:{ok:!1,reason:`Failed to fetch tarball from ${e.url} Status: ${e.statusText}`}}function findReadme(e){for(const[t,r]of Object.entries(e))if(r&&"readme.md"===t.toLowerCase())return r}
|
|
956
|
-
function _optionalChain$_(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}const npmRegistryUrl="https://registry.npmjs.org";async function extractPackageContents(e){return _optionalChain$_([e,"access",e=>e.qualifiers,"optionalAccess",e=>e.repository_url])?{ok:!1,reason:`PackageURL with repository_url is not yet supported: ${e.toString()}`}:e.qualifiers&&Object.keys(e.qualifiers).length>0?{ok:!1,reason:`PackageURL with qualifiers is not yet supported: ${e.toString()}`}:e.version?"npm"===e.type?await extractFilesFromNpmPackage(e,{npmRegistryUrl}):{ok:!1,reason:`Unsupported package type: ${e.type}`}:{ok:!1,reason:"PackageURL must include a version"}}function purlToPackageDisplayName(e){
|
|
957
|
-
;throw new Error(
|
|
958
|
-
message:"Package is not a Tile package"}}),0;const{summaryText:c,descriptionMarkdown:u,lookupText:l}=await generateText(e.script,i,o,a);return await n.submitTilePackageVersion({purl:i.toString(),summaryText:c,descriptionMarkdown:u,lookupText:l,readmeText:a,filesJson:JSON.stringify(s.files)}),await r.emitMgmt({id:"setOutput",value:{ok:!0,message:"Package processed successfully"}}),0}async function generateText(e,t,r,n){const i=purlToPackageDisplayName(t),s=stripIndent`
|
|
956
|
+
function _optionalChain$_(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}const npmRegistryUrl="https://registry.npmjs.org";async function extractPackageContents(e){return _optionalChain$_([e,"access",e=>e.qualifiers,"optionalAccess",e=>e.repository_url])?{ok:!1,reason:`PackageURL with repository_url is not yet supported: ${e.toString()}`}:e.qualifiers&&Object.keys(e.qualifiers).length>0?{ok:!1,reason:`PackageURL with qualifiers is not yet supported: ${e.toString()}`}:e.version?"npm"===e.type?await extractFilesFromNpmPackage(e,{npmRegistryUrl}):{ok:!1,reason:`Unsupported package type: ${e.type}`}:{ok:!1,reason:"PackageURL must include a version"}}function purlToPackageDisplayName(e){switch(e.type){case"npm":return e.namespace?`${e.namespace}/${e.name}`:e.name;case"pypi":
|
|
957
|
+
return e.name;case"maven":return e.namespace?`${e.namespace}:${e.name}`:e.name;default:throw new Error(`Unsupported package type: ${e.type}. Only npm, pypi, and maven are supported`)}}const processPackageParamsSchema=objectType$1({purl:stringType$1()}),processPackage={name:"process-package",type:"fsd",impl:processPackageImpl,paramsSchema:processPackageParamsSchema,description:"Extracts metadata from a Package URL and publishes to the Tile Directory",visibility:"private"};async function processPackageImpl({utils:e,params:t,rc:r}){const n=r.tilePackagesClient;if(!n)throw new Error("Tile Packages client is not available in the request context");const i=packageurlJsExports.PackageURL.fromString(t.purl);r.logger.debug({purl:t.purl},"Processing package with purl");const s=await extractPackageContents(i);if(!s.ok)return r.logger.error({purl:t.purl},s.reason),await r.emitMgmt({id:"setOutput",value:{ok:!1,message:s.reason}}),0;const o=s.packageSpec,a=s.readme;if(!o)return r.logger.warn({
|
|
958
|
+
purl:t.purl},"package spec not found"),await r.emitMgmt({id:"setOutput",value:{ok:!1,message:"Package is not a Tile package"}}),0;const{summaryText:c,descriptionMarkdown:u,lookupText:l}=await generateText(e.script,i,o,a);return await n.submitTilePackageVersion({purl:i.toString(),summaryText:c,descriptionMarkdown:u,lookupText:l,readmeText:a,filesJson:JSON.stringify(s.files)}),await r.emitMgmt({id:"setOutput",value:{ok:!0,message:"Package processed successfully"}}),0}async function generateText(e,t,r,n){const i=purlToPackageDisplayName(t),s=stripIndent`
|
|
959
959
|
You are a software engineer tasked with summarizing the contents of a published software package.
|
|
960
960
|
Keep the response concise and focused on the package itself.
|
|
961
961
|
Do not include any links to external resources.
|
|
@@ -2333,21 +2333,23 @@ const ZodUnion$1=$constructor("ZodUnion",(e,t)=>{$ZodUnion.init(e,t),ZodType$1.i
|
|
|
2333
2333
|
$ZodOptional.init(e,t),ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType});function optional(e){return new ZodOptional$1({type:"optional",innerType:e})}const ZodNullable$1=$constructor("ZodNullable",(e,t)=>{$ZodNullable.init(e,t),ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType});function nullable(e){return new ZodNullable$1({type:"nullable",innerType:e})}const ZodDefault$1=$constructor("ZodDefault",(e,t)=>{$ZodDefault.init(e,t),ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function _default(e,t){return new ZodDefault$1({type:"default",innerType:e,get defaultValue(){return"function"==typeof t?t():t}})}const ZodPrefault=$constructor("ZodPrefault",(e,t)=>{$ZodPrefault.init(e,t),ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType});function prefault(e,t){return new ZodPrefault({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof t?t():t}})}const ZodNonOptional=$constructor("ZodNonOptional",(e,t)=>{$ZodNonOptional.init(e,t),
|
|
2334
2334
|
ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType});function nonoptional(e,t){return new ZodNonOptional({type:"nonoptional",innerType:e,...normalizeParams(t)})}const ZodCatch$1=$constructor("ZodCatch",(e,t)=>{$ZodCatch.init(e,t),ZodType$1.init(e,t),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function _catch(e,t){return new ZodCatch$1({type:"catch",innerType:e,catchValue:"function"==typeof t?t:()=>t})}const ZodPipe=$constructor("ZodPipe",(e,t)=>{$ZodPipe.init(e,t),ZodType$1.init(e,t),e.in=t.in,e.out=t.out});function pipe$3(e,t){return new ZodPipe({type:"pipe",in:e,out:t})}const ZodReadonly$1=$constructor("ZodReadonly",(e,t)=>{$ZodReadonly.init(e,t),ZodType$1.init(e,t)});function readonly(e){return new ZodReadonly$1({type:"readonly",innerType:e})}const ZodCustom=$constructor("ZodCustom",(e,t)=>{$ZodCustom.init(e,t),ZodType$1.init(e,t)});function check$1(e){const t=new $ZodCheck({check:"custom"});return t._zod.check=e,t}function refine(e,t={}){
|
|
2335
2335
|
return _refine(ZodCustom,e,t)}function superRefine(e){const t=check$1(r=>(r.addIssue=e=>{if("string"==typeof e)r.issues.push(issue(e,r.value,t._zod.def));else{const n=e;n.fatal&&(n.continue=!1),n.code??(n.code="custom"),n.input??(n.input=r.value),n.inst??(n.inst=t),n.continue??(n.continue=!t._zod.def.abort),r.issues.push(issue(n))}},e(r.value,r)));return t}const DEFAULT_KNOWLEDGE_MD_CONTENT="# Knowledge Index\n\n";function ensureKnowledgeMd(e){const t=path__default.resolve(e,KNOWLEDGE_MD_FILENAME$1);if(!fs$8.existsSync(t)){fs$8.writeFileSync(t,DEFAULT_KNOWLEDGE_MD_CONTENT);return[path__default.relative(e,t)]}return[]}const TesslJsonSchema=object$1({name:string$2(),dependencies:record(string$2(),object$1({version:string$2(),source:string$2().optional()})).optional()}),TESSL_JSON_FILENAME="tessl.json";async function hasTesslJson(e){try{return await access(path__default$1.join(e,TESSL_JSON_FILENAME)),!0}catch(e){return!1}}async function readTesslJson$1(e){
|
|
2336
|
-
const t=path__default$1.join(e,TESSL_JSON_FILENAME),r=await readFile$1(t,"utf-8");return JSON.parse(r)}function safeParseTesslJson(e){return TesslJsonSchema.safeParse(e)}function validateTesslJson(e){const t=safeParseTesslJson(e);if(!t.success)throw new Error(`Tessl JSON validation failed: ${t.error.message}`);return t.data}function ensureTesslJsonSync(e,t){const r=path__default$1.join(e,TESSL_JSON_FILENAME);if(!existsSync(r))return writeFileSync$1(r,JSON.stringify(t,null,2)),path__default$1.relative(e,r)}async function throwIfNotInitialised(e){if(!await hasTesslJson(e))throw new RequiresInitError;validateTesslJson(await readTesslJson$1(e))}
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
function
|
|
2342
|
-
const
|
|
2343
|
-
;if(!
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2336
|
+
const t=path__default$1.join(e,TESSL_JSON_FILENAME),r=await readFile$1(t,"utf-8");return JSON.parse(r)}function safeParseTesslJson(e){return TesslJsonSchema.safeParse(e)}function validateTesslJson(e){const t=safeParseTesslJson(e);if(!t.success)throw new Error(`Tessl JSON validation failed: ${t.error.message}`);return t.data}function ensureTesslJsonSync(e,t){const r=path__default$1.join(e,TESSL_JSON_FILENAME);if(!existsSync(r))return writeFileSync$1(r,JSON.stringify(t,null,2)),path__default$1.relative(e,r)}async function throwIfNotInitialised(e){if(!await hasTesslJson(e))throw new RequiresInitError;validateTesslJson(await readTesslJson$1(e))}function extractSteeringRules(e){return e?Object.entries(e).map(([e,t])=>({name:e,rules:t.rules})):[]}async function copyDirectory(e,t){if(resolve$2(e)!==e)throw new Error(`Source path must be absolute: ${e}`);if(resolve$2(t)!==t)throw new Error(`Destination path must be absolute: ${t}`);try{
|
|
2337
|
+
if(!(await fsp.stat(e)).isDirectory())throw new Error(`Source is not a directory: ${e}`)}catch(t){if(isErrnoException(t)&&"ENOENT"===t.code)throw new Error(`Source directory not found: ${e}`);throw t}await fsp.mkdir(t,{recursive:!0});const r=await glob("**/*",{cwd:e,nodir:!0,dot:!0});for(const n of r){const r=join(e,n),i=join(t,n),s=join(t,relative$1(e,join(r,"..")));await fsp.mkdir(s,{recursive:!0}),await fsp.copyFile(r,i)}}function isErrnoException(e){return"object"==typeof e&&null!==e&&"code"in e}const CURSOR_DIR=".cursor",CURSOR_RULES_DIR=join(CURSOR_DIR,"rules"),CURSOR_TESSL_DIR=join(CURSOR_RULES_DIR,"tessl"),CURSOR_TILES_DIR=join(CURSOR_TESSL_DIR,"tiles"),CURSOR_GITIGNORE=join(CURSOR_TESSL_DIR,".gitignore"),CURSOR_GITIGNORE_CONTENT="tiles\n";async function detectCursorProject(e){return exists(join(e,CURSOR_DIR))}async function ensureCursorGitignore(e){const t=join(e,CURSOR_GITIGNORE);await exists(t)||(await mkdir(join(e,CURSOR_TESSL_DIR),{recursive:!0}),
|
|
2338
|
+
await writeFile(t,CURSOR_GITIGNORE_CONTENT))}function generateMdcContent(e){return`---\nalwaysApply: true\n---\n\n${e}`}async function shouldCopyCursorTile(e,t){if(!await exists(e))return!0;const r=join(e,SPEC_MANIFEST_NAME);if(!await exists(r))return!0;try{const e=await readText(r);return JSON.parse(e).version!==t}catch(e){return!0}}async function batchDeletePaths$1(e){await pMap(e,async e=>{try{await rm(e,{recursive:!0})}catch(e){}},{concurrency:8})}async function copyTileWithMdcFiles(e,t){const r=extractSteeringRules(t.steering);if(0===r.length)return;const n=join(e,USAGE_SPEC_DIR_PATH,t.workspaceName,t.tileName),i=join(e,CURSOR_TILES_DIR,t.workspaceName,t.tileName),s=n;if(await shouldCopyCursorTile(i,t.version)){await exists(i)&&await rm(i,{recursive:!0}),await copyDirectory(s,i);for(const e of r){const t=join(i,e.rules),r=t.replace(/\.md$/,".mdc"),n=generateMdcContent(await readText(t));await writeFile(r,n)}}}async function maybeGenerateCursorRules(e,t){
|
|
2339
|
+
if(!await detectCursorProject(e))return;await ensureCursorGitignore(e);const r=join(e,CURSOR_TILES_DIR),n=new Set,i=await glob(join(r,"**",SPEC_MANIFEST_NAME));for(const e of i)n.add(dirname$1(e));const s=new Set;for(const n of t)await copyTileWithMdcFiles(e,n),s.add(join(r,n.workspaceName,n.tileName));const o=Array.from(n.difference(s));await batchDeletePaths$1(o)}const RULES_MD_FILENAME="RULES.md",DEFAULT_RULES_MD_CONTENT="# Agent Rules\n\nThis file is updated running `tessl registry install`. If a linked file is missing, make sure to run the command to download any missing tiles from the registry.";function ensureRulesMd(e){const t=path__default.resolve(e,RULES_MD_FILENAME);if(!fs$8.existsSync(t)){fs$8.writeFileSync(t,DEFAULT_RULES_MD_CONTENT);return[path__default.relative(e,t)]}return[]}function generateRulesMd(e){const t=[DEFAULT_RULES_MD_CONTENT];for(const r of e){const e=extractSteeringRules(r.steering);if(0!==e.length)for(const n of e){
|
|
2340
|
+
const e=join(USAGE_SPEC_DIR_PATH,r.workspaceName,r.tileName,n.rules);t.push(`## ${r.fullName} â ${n.name}`),t.push(`@${e} [${n.name}](${e})`)}}return t.join("\n\n")}function findTilesWithSteering(e){return e.filter(e=>void 0!==e.steering&&Object.keys(e.steering).length>0).map(e=>{const[t,r]=e.name.split("/");if(!t||!r)throw new Error(`Invalid tile name format: ${e.name}`);return{workspaceName:t,tileName:r,fullName:e.name,version:e.version,steering:e.steering}}).sort((e,t)=>e.fullName.localeCompare(t.fullName))}function _nullishCoalesce$s(e,t){return null!=e?e:t()}const TileManifest=object$1({name:string$2(),version:string$2(),summary:string$2(),private:boolean$1().optional(),describes:string$2().optional(),docs:string$2().optional(),steering:record(string$2(),object$1({rules:string$2()})).optional()}).refine(e=>!(e.describes&&!e.docs),{message:"docs is required when describes is set"
|
|
2341
|
+
}),USAGE_SPEC_DIR_NAME="usage-specs",USAGE_SPEC_DIR_PATH=join$1(CONFIG_DIR_NAME,USAGE_SPEC_DIR_NAME),SPEC_MANIFEST_NAME="tile.json";async function shouldInstall(e,t){if(!await exists(e))return!0;const r=join$1(e,SPEC_MANIFEST_NAME);if(!await exists(r))return!0;const n=await readText(r),i=JSON.parse(n),s=TileManifest.safeParse(i);return!s.success||s.data.version!==t}async function downloadAndWriteTile(e,t,r,n,i){if(await shouldInstall(t,i)){const s=await e.GET("/v1/tiles/{workspaceName}/{tileName}/versions/{version}/files",{params:{path:{workspaceName:r,tileName:n,version:i},header:{accept:"application/gzip"}},parseAs:"arrayBuffer"});if(s.error)return{success:!1,error:apiErrToString(s.error)};const o=await writeDocs(Buffer.from(s.data),t);if(!o.success)return{success:!1,error:o.errMsg}}const s=join$1(t,SPEC_MANIFEST_NAME);if(!await exists(s))return{success:!1,error:`Download is malformed: ${SPEC_MANIFEST_NAME} manifest not found in ${t}`}
|
|
2342
|
+
;const o=await readText(s),a=JSON.parse(o),c=TileManifest.safeParse(a);return c.success?{success:!0,manifest:c.data}:{success:!1,error:`Download is malformed: ${s} is invalid`}}async function writeDocs(e,t){try{return await extractTarGz(e,t),{success:!0}}catch(e){return{success:!1,errMsg:`Failed to extract usage spec files: ${e instanceof Error?e.message:"Unknown error"}`}}}async function extractTarGz(e,t){return new Promise((r,n)=>{const i=tarStreamExports.extract();i.on("entry",(e,r,i)=>{(async()=>{try{if("file"===e.type){const n=safeJoin(t,e.name);await mkdir$1(dirname(n),{recursive:!0});const i=createWriteStream(n);await pipeline$1(r,i)}else r.resume();i()}catch(e){n(e instanceof Error?e:new Error(String(e)))}})().catch(e=>{n(e instanceof Error?e:new Error(String(e)))})}),i.on("error",n),i.on("finish",r);const s=createGunzip$1();s.on("error",n);Readable.from(e).pipe(s).pipe(i)})}function safeJoin(e,t){const r=normalize$3(join$1(e,t)),n=normalize$3(resolve$3(e))+sep$1
|
|
2343
|
+
;if(!r.startsWith(n))throw new Error(`Refusing to write outside destination: ${t}`);return r}async function readTesslJson(e){const t=await e.readText(TESSL_JSON_FILENAME);if(void 0===t)return{success:!1,error:"Tessl JSON not found"};const r=safeParseTesslJson(JSON.parse(t));return r.success?{success:!0,data:r.data}:{success:!1,error:r.error.message}}async function updateTesslJsonDependencies(e,{add:t,remove:r}){if(!t&&!r)return{success:!0};const n=await readTesslJson(e);if(!n.success)return{success:!1,error:n.error};const i=n.data,s=structuredClone(_nullishCoalesce$s(i.dependencies,()=>({})));for(const e of _nullishCoalesce$s(r,()=>[]))delete s[e];for(const{workspaceName:e,tileName:r,newVersion:n}of _nullishCoalesce$s(t,()=>[])){s[`${e}/${r}`]={version:n}}const o=Object.fromEntries(Object.entries(s).sort((e,t)=>e[0].localeCompare(t[0]))),a={...i,dependencies:o};try{const t=JSON.stringify(a,null,2)+EOL;await e.writeText(TESSL_JSON_FILENAME,t)}catch(e){return{success:!1,
|
|
2344
|
+
error:e instanceof Error?e.message:"Error updating Tessl JSON"}}return{success:!0}}async function ensureUsageSpecDirExists(e){const t=join$1(e,USAGE_SPEC_DIR_PATH);return await exists(t)||await mkdir$1(t,{recursive:!0}),t}async function downloadTile(e,t,{workspaceName:r,tileName:n,version:i}){const s=await ensureUsageSpecDirExists(e);return downloadAndWriteTile(t,join$1(s,r,n),r,n,i)}async function installTileFromSource(e,t,r,n,i){const[s,...o]=t.split(":"),a=o.join(":");return"file"!==s?{success:!1,error:`Unsupported source scheme: ${s}. Only 'file:' is currently supported.`}:a?installLocalTile(e,a,r,n,i):{success:!1,error:"Invalid source format: missing path after 'file:' scheme"}}async function installLocalTile(e,t,r,n,i){const s=resolve$3(e,t);if(!await exists(s))return{success:!1,error:`Local tile path not found: ${t}`};const o=join$1(s,SPEC_MANIFEST_NAME);if(!await exists(o))return{success:!1,error:`tile.json not found at path: ${t}`};const a=await readText(o);let c;try{
|
|
2345
|
+
c=JSON.parse(a)}catch(e){return{success:!1,error:`Invalid JSON in tile.json at ${t}: ${e instanceof Error?e.message:"Unknown error"}`}}const u=TileManifest.safeParse(c);if(!u.success)return{success:!1,error:`Invalid tile.json at ${t}: ${u.error.message}`};const l=u.data;if(l.version!==i)return{success:!1,error:`Version mismatch for ${r}/${n}: tessl.json specifies ${i} but tile.json has ${l.version}`};const d=`${r}/${n}`;if(l.name!==d)return{success:!1,error:`Tile name mismatch: expected ${d} but tile.json has ${l.name}`};const p=join$1(e,USAGE_SPEC_DIR_PATH),h=join$1(p,r,n);try{await copyDirectory(s,h)}catch(e){return{success:!1,error:`Failed to copy local tile: ${e instanceof Error?e.message:"Unknown error"}`}}return{success:!0,manifest:l}}async function syncUsageSpecs(e,t,r){const n=await readTesslJson(t);if(!n.success)return{success:!1,error:n.error};const i=n.data,s=await ensureUsageSpecDirExists(e),o=new Set,a=new Set,c=await t.glob(join$1(s,"**",SPEC_MANIFEST_NAME))
|
|
2346
|
+
;for(const e of c){const t=dirname(e);o.add(t);const r=dirname(t);a.add(r)}const u=new Set,l=new Set,d=await pMap(Object.entries(_nullishCoalesce$s(i.dependencies,()=>({}))),async([t,n])=>{const{version:i,source:o}=n,[a,c]=t.split("/");if(!a||!c)return{success:!1,error:`Invalid name: ${t}`};const d=join$1(s,a),p=join$1(d,c),h=o?await installTileFromSource(e,o,a,c,i):await downloadAndWriteTile(r,p,a,c,i);return h.success?(u.add(p),l.add(dirname(p)),{...h,tileFullName:t}):{...h,error:`${t}@${i}: ${h.error}`}},{concurrency:8});if(!d.every(e=>e.success)){const e=d.filter(e=>!e.success).map(e=>`- ${e.error}`);return{success:!1,error:`Failed to sync ${pluralize$1("tile",e.length)}:\n${e.join("\n")}`}}const p=d.map(e=>e.manifest);await createKnowledgeDoc(t,p),await createRulesDoc(e,t,p);const h=Array.from(o.difference(u));await batchDeletePaths(h);const A=Array.from(a.difference(l));return await batchDeletePaths(A),{success:!0}}async function batchDeletePaths(e){await pMap(e,async e=>{try{
|
|
2347
|
+
await rm$1(e,{recursive:!0})}catch(e){}},{concurrency:8})}const KNOWLEDGE_MD_FILENAME="KNOWLEDGE.md";async function createKnowledgeDoc(e,t){const r=t.filter(e=>e.describes&&e.docs).map(e=>{const t=packageurlJsExports.PackageURL.fromString(e.describes),[r,n]=e.name.split("/");return{name:t.namespace?`${t.namespace}/${t.name}@${t.version}`:`${t.name}@${t.version}`,summary:e.summary,path:join$1(USAGE_SPEC_DIR_PATH,r,n,e.docs)}}),n=t.filter(e=>!e.describes&&e.docs).map(e=>{const[t,r]=e.name.split("/");return{name:e.name,summary:e.summary,path:join$1(USAGE_SPEC_DIR_PATH,t,r,e.docs)}}),i=[DEFAULT_KNOWLEDGE_MD_CONTENT.trim()];r.length>0&&(i.push("## Dependencies"),i.push("Consult the relevant documentation when using any of the dependencies listed below:"),r.forEach(({name:e,summary:t,path:r})=>{i.push(`### ${e}`),i.push(t),i.push(`[docs](${r})`)})),n.length>0&&(i.push("## Documentation"),n.forEach(({name:e,summary:t,path:r})=>{i.push(`### ${e}`),i.push(t),i.push(`[docs](${r})`)})),
|
|
2348
|
+
await e.writeText(KNOWLEDGE_MD_FILENAME,i.join("\n\n"))}async function createRulesDoc(e,t,r){const n=findTilesWithSteering(r);if(0===n.length)return;const i=generateRulesMd(n);await t.writeText(RULES_MD_FILENAME,i),await maybeGenerateCursorRules(e,n)}async function readTileManifest(e,t){const r=join$1(t,SPEC_MANIFEST_NAME),n=await e.readText(r);if(n)try{const e=JSON.parse(n),t=TileManifest.safeParse(e);return t.success?t.data:void 0}catch(e){return}}async function loadKnowledgeIndexWithDetails(e,t){const r=await readTesslJson(e);if(!r.success)return[];if(!r.data.dependencies)return[];const n=[];for(const[i]of Object.entries(r.data.dependencies)){const[r,s]=i.split("/");if(!r||!s)continue;const o=join$1(t,USAGE_SPEC_DIR_PATH,r,s),a=await readTileManifest(e,o);if(a&&a.docs){let e=a.name;if(a.describes){e=purlToPackageDisplayName(packageurlJsExports.PackageURL.fromString(a.describes))}const t={packageName:e,version:a.version,description:a.summary||"",mainDocPath:join$1(o,a.docs)}
|
|
2349
|
+
;n.push(t)}}return n}const paramsSchema$3=z.object({name:z.string().describe('The full name of the tile e.g. "tessl/svelte@5.38.0". The version is optional; if omitted, the latest version will be used')}),installTool={name:"install",type:"fsd",impl:installToolImpl,paramsSchema:paramsSchema$3,description:'Install docs (usage specs) for your project by providing the full name of the spec e.g. "tessl/svelte@5.38.0". If a version is not provided, the latest version will be used. This can help provide context for your LLM tooling. You can find more with the search tool',visibility:"private"};async function installToolImpl({params:e,fsd:t,rc:{reporter:r,tesslClient:n,projectDir:i}}){const{name:s}=e;if(s){const e=s.split("@"),o=e[0];let a=e[1];if(!o)return r.failure('The name argument must be in the format "workspace/tile" (or "workspace/tile@version")');const[c,u]=o.split("/");if(!c||!u)return r.failure('The name argument must be in the format "workspace/tile" (or "workspace/tile@version")')
|
|
2350
|
+
;const l=await n.GET("/v1/tiles/{workspaceName}/{tileName}",{params:{path:{workspaceName:c,tileName:u}}});if(l.error)return r.failure(apiErrToString(l.error));const d=l.data.data;if(!a){const e=d.attributes.latestVersion;if(!e)return r.failure("The tile does not have a latest version. Please specify a version");a=e}const p=await n.GET("/v1/tiles/{workspaceName}/{tileName}/versions/{version}",{params:{path:{workspaceName:c,tileName:u,version:a}}});if(p.error)return r.failure(apiErrToString(p.error));const h=p.data.data;if(!h.attributes.describes)return r.failure("Invalid usage spec; does not describe a package");const A=await downloadTile(i,n,{workspaceName:c,tileName:u,version:a});if(!A.success)return r.failure(A.error);const f=await updateTesslJsonDependencies(t,{add:[{workspaceName:c,tileName:u,newVersion:h.attributes.version}]});if(!f.success)return r.failure(f.error)}const o=await syncUsageSpecs(i,t,n);return o.success?r.success():(r.summary(["Failed to sync all dependencies"]),
|
|
2351
|
+
r.failure(o.error))}const paramsSchema$2=z.object({goal:z.string().min(1,"Goal must not be empty").describe('A description of what you want to accomplish (e.g., "I need to parse and validate user input", "I want to build a REST API")').transform(stripSurroundingQuotes)}),recommendSpecsTool={name:"recommend-specs",type:"fsd",impl:recommendSpecsToolImpl,paramsSchema:paramsSchema$2,description:"Get recommendations for relevant usage specs from your local KNOWLEDGE.md based on a goal. Only recommends specs that are already installed in your project.",visibility:"private"};async function recommendSpecsToolImpl({params:e,fsd:t,rc:r}){const{goal:n}=e,{reporter:i,logger:s,projectDir:o}=r,a=await loadKnowledgeIndexWithDetails(t,o);if(0===a.length)return i.failure('No usage specs found. Run "tessl registry sync" to install specs.');s.info({goal:n,specsCount:a.length},"Finding relevant specs");try{const e=await findRelevantSpecs(r,n,a)
|
|
2352
|
+
;if(0===e.length)return i.success(["No highly relevant specs found for your goal"]),i.summary(["","You can search for new specs to install using: tessl registry search"]),SUCCESS;i.success([`${e.length} relevant ${pluralize$1("spec",e.length)} found`]);const t=formatRecommendations(e);return i.summary(t),SUCCESS}catch(e){return s.error({err:e,goal:n},"Failed to get spec recommendations"),i.failure(`Failed to analyze specs: ${e instanceof Error?e.message:String(e)}`)}}async function findRelevantSpecs(e,t,r){
|
|
2351
2353
|
const n=`Goal: ${t}\n\nAvailable packages:\n\n${r.map(e=>`Package: ${e.packageName}\nDescription: ${e.description||"No description available"}`).join("\n\n")}\n\nAnalyze which packages would be most helpful for this goal and provide recommendations.`,i=createHighLevelClient(e,"You are a helpful assistant that recommends relevant software libraries and dependencies based on user goals.\n\nYou will be given:\n1. A user's goal describing what they want to accomplish\n2. A list of available packages with their descriptions\n\nYour task is to identify which packages would be most relevant and helpful for achieving the user's goal.\n\nRespond with a JSON object containing an array of recommendations. Each recommendation should have:\n- packageName: the name of the package\n- reasoning: a brief explanation (1-2 sentences) of why this package is relevant\n- relevance: a score from 1-10 indicating how relevant this package is (10 = highly relevant, 1 = barely relevant)\n\nOnly include packages with a relevance score of 4 or higher.\nIf no packages are particularly relevant (all would score below 4), return an empty array.",{
|
|
2352
2354
|
modelName:e.reqLevelParams.modelName||"auto"}),s=z.object({recommendations:z.array(z.object({packageName:z.string(),reasoning:z.string(),relevance:z.number().min(1).max(10)}))}),o=await i.user(n).object({schema:s,name:"recommendations"});e.logger.info({llmRecommendations:o.recommendations},"[findRelevantSpecs] LLM recommendations"),e.logger.info({availablePackageNames:r.map(e=>e.packageName)},"[findRelevantSpecs] Available package names");const a=o.recommendations.map(e=>{const t=r.find(t=>t.packageName===e.packageName);return t?{spec:t,reasoning:e.reasoning,relevance:e.relevance}:null}).filter(e=>null!==e);return a.sort((e,t)=>t.relevance-e.relevance),a}function formatRecommendations(e){return e.map(e=>{const{spec:t,reasoning:r,relevance:n}=e,i="â
".repeat(Math.round(n/2));return[`${t.packageName}@${t.version} ${i}`,` ${r}`,` [docs](./${t.mainDocPath})`,""].join("\n")})}const paramsSchema$1=z.object({
|
|
2353
2355
|
query:z.string().describe("A name, package-url, or package registry web url").transform(stripSurroundingQuotes)}),searchTool={name:"search",type:"fsd",impl:searchToolImpl,paramsSchema:paramsSchema$1,description:"Search for docs (usage specs) by package name",visibility:"private"};async function searchToolImpl({params:e,rc:{reporter:t,logger:r,tesslClient:n}}){const{query:i}=e,s=validateBaseEnv(process.env),o=[];if(maybeName(i)){const[e,s]=await Promise.all([n.GET("/v1/tiles",{params:{query:{sort:["-similarity","-id"],"filter[fullName][like]":i,include:"versions"}}}),n.GET("/v1/tiles",{params:{query:{"filter[describes]":i,include:"versions"}}})]);if(e.error)return r.error({err:e.error},"Failed to search the knowledge base"),t.failure(apiErrToString(e.error));if(s.error)return r.error({err:s.error},"Failed to search the knowledge base"),t.failure(apiErrToString(s.error));const a=new Map;for(const t of e.data.data)a.set(t.id,t);for(const e of s.data.data)a.set(e.id,e)
|
|
@@ -2456,10 +2458,10 @@ refreshToken:r.refresh_token};if(!("error"in r))return{error:"Authorization fail
|
|
|
2456
2458
|
"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",client_id:e,refresh_token:t,user_agent:"tessl.cli"})}),n=await r.json();if(r.ok){const e=n;return{user:{id:e.user.id,email:e.user.email,firstName:e.user.first_name,lastName:e.user.last_name},accessToken:e.access_token,refreshToken:e.refresh_token}}return{error:getErrorFromResponseBody(n)||"Failed to authenticate with refresh token"}}function getAuthClientId(){const e="client_01HXSHDD9KV92A4892CWHZZDDR";if(!e.startsWith("client_"))throw new Error("Auth client id not set to appropriate value - please check `WORKOS_CLIENT_ID` env var");return e}function getErrorFromResponseBody(e){if("object"==typeof e&&e){if("error_description"in e&&"string"==typeof e.error_description)return e.error_description;if("error"in e&&"string"==typeof e.error)return e.error}}async function validateAccessTokenWithJWKS(e,t){const r=createRemoteJWKSet(new URL(`https://api.workos.com/sso/jwks/${t}`)),{payload:n}=await jwtVerify(e,r,{
|
|
2457
2459
|
issuer:"https://api.workos.com"});return n}function _optionalChain$w(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}async function createDotenvFile(e,t,r,n){e.debug({},"provisioning dotenv file");const i=getTesslClient(t,n),s=await i.GET("/experimental/cli-env");if("error"in s)throw e.error({err:s.error},"Failed to fetch dotenv data"),new Error("Failed to setup environment file: please try again");const o=_optionalChain$w([s,"access",e=>e.data,"optionalAccess",e=>e.data,"optionalAccess",e=>e.attributes,"optionalAccess",e=>e.envVars]);if(!o||"object"!=typeof o)throw e.warn({},"No environment variables received from API"),new Error("Failed to setup environment file: please try again");const a=`# Generated on ${(new Date).toISOString()} from ${t.TESSL_BASE_API_URL}`;let c=o
|
|
2458
2460
|
;"development"===t.NODE_ENV&&(c=Object.fromEntries(Object.entries(c).filter(([e])=>"LANGFUSE_PROXY_TOKEN"!==e)));const u=Object.entries(c).map(([e,t])=>`${e}="${t}"`).join("\n"),l=u?`${a}\n${u}`:a,d=join(r,"dotenv");await mkdir(dirname$1(d),{recursive:!0}),await writeFile(d,l,"utf-8"),await chmod(d,384),e.debug({path:d},"Created dotenv file")}const DEFAULT_TESSL_PATHS={globalConfigDir:getDefaultGlobalConfigDir(),projDir:process.cwd()},CredsSchema=Type.Object({accessToken:Type.String(),refreshToken:Type.String(),user:Type.Object({id:Type.String(),email:Type.String(),firstName:Type.Optional(Type.String()),lastName:Type.Optional(Type.String()),username:Type.Optional(Type.String())})}),AUTH_FILENAME="api-credentials.json",AUTH_PERMISSIONS=384;class RefreshTokenError extends ExpectedError{}const readAuth=async(e=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const t=resolve$3(e,AUTH_FILENAME),r=await readFile$2(t),n=JSON.parse(r.toString());return strictCheck(CredsSchema,n),n
|
|
2459
|
-
},writeAuth=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const n=resolve$3(r,AUTH_FILENAME);return t.debug({path:n},"writing auth"),await writeText(n,JSON.stringify(e),AUTH_PERMISSIONS),e},updateAuth=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const n=resolve$3(r,AUTH_FILENAME),i={...await readAuth(r),...e};return t.debug({path:n},"updating auth"),await writeText(n,JSON.stringify(i),AUTH_PERMISSIONS),i},getCreds=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{if(process.env.TESSL_SIMULATE_LOGOUT)return null;if(process.env.TESSL_TOKEN)return{accessToken:process.env.TESSL_TOKEN,refreshToken:"",user:{id:"token-user",email:"token@example.com"}};try{
|
|
2460
|
-
},isAuthed=async(e,t,r)=>null!==await getCreds(e,t,r),clearAuth=async(e,t=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const r=resolve$3(t,AUTH_FILENAME);e.debug({path:r},"clearing auth"),existsSync$1(r)?await unlink(r):e.debug({path:r},"auth file does not exist, nothing to clear")};async function refreshSessionIfNeeded(e,t,r,n=DEFAULT_TESSL_PATHS.globalConfigDir){const{accessToken:i,refreshToken:s}=r,o=t.WORKOS_CLIENT_ID;if(!o)throw new Error("no auth client id configured");try{e.debug({},"Validating access token with JWKS");const t=(await validateAccessTokenWithJWKS(i,o)).exp;if(t){if(!(Math.floor(Date.now()/1e3)>=t-5))return e.debug({},"Access token valid, not expired"),r;e.debug({},"Access token expired, will refresh")}else e.debug({},"No expiry claim in token payload, will refresh")}catch(t){e.debug({err:t},"JWKS validation failed, will refresh token")}const a=await authenticateWithRefreshToken(o,s)
|
|
2461
|
-
new RefreshTokenError(a.error);const{accessToken:c,refreshToken:u}=a,l=await updateAuth({accessToken:c,refreshToken:u},e,n);return await createDotenvFile(e,t,n||DEFAULT_TESSL_PATHS.globalConfigDir,c),e.debug({},"Token refreshed successfully"),l}function _nullishCoalesce$r(e,t){return null!=e?e:t()}function _optionalChain$v(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}const SPINNER_OPTIONS={hideCursor:!1,discardStdin:!1},loginCommand=new Command$1({name:"login",summary:"Login to Tessl; requires a Tessl account. See https://www.tessl.io/ to request access.",flags:{},requiresConfig:!1,handler:async({monitoring:{logger:e},env:t,tesslClient:r})=>{const n=arg(flagToSpec(GlobalFlags),{permissive:!0
|
|
2462
|
-
;if(await handleTokenLogin(e,t,n))return SUCCESS;return await login({logger:e,env:t,globalConfigDir:n,tesslClient:r})}});async function login({logger:e,env:t,globalConfigDir:r=DEFAULT_TESSL_PATHS.globalConfigDir,tesslClient:n}){const i=ora({text:"Initializing login flow",...SPINNER_OPTIONS}).start(),s=getAuthClientId();let o;try{o=await initialiseDeviceAuthFlow(s)}catch(t){return e.error({err:t},"Failed to initialize device auth flow"),i.fail("Failed to initialize device auth flow"),FAILURE}i.stop();let a=!1;try{await open(o.verificationUriComplete),a=!0}catch(e){}const c=stripIndent`
|
|
2461
|
+
},writeAuth=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const n=resolve$3(r,AUTH_FILENAME);return t.debug({path:n},"writing auth"),await writeText(n,JSON.stringify(e),AUTH_PERMISSIONS),e},updateAuth=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const n=resolve$3(r,AUTH_FILENAME),i={...await readAuth(r),...e};return t.debug({path:n},"updating auth"),await writeText(n,JSON.stringify(i),AUTH_PERMISSIONS),i},getCreds=async(e,t,r=DEFAULT_TESSL_PATHS.globalConfigDir)=>{if(process.env.TESSL_SIMULATE_LOGOUT)return null;if(process.env.TESSL_TOKEN)return{accessToken:process.env.TESSL_TOKEN,refreshToken:"",user:{id:"token-user",email:"token@example.com"}};let n;try{n=await readAuth(r)}catch(e){return null}try{return await refreshSessionIfNeeded(e,t,n,r)}catch(t){if(e.error({err:t},"error refreshing credentials"),t instanceof RefreshTokenError)try{await clearAuth(e,r)}catch(t){e.debug({err:t},"failed to clear auth file")}
|
|
2462
|
+
throw new Error("Could not refresh credentials. Check your connection and try again.")}},isAuthed=async(e,t,r)=>null!==await getCreds(e,t,r),clearAuth=async(e,t=DEFAULT_TESSL_PATHS.globalConfigDir)=>{const r=resolve$3(t,AUTH_FILENAME);e.debug({path:r},"clearing auth"),existsSync$1(r)?await unlink(r):e.debug({path:r},"auth file does not exist, nothing to clear")};async function refreshSessionIfNeeded(e,t,r,n=DEFAULT_TESSL_PATHS.globalConfigDir){const{accessToken:i,refreshToken:s}=r,o=t.WORKOS_CLIENT_ID;if(!o)throw new Error("no auth client id configured");try{e.debug({},"Validating access token with JWKS");const t=(await validateAccessTokenWithJWKS(i,o)).exp;if(t){if(!(Math.floor(Date.now()/1e3)>=t-5))return e.debug({},"Access token valid, not expired"),r;e.debug({},"Access token expired, will refresh")}else e.debug({},"No expiry claim in token payload, will refresh")}catch(t){e.debug({err:t},"JWKS validation failed, will refresh token")}const a=await authenticateWithRefreshToken(o,s)
|
|
2463
|
+
;if("error"in a)throw e.error({response:a},"error authenticating with refresh token"),new RefreshTokenError(a.error);const{accessToken:c,refreshToken:u}=a,l=await updateAuth({accessToken:c,refreshToken:u},e,n);return await createDotenvFile(e,t,n||DEFAULT_TESSL_PATHS.globalConfigDir,c),e.debug({},"Token refreshed successfully"),l}function _nullishCoalesce$r(e,t){return null!=e?e:t()}function _optionalChain$v(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}const SPINNER_OPTIONS={hideCursor:!1,discardStdin:!1},loginCommand=new Command$1({name:"login",summary:"Login to Tessl; requires a Tessl account. See https://www.tessl.io/ to request access.",flags:{},requiresConfig:!1,handler:async({monitoring:{logger:e},env:t,tesslClient:r})=>{const n=arg(flagToSpec(GlobalFlags),{permissive:!0
|
|
2464
|
+
})["--global-config-dir"]||DEFAULT_TESSL_PATHS.globalConfigDir;if(await handleTokenLogin(e,t,n))return SUCCESS;return await login({logger:e,env:t,globalConfigDir:n,tesslClient:r})}});async function login({logger:e,env:t,globalConfigDir:r=DEFAULT_TESSL_PATHS.globalConfigDir,tesslClient:n}){const i=ora({text:"Initializing login flow",...SPINNER_OPTIONS}).start(),s=getAuthClientId();let o;try{o=await initialiseDeviceAuthFlow(s)}catch(t){return e.error({err:t},"Failed to initialize device auth flow"),i.fail("Failed to initialize device auth flow"),FAILURE}i.stop();let a=!1;try{await open(o.verificationUriComplete),a=!0}catch(e){}const c=stripIndent`
|
|
2463
2465
|
If you have access to the full Tessl framework, you can log in at the following URL. (To request access, go to https://www.tessl.io/)
|
|
2464
2466
|
|
|
2465
2467
|
Please log in at the URL below (if your browser didn't open automatically):
|
|
@@ -2487,35 +2489,31 @@ f=t.length>0?chalk.inverse(t[0])+chalk.grey(t.slice(1)):chalk.inverse(" "),A=h.l
|
|
|
2487
2489
|
r.trim()?(submitFeedbackToPosthog(r.trim(),e),render(jsxRuntimeExports.jsx(Thanks,{})),t(SUCCESS)):(render(jsxRuntimeExports.jsx(Text,{color:"yellow",children:"Feedback submission cancelled - message was empty."})),t(FAILURE))}}))})}}),submitFeedbackToPosthog=(e,t)=>{t.posthogCapture({event:"survey sent",properties:{sessionId:t.analytics.getSessionId(),projectId:t.analytics.getProjectId(),$survey_id:"0197d0d3-6704-0000-e36e-569911acb8ee",$survey_questions:[{id:"e34e48fc-938a-4af1-b255-3c55d6bdcbc7",question:"Feedback message"}],"$survey_response_e34e48fc-938a-4af1-b255-3c55d6bdcbc7":e}},{bypassOptOut:!0})
|
|
2488
2490
|
},content$5="\n# Tessl\n\nTessl is a [spec driven development](./docs/spec-driven-development.md) framework and toolkit: @docs/spec-driven-development.md\n\n## Spec Driven Software Development Lifecycle\n\n### User Engagement\n\nUsers should be encouraged to engage directly with specs, so that they understand what is being asked for (or documented), and can steer the software development processes.\n\nIn order to do this, agents should:\n\n1. Interview the user to get details before creating or updating specs (but ask one or two questions at a time, so as not to overwhelm them).\n2. Ask for feedback on specs before building them. This should include pointing out key implementation choices, and highlighting any gaps in the spec.\n3. Include interview/feedback points as separate tasks in plans, so these steps are not skipped.\n\n### Primary Workflow: Spec to code\n\nSoftware is developed by creating or editing a spec and then `building` that spec to generate or update the implementation and then `fixing` to refine the spec and implementation until it works as intended.\n\n1. Create/edit the spec to reflect the desired functionality/changes requested, using the appropriate Tessl tool and providing it with relevant context (see the \"Using Tessl Tools\" instructions below)\n2. Install any new required dependencies from the spec\n3. Build the spec to generate the implementation code from the updated spec and fix\n4. When/if the user asks for tests, add them to the spec and generate them and fix.\n\n### Alternative Workflow: Code to spec\n\nSometimes the user may decide to change the code directly, or they may have legacy code they want to document. In such cases:\n\n1. Document the code changes into the spec + fix spec/tests to match observed code behaviors\n2. If the spec is changed, flag any capabilities that are lost or changed.\n\n### Using Tessl Tools\n\nTessl tools allow targeted changes to spec, code and test files ensuring that the methodology is followed, and that the correct context is provided at each step.\n\nBefore using any Tessl tool (`create`, `edit`, `build`, `document` etc) you must:\n\n1. **First: Check Knowledge Index:**\n\n - Read `./KNOWLEDGE.md` (the Knowledge Index)\n - Consider the Tessl tool call you're about to make, including any parameters\n - Decide if any entries in the Knowledge Index seem directly relevant to the current task\n - If so, spawn a research sub-agent to dig deeper into the chosen documents\n - If not, skip research and just call the tool\n\n2. **Research context** - Spawn a research sub-agent with details about:\n\n - The Knowledge Index candidates to explore\n - The specific Tessl tool you're about to call\n - The inputs to that tool call (what you're building, which files, etc.)\n\n3. **Research sub-agent identifies relevant context file paths:**\n\n - Explore the provided Knowledge Index entries\n - **Return**: Only relevant file paths (relative to the project root)\n\n4. **Then: Call the Tessl tool** - Use the file paths returned by the research sub-agent (relative to project root) in the `--context` parameter.\n\nRemember the research output and re-use it for similar tool calls (where the tool and inputs are the same).\n\nUse Tessl tools to:\n\n- Capture requirements for new code files in specs using the `create` tool\n- Edit specs / code / tests whenever the user wants to introduce or change behavior in existing specs / code / tests with the `edit` tool\n- Build code and tests from specs using the `build` and `build-tests` tools\n- Document code into specs using the `document` tool\n- Run tests using the `test` tool\n- Add extra functionality to code, by editing the spec and rebuilding\n- Check project and spec status using the `status` tool\n\nTessl also provides the capability to run its tools in parallel. Use this when you have multiple tasks to do that are independent of each other - e.g. rebuilding multiple specs at once.\n\n### Detailed Expectations Around Fixing Code and Tests:\n\nA key concept in spec-driven development is that built code and tests should be run to verify conformity to the spec. Often, however, working code and useful tests are not made on the first attempt. \n\nTessl tools will attempt to 'fix' before finishing build, but agents may need to continue or debug this process. \n\nBy default, the spec will have few if any test cases to start with, focus on getting the functionality working and then if the user asks for more tests, add them to the spec and generate them.\n\nTests should be prioritised in the following order:\n- Locked tests. Make sure the code is able to pass these tests, they are core functional requirements that have been confirmed by the user.\n- Draft tests. If draft tests have been generated, try to make the code pass. These tests have not been fully validated, so their definition or implementation may need to be refined until useful or removed altogether.\n\nFixes should be applied in this preference order:\n1. (Preferred fix): Install dependencies explicitly listed in the spec if needed.\n2. (Preferred fix): Iteratively run tests and update code to address errors, until the code passes the tests.\n3. (Cautious fix): Iteratively fix implementation errors in tests (e.g. syntax errors) and check they are still faithful to the spec.\n4. (Last resort): Identify if the spec contains errors, ambiguities or hard to implement definitions. Ask the user for how to proceed.\n\n**Never** simply remove requirements from the spec.\n**Never** add new capabilities to the code without updating the spec to capture how it will be verified.\n\n**Setup/Configuration errors**\nIt's possible the error stems from the overall project set up, in this case:\n\n- Ask the user to add dependencies to the spec if they are implied or necessary for the capabilities required.\n- Help the user configure their project further and make sure that their development environment is working.\n- Make sure that project details like the language(s), test runner(s) and ecosystem(s), and any testing or implementation guidelines are added to AGENTS.md to help guide the Tessl tools to produce consistent implementations that adhere to them.\n\n### Software Decomposition\n\nSpecs should map 1:1 with code files, with the structure of the specs and the links between them matching the intended decomposition of the software.\n\nIf the user asks for new functionality that would be challenging to fit into a single spec and code file, then you should first suggest decomposition approaches with them, and then make a plan to iteratively build up the software spec by spec.\n\nMake sure that specs link to each other as needed, and that there is a clear entry-point.\n\n**Pointers:**\n\n- Prefer to work in an incremental way, building up the software one piece at a time, improving the software with each iteration. Suggest a simple starting point, and include tasks in your plan to add additional features one by one later.\n- Check generated specs to make sure that they link to one another via \"dependencies\" links, and if not, call edit spec and ask for the dependency to be added.\n- Add more details on project expectations to AGENTS.md if you need more consistency in the project across specs - for example, on choices on key external dependencies, or testing guidelines.\n- Make sure the user provides explicit feedback and approval before deciding on a decomposition and beginning to create multiple specs and building them all.\n\n## The Knowledge Index\n\nThe Knowledge Index is a centralized reference for documentation about dependencies and processes used in the project.\n\nIt's stored in `./KNOWLEDGE.md` and contains links to versioned documentation files.\n\nThe Knowledge Index helps ensure consistency when selecting dependency versions and provides quick access to relevant documentation during development.\n\n## Important\n\nAlways modify code, tests or specs using Tessl tools. The only exceptions are when the user approves this behavior interactively. In either case **specs and generated code and tests must be always in sync**\n",content$4="\n# Spec Driven Development (SDD)\n\nSpec driven development places specs at the center of the software development lifecycle. Specs are considered the canonical source of truth when they are verifiable. Code is considered disposable when it can be reliably regenerated from a spec.\n\nSpecs capture _intent_, and may contain or link to files containing the API and test cases. Over time specs are updated to add new features or requirements, and code is regenerated to align with the specs.\n\nEach spec usually maps 1:1 to a code file. Larger units are composed of multiple linked specs (via dependencies), mirroring decomposition. A linked set of specs with their code and tests is a **tile** or **Tessl tile**. Projects may contain multiple tiles.\n\n## Specs\n\n- Follow the [Spec Format](./spec-format.md)\n- Used to capture all user intent\n- MUST NOT be modified without explicit user instruction or review\n- Together reflect the expected software decomposition with local spec dependencies mirroring targeted local code files, and with links to external dependencies\n\n## Code\n\n- Follow language and ecosystem requirements specified in AGENTS.md, and APIs and requirements in spec\n- Can be edited or rebuilt by tools or agents\n- Makes good use of dependencies explicitly linked in spec - following dependency APIs if provided and without reimplementing functionality\n- Doesn't use dependencies not explicitly listed in the spec\n\n## Tests\n\n- Follow the test runner requirements specified in AGENTS.md\n- Can be edited or rebuilt by tools or agents\n- Each test implements exactly one test definition from the spec, and only verifies that exact case\n- Assumes code complies exactly with the defined APIs\n- Can be tagged to indicate prioritization: draft (default), locked\n",content$3='\n# Spec Format\n\nSpecs are markdown files with some annotations for parsing. Typically one spec is written for each module.\n\nThey can contain the following sections, empty sections can be omitted:\n\n- Name.\n - Short overview to explain overall purpose.\n- Target.\n - Relative link to the code file this spec targets.\n- Capabilities.\n - Headings for each capability with an optional description.\n - List of test definitions for each capability, with relative links to the test files where they will be implemented.\n- API.\n - Description of the module\'s API that code and tests will be written to conform to.\n- Dependencies.\n - List of dependencies the spec has on other modules and external libraries.\n\nA further explanation of each is provided below.\n\n## Target\n\nShould contain a relative link to the code file that will contain the code this spec targets. This can be one of two flavors:\n\n- [@generate](./relative/path/to/code/file) or\n- [@describe](./relative/path/to/code/file)\n\n@generate is used where the spec is the primary artifact and the linked code will be generated (and regenerated) from the spec. This is the default.\n@describe is used to provide a wrapper to an existing code file, where the code is the primary artifact. This is provided to allow the spec to act as a reference material. The spec will be updated to match code changes.\n\nA spec may contain multiple links if multiple code files are generated from or described by the spec, but it is best practice to have one spec for one code file.\n\n## Capabilities\n\nList of capabilities of the module.\n\nEach capability:\n\n- Should be precise and concise.\n- Should explicitly describe the _intent_ of the capability, rather than describing the approach.\n- Can optionally have a short description under the title to explain the capability in more detail.\n\nEach capability should be followed by a list of requirements.\n\nEach requirement:\n\n- Should be concise, precise and opinionated on specific behaviors.\n- Can cover internal logic or external behavior.\n- Requirements can be converted into test cases by adding a corresponding [@test](./relative/path/to/test/file) annotation. Test cases must have clearly defined inputs and outputs, as well as setup/mocking notes if needed.\n\nExample:\n\n```markdown\nReverses any string. Preserves capitalization and whitespaces during reversal.\n\n- "hello" becomes "olleh" [@test](./relative/path/to/test/file)\n- "Hello, world!" becomes "!dlrow ,olleH" [@test](./relative/path/to/test/file_impl) { .impl }\n```\n\n## API\n\n- Describe the external interface for the module, including function signatures and parameters with types.\n- Must be wrapped in code block with a language identifier, with an { .api } tag on the block.\n- Should be an appropriate format for the language, and should be consistent with any project configuration provided.\n\n## Dependencies\n\nList of dependencies on other specs, files or external libraries that the module is expected to have. No other dependencies should be assumed, unless explicitly specified in the project configuration or in a user goal. Links can either be to the spec for the module if available, or directly to the code itself if the spec is not available.\n\n- Each lists what is expected from the dependency and has a link to the dependency.\n- New dependencies should only be added when explicitly requested by the user.\n\n- The whole section can be skipped if there are no requirements.\n- Each requirement should have a @use link.\n- For local dependencies, the link will be a relative path, for example [@use](./relative/path/to/dependency-spec)\n- For external dependencies a package name will be used, for example [@use](package-name)\n- For code dependencies, the link will be a relative path, for example [@use](./relative/path/to/code-file).\n\nExample dependencies:\n\n```markdown\n# Dependencies\n\n## Code Dependency Example\n\nDescription of the requirements for the module.\n[@use](./relative/path/to/code-file)\n\n## Spec Dependency Example\n\nDescription of the requirements for the module.\n[@use](./relative/path/to/dependency-spec)\n\n## External Dependency Example\n\nDescription of the requirements for the module.\n[@use](package-name)\n```\n\n## Content tags\n\nSections of the spec can be annotated with tags to explain the prioritization and level of editing that is appropriate. They are most often used for annotating specific tests.\n\nRules for applying tags:\n- By default, do not add tags.\n- Tags applied to a section will apply to all tests in the section.\n- Tests must not have more than one kind. e.g: you should not have a test marked as `impl` and `locked`, or a section marked with both `impl` and a test marked with `locked`.\n- Tests files must not mix test kinds. e.g: you should not have untagged and `locked` tests in the same test file.\n- Locked content must never be edited unless instructed to do so by the user.\n- Content must never be tagged as locked unless explicitly requested by the user.\n\n### Untagged (default)\n\nUntagged content is the standard and is considered draft.\n\nUntagged test cases \n- **Purpose**: Regular test cases that can be modified during development as necessary.\n- **Annotation**: No special class required (default behavior)\n- **Priority**: Medium priority, they can be changed during the development flow as the spec is refined\n\nExample:\n```markdown\n- "hello" becomes "olleh" [@test](./relative/path/to/test/file)\n```\n\n\n### Locked { .locked }\n\nLocked tags capture core functional requirements that should remain stable over time. They represent critical test cases that define the essential behavior of the module that have been confirmed by the user.\n\n- **Purpose**: Capture core functional requirements that should remain stable over time\n- **Annotation**: `{ .locked }` class on individual tests or section headers\n- **Priority**: High priority, they are applied deliberately by the user after reviews have been completed.\n\nExamples:\n```markdown\n- "hello" becomes "olleh" [@test](./relative/path/to/test/file) { .locked }\n\n### Core functionality { .locked }\n- "test1" becomes "1tset" [@test](./relative/path/to/test/file1)\n- "test2" becomes "2tset" [@test](./relative/path/to/test/file2)\n```\n\n### Implementation { .impl }\n\nImplementation tags are used to mark incidental implementation by-products rather than user-specified capabilities. They have lower priority and can be changed more freely.\n\n- **Purpose**: Cover implementation details that were not explicitly specified by the user.\n- **Annotation**: `{ .impl }` class on individual tests or section headers\n- **Priority**: Lower priority, they should be more freely changed if user requirements change.\n\nExamples:\n```markdown\n- "Hello" becomes "olleH" [@test](./relative/path/to/test/file) { .impl }\n\n### Implementation details { .impl }\n- Edge case behavior [@test](./relative/path/to/test/file1)\n- Performance characteristics [@test](./relative/path/to/test/file2)\n```\n\n\n## Example spec (with placeholders for the api details)\n\n````markdown\n# String Reverser\n\nString reverser. Switches the order of characters in a string.\n\n## Target\n\n[@generate](./relative/path/to/code/file)\n\n## Capabilities\n\n### Reverses a string.\n\n- "hello" becomes "olleh" [@test](./relative/path/to/test/file1)\n- "iPhone 5 Samsung" becomes "gnusmaS 5 enohPi" [@test](./relative/path/to/test/file2)\n\n### Reverses within a delimiter.\n\nDelimiter is optional, but if provided, reversing only happens between each delimited block, with block order preserved.\n\n- ("hello friend", " ") becomes "olleh dneirf" [@test](./relative/path/to/test/file4)\n\n### Efficient implementation\n\n- Uses a single pass buffer approach.\n- Doesn\'t modify the original string.\n\n\n## API\n\n```{{LANGUAGE}} { .api }\n\n{{API_CODE}}\n\n```\n\n````\n\n\n',content$2='# Plan Files\n\n**CRITICAL: Create a plan file EVERY TIME you make a plan:**\n\n1. Create a new plan file in the `plans/` directory at the root of the project.\n2. Plan filename format: `YYYY-MM-DD_HH-mm-ss_descriptive-name.plan.md`\n - Example: `2025-08-25_14-37-12_user-authentication.plan.md`\n3. Keep the plan file in sync with your own native task tracking tool.\n4. Update the plan file IMMEDIATELY after completing EACH task. Do NOT batch updates.\n\n## Plan File Structure\n\n### Format\nA plan file is a markdown document (`.plan.md`) that records tasks to achieve a goal, and acts as an audit trail of the plan.\n\n### Components\n1. **Header**: Overall goal and any relevant background context\n2. **Task List**: Markdown checkboxes for each task\n - `- [ ]` for pending tasks\n - `- [x]` for completed tasks\n3. **Task Outputs**: Document results as blockquotes after each task\n\n## Rules for Executing Plans with Plan Files\n\n### 1. Task Documentation\nAfter completing each task, document comprehensively:\n\n- **Update status**: Change checkbox from `[ ]` to `[x]`\n- **Add output**: Create detailed blockquote on new line after task\n- **Document tool calls**: For EVERY tool call (MCP, Bash, Edit, etc.), include:\n - Tool name\n - COMPLETE, VERBATIM parameters (do not summarize), EXCEPTION: do summarize parameters containing file contents\n - Use markdown code blocks for multi-line string parameters (e.g. prompts)\n - Summary of tool output\n- **Include every step in the task**: Document every tool call needed to complete the task\n- **Use separators**: Add `---` and a newline between multiple tool calls in same task\n- **Include full journey**: Document the complete process, including diagnostics and debugging:\n - ALL problems encountered with specific details\n - Each fix attempt and rationale\n - Every diagnostic tool used (exact tool name, summary of parameters and output)\n - Summary of outcome, including initial state (e.g., "7 tests failed out of 12") and final state (e.g., "All 11 tests passing")\n- **Always link to project files**: Include markdown links to any created/read/update/deleted project files:\n - link text: file path relative to the project root\n - link href: file path relative to the plan file\n\n### 2. Plan Updates\n- Modify the plan and plan file as needed when requirements change\n- Add new tasks or remove irrelevant ones\n- Document reasons for significant changes\n\n## Best Practices\nTasks should be:\n- **Specific**: Clear, actionable completion criteria\n- **Atomic**: One logical unit of work per task\n- **Logically Ordered**: Arrange in execution sequence\n- **Well Sized**: Break down complex goals into incremental atomic tasks\n\n## Example\n\n````markdown\n# Plan: Implement User Authentication\n\nAdd secure user authentication with email/password login.\n\n## Tasks\n\n- [x] Create user model spec with email, password hash, and timestamps\n > **MCP** `tessl - create`\n > - spec: specs/models/user.spec.md\n > - prompt:\n > ```\n > Create a User model with the following fields:\n > - id: string (UUID)\n > - email: string (unique, required)\n > - passwordHash: string (required)\n > - createdAt: Date\n > - updatedAt: Date\n >\n > Include methods for:\n > - Password hashing and verification using bcrypt\n > - Email validation\n > - Safe JSON serialization (excludes passwordHash)\n > ```\n >\n > Created [specs/models/user.spec.md](../specs/models/user.spec.md)\n > Model spec created successfully with all required fields and methods.\n\n- [x] Build user model from spec\n > **MCP** `tessl - build`\n > - spec: ["specs/models/user.spec.md"]\n >\n > Generated:\n > - [src/models/user.ts](../src/models/user.ts)\n >\n > Build completed successfully, no errors.\n > ---\n >\n > **Bash** `npm run build`\n > Build failed with TypeScript errors: missing import extensions\n > ---\n >\n > **Edit** `src/models/user.ts`\n > - old_string: import { SomeType } from \'./types\'\n > - new_string: import { SomeType } from \'./types.js\'\n >\n > Updated [src/models/user.ts](../src/models/user.ts).\n > Fixed import to include .js extension for ESM compatibility.\n > ---\n >\n > **MCP** `tessl - document`\n > - spec: specs/models/user.spec.md\n > - includeImplDetails: true\n >\n > Synced [code](../src/models/user.ts) behavior to [spec](../specs/models/user.spec.md)\n\n- [ ] Add database migration for users table\n- [ ] Create authentication service spec\n- [ ] Implement login endpoint\n- [ ] Add session management\n- [ ] Test authentication flow end-to-end\n- [ ] Ask user to manually review and confirm authentication flow is working as expected\n````\n',content$1="\n# Tessl\n\nTessl is a spec driven development framework and toolkit.\n\nAlways use [Spec Driven Development](./docs/spec-driven-development.md) when executing tasks.\n",content="\n# Using the Knowledge Index\n\nRequired dependencies for this projects are documented in the Knowledge Index: `./KNOWLEDGE.md`\n\nBefore starting any work, review the contents of `./KNOWLEDGE.md` to discover the expectations on what dependencies (and which versions) and processes you must follow.\n\nBecause the index can link to a large amount of content, use this workflow to read relevant content:\n\n1. Review `./KNOWLEDGE.md` and check if there any relevant files.\n2. If so, spawn a research subagent with information about your task and a pointer to the files, and ask it to return a relevant summary of context for you to use (but not to do the task). This will prevent you from getting overwhelmed by too much information.\n3. Use the information in your task!\n\nClarify by interviewing the user if the content is not what you expect:\n\n- There's documentation for a dependency you could use, but it isn't the obvious choice. Check if you are expected to use it for the task you are doing.\n- If you are not sure whether to use the version of the dependency from the docs, for example, if you discover that there's a more up to date version of the package.\n- If there's documentation that appears to be missing that would help.\n\nREPEAT this workflow for every new task. The Knowledge Index is updated frequently, so make sure to review it for changes.\n\n# Using the Tessl Spec Registry\n\nDocumentation can be added to the Knowledge Index using the Tessl `registry` tools:\n\n- Search Tessl's Spec Registry for dependency documentation using `search`\n- Install relevant docs into the Knowledge Index using `install`\n\nConsult the Spec Registry when deciding which dependencies to install into a project. Likewise, install the documentation for a given dependency after installing it.\n",FRAMEWORK_FILES={
|
|
2489
2491
|
"agents.md":content$5,"bootstrap.md":content$6,"plan-files.md":content$2,"tessl-system-prompt.md":content$1,"docs/spec-driven-development.md":content$4,"docs/spec-format.md":content$3},KNOWLEDGE_ONLY_FILES={"usage-specs.md":content};function installFullFrameworkFiles(e){return installFrameworkFiles(e,FRAMEWORK_FILES)}function installKnowledgeFrameworkFiles(e){return installFrameworkFiles(e,KNOWLEDGE_ONLY_FILES)}function installFrameworkFiles(e,t){const r=path__default.resolve(e,DEFAULT_TESSL_DIRS.frameworkDirectory);fs$8.existsSync(r)&&fs$8.rmSync(r,{recursive:!0});const n=[];for(const[i,s]of Object.entries(t)){const t=path__default.join(r,i);fs$8.existsSync(path__default.dirname(t))||fs$8.mkdirSync(path__default.dirname(t),{recursive:!0}),fs$8.writeFileSync(t,s.trim());const o=path__default.relative(e,t);n.push(o)}return n}function setupFramework(e,t){const r=[];if("full"===e){removeHooks(t,KNOWLEDGE_ONLY_HOOKS);const e=installFullFrameworkFiles(t);r.push(...e)
|
|
2490
|
-
;const n=addAgentsMdHooks(t,ALL_TESSL_FRAMEWORK_HOOKS);r.push(...n)}else{removeHooks(t,ALL_TESSL_FRAMEWORK_HOOKS);const e=installKnowledgeFrameworkFiles(t);r.push(...e);const n=addAgentsMdHooks(t,KNOWLEDGE_ONLY_HOOKS);r.push(...n)}return r}function getExistingFrameworkType(e){return hasHooks(e,REQUIRED_TESSL_FRAMEWORK_HOOKS)?"full":hasHooks(e,KNOWLEDGE_ONLY_HOOKS)?"spec-registry":void 0}function
|
|
2491
|
-
if("object"!=typeof r.mcpServers||null===r.mcpServers)throw new Error(`Expected "mcpServers" to be an object in ${e}`);if("tessl"in r.mcpServers)return;const n={...r,mcpServers:{...r.mcpServers,...getMCPConfig(e.includes("cursor")).mcpServers}};return writeFileSync$1(e,JSON.stringify(n,null,2)+"\n"),relative$1(process.cwd(),e)}function addCursorMcpConfig(e=process.cwd()){return createOrAppendMcpConfig(join(e,".cursor","mcp.json"))}function addGeminiMcpConfig(e=process.cwd()){return createOrAppendMcpConfig(join(e,".gemini","settings.json"))}function addCodexMcpConfig(){const e=join(homedir$1(),".codex","config.toml");mkdirSync$1(dirname$1(e),{recursive:!0});const t=
|
|
2492
|
-
relative$1(process.cwd(),e)}if("object"!=typeof
|
|
2493
|
-
description:"Spec format"}},KNOWLEDGE_ONLY_RULES={"usage-specs.mdc":{content:KNOWLEDGE_ONLY_FILES["usage-specs.md"],description:"Working with external dependencies",alwaysApply:!0}};function installCursorFiles(e){const t=[],r=path__default.join(e,TESSL_RULES_DIR);if(fs$8.existsSync(r)&&fs$8.rmSync(r,{recursive:!0}),fs$8.mkdirSync(r,{recursive:!0}),"full"===getExistingFrameworkType(e))for(const[n,i]of Object.entries(FRAMEWORK_RULES)){const s=writeMdcContent(r,n,i);t.push(path__default.relative(e,s))}else for(const[n,i]of Object.entries(KNOWLEDGE_ONLY_RULES)){const s=writeMdcContent(r,n,i);t.push(path__default.relative(e,s))}return t}function writeMdcContent(e,t,r){const n=toMdcContent(r),i=path__default.join(e,t)
|
|
2494
|
-
return`---\n${[`description: ${e.description}`,"alwaysApply"in e?`alwaysApply: ${e.alwaysApply}`:"","globs"in e?`globs: ${e.globs}`:""].filter(Boolean).join("\n")}\n---\n${e.content.replaceAll(/((?:\[[^\]]*\]\([^)]*?)|@docs\/[^\s)]+)\.md\b/g,"$1.mdc")}`}const AGENT_INFO={amp:{label:"Amp",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},"claude-code":{label:"Claude Code",configFile:"CLAUDE.md",addMcpConfig:addClaudeMcpConfig,level:"core"},cline:{label:"Cline",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},codex:{label:"Codex",configFile:"AGENTS.md",addMcpConfig:addCodexMcpConfig,level:"alpha"},cursor:{label:"Cursor",configFile:"AGENTS.md",addMcpConfig:addCursorMcpConfig,installCustomFiles:installCursorFiles,level:"alpha"},"gemini-cli":{label:"Gemini CLI",configFile:"GEMINI.md",
|
|
2495
|
-
configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},opencode:{label:"opencode",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},windsurf:{label:"Windsurf",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},zed:{label:"Zed",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"}},RECOGNIZED_AGENTS=Object.keys(AGENT_INFO)
|
|
2496
|
-
|
|
2497
|
-
setCwd:(e=process.cwd())=>`${n}50;CurrentDir=${e}${i}`,annotation:(e,t={})=>{let r=`${n}1337;`;const s=void 0!==t.x,o=void 0!==t.y;if((s||o)&&(!s||!o||void 0===t.length))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return e=e.replace(/\|/g,""),r+=t.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",t.length>0?r+=(s?[e,t.length,t.x,t.y]:[t.length,e]).join("|"):r+=e,r+i}}}(ansiEscapes$3)),ansiEscapes$3.exports}var ansiEscapesExports$1=requireAnsiEscapes$1(),ansiEscapes$2=getDefaultExportFromCjs(ansiEscapesExports$1);const checkboxTheme={icon:{checked:colors.green(figures$1.circleFilled),unchecked:figures$1.circle,cursor:figures$1.pointer},style:{disabledChoice:e=>colors.dim(`- ${e}`),renderSelectedChoices:e=>e.map(e=>e.short).join(", "),description:e=>colors.cyan(e)},helpMode:"auto"};function isSelectable$1(e){return!Separator.isSeparator(e)&&!e.disabled}function isChecked(e){return isSelectable$1(e)&&Boolean(e.checked)}function toggle$1(e){
|
|
2498
|
-
return isSelectable$1(e)?{...e,checked:!e.checked}:e}function check(e){return function(t){return isSelectable$1(t)?{...t,checked:e}:t}}function normalizeChoices$1(e){return e.map(e=>{if(Separator.isSeparator(e))return e;if("string"==typeof e)return{value:e,name:e,short:e,disabled:!1,checked:!1};const t=e.name??String(e.value),r={value:e.value,name:t,short:e.short??t,disabled:e.disabled??!1,checked:e.checked??!1};return e.description&&(r.description=e.description),r})}var checkbox=createPrompt((e,t)=>{const{instructions:r,pageSize:n=7,loop:i=!0,required:s,validate:o=()=>!0}=e,a={all:"a",invert:"i",...e.shortcuts},c=makeTheme(checkboxTheme,e.theme),u=useRef(!0),[l,d]=useState("idle"),p=usePrefix({status:l,theme:c}),[h,A]=useState(normalizeChoices$1(e.choices)),f=useMemo(()=>{const e=h.findIndex(isSelectable$1),t=h.findLastIndex(isSelectable$1);if(-1===e)throw new ValidationError$1("[checkbox prompt] No selectable choices. All choices are disabled.");return{first:e,last:t}
|
|
2492
|
+
;const n=addAgentsMdHooks(t,ALL_TESSL_FRAMEWORK_HOOKS);r.push(...n)}else{removeHooks(t,ALL_TESSL_FRAMEWORK_HOOKS);const e=installKnowledgeFrameworkFiles(t);r.push(...e);const n=addAgentsMdHooks(t,KNOWLEDGE_ONLY_HOOKS);r.push(...n)}return r}function getExistingFrameworkType(e){return hasHooks(e,REQUIRED_TESSL_FRAMEWORK_HOOKS)?"full":hasHooks(e,KNOWLEDGE_ONLY_HOOKS)?"spec-registry":void 0}function isNpxInvocation(){return"exec"===process.env.npm_command&&"npx"===process.env.npm_lifecycle_event}function getMcpCommand(){return isNpxInvocation()?"npx":"tessl"}function getMcpArgs(e=!1){const t=[];return isNpxInvocation()&&t.push("@tessl/cli@latest"),t.push("mcp"),e&&t.push("--config-dir","."),t}function getMCPConfig(e){return{mcpServers:{tessl:{type:"stdio",command:getMcpCommand(),args:getMcpArgs(e)}}}}function createOrAppendMcpConfig(e){mkdirSync$1(dirname$1(e),{recursive:!0});if(!existsSync(e))return writeFileSync$1(e,JSON.stringify(getMCPConfig(e.includes("cursor")),null,2)),
|
|
2493
|
+
relative$1(process.cwd(),e);const t=readFileSync$1(e,"utf-8"),r=JSON.parse(t);if(!("mcpServers"in r)){const t={...r,...getMCPConfig(e.includes("cursor"))};return writeFileSync$1(e,JSON.stringify(t,null,2)+"\n"),relative$1(process.cwd(),e)}if("object"!=typeof r.mcpServers||null===r.mcpServers)throw new Error(`Expected "mcpServers" to be an object in ${e}`);if("tessl"in r.mcpServers)return;const n={...r,mcpServers:{...r.mcpServers,...getMCPConfig(e.includes("cursor")).mcpServers}};return writeFileSync$1(e,JSON.stringify(n,null,2)+"\n"),relative$1(process.cwd(),e)}function addCursorMcpConfig(e=process.cwd()){return createOrAppendMcpConfig(join(e,".cursor","mcp.json"))}function addGeminiMcpConfig(e=process.cwd()){return createOrAppendMcpConfig(join(e,".gemini","settings.json"))}function addCodexMcpConfig(){const e=join(homedir$1(),".codex","config.toml");mkdirSync$1(dirname$1(e),{recursive:!0});const t=existsSync(e),r={tessl:{command:getMcpCommand(),args:getMcpArgs()}};if(!t){const t={
|
|
2494
|
+
mcp_servers:r};return writeFileSync$1(e,tomlExports.stringify(t)),relative$1(process.cwd(),e)}const n=readFileSync$1(e,"utf-8"),i=tomlExports.parse(n);if(!("mcp_servers"in i)){const t={...i,mcp_servers:r};return writeFileSync$1(e,tomlExports.stringify(t)),relative$1(process.cwd(),e)}if("object"!=typeof i.mcp_servers||null===i.mcp_servers)throw new Error(`Expected "mcp_servers" to be an object in ${e}`);if("tessl"in i.mcp_servers)return;const s={...i,mcp_servers:{...i.mcp_servers,...r}};return writeFileSync$1(e,tomlExports.stringify(s)),relative$1(process.cwd(),e)}function addClaudeMcpConfig(e=process.cwd()){return createOrAppendMcpConfig(join(e,".mcp.json"))}const TESSL_RULES_DIR=".cursor/rules/tessl/framework",FRAMEWORK_RULES={"agents.mdc":{content:FRAMEWORK_FILES["agents.md"],description:"Tessl framework",alwaysApply:!0},"bootstrap.mdc":{content:FRAMEWORK_FILES["bootstrap.md"],description:"Configuring a project"},"plan-files.mdc":{content:FRAMEWORK_FILES["plan-files.md"],
|
|
2495
|
+
description:"Planning"},"docs/spec-driven-development.mdc":{content:FRAMEWORK_FILES["docs/spec-driven-development.md"],description:"Spec driven development",alwaysApply:!0},"docs/spec-format.mdc":{content:FRAMEWORK_FILES["docs/spec-format.md"],description:"Spec format"}},KNOWLEDGE_ONLY_RULES={"usage-specs.mdc":{content:KNOWLEDGE_ONLY_FILES["usage-specs.md"],description:"Working with external dependencies",alwaysApply:!0}};function installCursorFiles(e){const t=[],r=path__default.join(e,TESSL_RULES_DIR);if(fs$8.existsSync(r)&&fs$8.rmSync(r,{recursive:!0}),fs$8.mkdirSync(r,{recursive:!0}),"full"===getExistingFrameworkType(e))for(const[n,i]of Object.entries(FRAMEWORK_RULES)){const s=writeMdcContent(r,n,i);t.push(path__default.relative(e,s))}else for(const[n,i]of Object.entries(KNOWLEDGE_ONLY_RULES)){const s=writeMdcContent(r,n,i);t.push(path__default.relative(e,s))}return t}function writeMdcContent(e,t,r){const n=toMdcContent(r),i=path__default.join(e,t)
|
|
2496
|
+
;return fs$8.existsSync(path__default.dirname(i))||fs$8.mkdirSync(path__default.dirname(i),{recursive:!0}),fs$8.writeFileSync(i,n),i}function toMdcContent(e){return`---\n${[`description: ${e.description}`,"alwaysApply"in e?`alwaysApply: ${e.alwaysApply}`:"","globs"in e?`globs: ${e.globs}`:""].filter(Boolean).join("\n")}\n---\n${e.content.replaceAll(/((?:\[[^\]]*\]\([^)]*?)|@docs\/[^\s)]+)\.md\b/g,"$1.mdc")}`}const AGENT_INFO={amp:{label:"Amp",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},"claude-code":{label:"Claude Code",configFile:"CLAUDE.md",addMcpConfig:addClaudeMcpConfig,level:"core"},cline:{label:"Cline",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},codex:{label:"Codex",configFile:"AGENTS.md",addMcpConfig:addCodexMcpConfig,level:"alpha"},cursor:{label:"Cursor",configFile:"AGENTS.md",addMcpConfig:addCursorMcpConfig,installCustomFiles:installCursorFiles,level:"alpha"},"gemini-cli":{label:"Gemini CLI",configFile:"GEMINI.md",
|
|
2497
|
+
addMcpConfig:addGeminiMcpConfig,level:"alpha"},"github-copilot":{label:"GitHub Copilot",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},goose:{label:"Goose",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},opencode:{label:"opencode",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},windsurf:{label:"Windsurf",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"},zed:{label:"Zed",configFile:"AGENTS.md",addMcpConfig:void 0,level:"experimental"}},RECOGNIZED_AGENTS=Object.keys(AGENT_INFO),checkboxTheme={icon:{checked:colors.green(figures$1.circleFilled),unchecked:figures$1.circle,cursor:figures$1.pointer},style:{disabledChoice:e=>colors.dim(`- ${e}`),renderSelectedChoices:e=>e.map(e=>e.short).join(", "),description:e=>colors.cyan(e)},helpMode:"auto"};function isSelectable$1(e){return!Separator.isSeparator(e)&&!e.disabled}function isChecked(e){return isSelectable$1(e)&&e.checked}function toggle$1(e){return isSelectable$1(e)?{...e,
|
|
2498
|
+
checked:!e.checked}:e}function check(e){return function(t){return isSelectable$1(t)?{...t,checked:e}:t}}function normalizeChoices$1(e){return e.map(e=>{if(Separator.isSeparator(e))return e;if("string"==typeof e)return{value:e,name:e,short:e,disabled:!1,checked:!1};const t=e.name??String(e.value),r={value:e.value,name:t,short:e.short??t,disabled:e.disabled??!1,checked:e.checked??!1};return e.description&&(r.description=e.description),r})}var checkbox=createPrompt((e,t)=>{const{instructions:r,pageSize:n=7,loop:i=!0,required:s,validate:o=()=>!0}=e,a={all:"a",invert:"i",...e.shortcuts},c=makeTheme(checkboxTheme,e.theme),u=useRef(!0),[l,d]=useState("idle"),p=usePrefix({status:l,theme:c}),[h,A]=useState(normalizeChoices$1(e.choices)),f=useMemo(()=>{const e=h.findIndex(isSelectable$1),t=h.findLastIndex(isSelectable$1);if(-1===e)throw new ValidationError$1("[checkbox prompt] No selectable choices. All choices are disabled.");return{first:e,last:t}
|
|
2499
2499
|
},[h]),[g,m]=useState(f.first),[y,E]=useState(!0),[b,C]=useState();useKeypress(async e=>{if(isEnterKey(e)){const e=h.filter(isChecked),r=await o([...e]);s&&!h.some(isChecked)?C("At least one choice must be selected"):!0===r?(d("done"),t(e.map(e=>e.value))):C(r||"You must select a valid value")}else if(isUpKey(e)||isDownKey(e)){if(i||isUpKey(e)&&g!==f.first||isDownKey(e)&&g!==f.last){const t=isUpKey(e)?-1:1;let r=g;do{r=(r+t+h.length)%h.length}while(!isSelectable$1(h[r]));m(r)}}else if(isSpaceKey(e))C(void 0),E(!1),A(h.map((e,t)=>t===g?toggle$1(e):e));else if(e.name===a.all){const e=h.some(e=>isSelectable$1(e)&&!e.checked);A(h.map(check(e)))}else if(e.name===a.invert)A(h.map(toggle$1));else if(isNumberKey(e)){const t=Number(e.name)-1;let r=-1;const n=h.findIndex(e=>!Separator.isSeparator(e)&&(r++,r===t)),i=h[n];i&&isSelectable$1(i)&&(m(n),A(h.map((e,t)=>t===n?toggle$1(e):e)))}});const v=c.style.message(e.message,l);let I;const _=usePagination({items:h,active:g,
|
|
2500
2500
|
renderItem({item:e,isActive:t}){if(Separator.isSeparator(e))return` ${e.separator}`;if(e.disabled){const t="string"==typeof e.disabled?e.disabled:"(disabled)";return c.style.disabledChoice(`${e.name} ${t}`)}t&&(I=e.description);const r=e.checked?c.icon.checked:c.icon.unchecked;return(t?c.style.highlight:e=>e)(`${t?c.icon.cursor:" "}${r} ${e.name}`)},pageSize:n,loop:i});if("done"===l){const e=h.filter(isChecked);return`${p} ${v} ${c.style.answer(c.style.renderSelectedChoices(e,h))}`}let S="",D="";if("always"===c.helpMode||"auto"===c.helpMode&&y&&(void 0===r||r)){if("string"==typeof r)S=r;else{S=` (Press ${[`${c.style.key("space")} to select`,a.all?`${c.style.key(a.all)} to toggle all`:"",a.invert?`${c.style.key(a.invert)} to invert selection`:"",`and ${c.style.key("enter")} to proceed`].filter(e=>""!==e).join(", ")})`}h.length>n&&("always"===c.helpMode||"auto"===c.helpMode&&u.current)&&(D=`\n${c.style.help("(Use arrow keys to reveal more choices)")}`,u.current=!1)}
|
|
2501
|
-
const w=I?`\n${c.style.description(I)}`:"";let R="";return b&&(R=`\n${c.style.error(b)}`),`${p} ${v}${S}\n${_}${D}${w}${R}${
|
|
2502
|
-
const{required:r,validate:n=()=>!0,prefill:i="tab"}=e,s=makeTheme(inputTheme,e.theme),[o,a]=useState("idle"),[c="",u]=useState(e.default),[l,d]=useState(),[p,h]=useState(""),A=usePrefix({status:o,theme:s});useKeypress(async(e,i)=>{if("idle"===o)if(isEnterKey(e)){const e=p||c;a("loading");const o=r&&!e?"You must provide a value":await n(e);!0===o?(h(e),a("done"),t(e)):("clear"===s.validationFailureMode?h(""):i.write(p),d(o||"You must provide a valid value"),a("idle"))}else isBackspaceKey(e)&&!p?u(void 0):
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
;if(
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
e=e.replace(LEADING_SEPARATORS,""),e=t.preserveConsecutiveUppercase?preserveConsecutiveUppercase(e,r):r(e),t.pascalCase&&(e=n(e.charAt(0))+e.slice(1)),postProcess(e,n)}var stringWidth$1={exports:{}},ansiRegex$1,hasRequiredAnsiRegex$1,stripAnsi$1,hasRequiredStripAnsi$1;function requireAnsiRegex$1(){return hasRequiredAnsiRegex$1||(hasRequiredAnsiRegex$1=1,ansiRegex$1=({onlyFirst:e=!1}={})=>{const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}),ansiRegex$1}function requireStripAnsi$1(){if(hasRequiredStripAnsi$1)return stripAnsi$1;hasRequiredStripAnsi$1=1;const e=requireAnsiRegex$1();return stripAnsi$1=t=>"string"==typeof t?t.replace(e(),""):t,stripAnsi$1}var isFullwidthCodePoint$1={exports:{}
|
|
2518
|
-
},hasRequiredIsFullwidthCodePoint$1,emojiRegex$2,hasRequiredEmojiRegex$1,hasRequiredStringWidth$1,ansiAlign_1,hasRequiredAnsiAlign;function requireIsFullwidthCodePoint$1(){if(hasRequiredIsFullwidthCodePoint$1)return isFullwidthCodePoint$1.exports;hasRequiredIsFullwidthCodePoint$1=1;const e=e=>!Number.isNaN(e)&&(e>=4352&&(e<=4447||9001===e||9002===e||11904<=e&&e<=12871&&12351!==e||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141));return isFullwidthCodePoint$1.exports=e,isFullwidthCodePoint$1.exports.default=e,isFullwidthCodePoint$1.exports}function requireEmojiRegex$1(){return hasRequiredEmojiRegex$1?emojiRegex$2:(hasRequiredEmojiRegex$1=1,emojiRegex$2=function(){
|
|
2501
|
+
const w=I?`\n${c.style.description(I)}`:"";let R="";return b&&(R=`\n${c.style.error(b)}`),`${p} ${v}${S}\n${_}${D}${w}${R}${cursorHide}`});function getBooleanValue(e,t){let r=!1!==t;return/^(y|yes)/i.test(e)?r=!0:/^(n|no)/i.test(e)&&(r=!1),r}function boolToString(e){return e?"Yes":"No"}var confirm=createPrompt((e,t)=>{const{transformer:r=boolToString}=e,[n,i]=useState("idle"),[s,o]=useState(""),a=makeTheme(e.theme),c=usePrefix({status:n,theme:a});useKeypress((a,c)=>{if("idle"===n)if(isEnterKey(a)){const n=getBooleanValue(s,e.default);o(r(n)),i("done"),t(n)}else if(isTabKey(a)){const t=boolToString(!getBooleanValue(s,e.default));c.clearLine(0),c.write(t),o(t)}else o(c.line)});let u=s,l="";"done"===n?u=a.style.answer(s):l=` ${a.style.defaultAnswer(!1===e.default?"y/N":"Y/n")}`;return`${c} ${a.style.message(e.message,n)}${l} ${u}`});const inputTheme={validationFailureMode:"keep"};var input=createPrompt((e,t)=>{
|
|
2502
|
+
const{required:r,validate:n=()=>!0,prefill:i="tab"}=e,s=makeTheme(inputTheme,e.theme),[o,a]=useState("idle"),[c="",u]=useState(e.default),[l,d]=useState(),[p,h]=useState(""),A=usePrefix({status:o,theme:s});useKeypress(async(e,i)=>{if("idle"===o)if(isEnterKey(e)){const e=p||c;a("loading");const o=r&&!e?"You must provide a value":await n(e);!0===o?(h(e),a("done"),t(e)):("clear"===s.validationFailureMode?h(""):i.write(p),d(o||"You must provide a valid value"),a("idle"))}else isBackspaceKey(e)&&!p?u(void 0):isTabKey(e)&&!p?(u(void 0),i.clearLine(0),i.write(c),h(c)):(h(i.line),d(void 0))}),useEffect(e=>{"editable"===i&&c&&(e.write(c),h(c))},[]);const f=s.style.message(e.message,o);let g,m=p;"function"==typeof e.transformer?m=e.transformer(p,{isFinal:"done"===o}):"done"===o&&(m=s.style.answer(p)),c&&"done"!==o&&!p&&(g=s.style.defaultAnswer(c));let y="";return l&&(y=s.style.error(l)),[[A,f,g,m].filter(e=>void 0!==e).join(" "),y]});const selectTheme={icon:{cursor:figures$1.pointer},style:{
|
|
2503
|
+
disabled:e=>colors.dim(`- ${e}`),description:e=>colors.cyan(e)},helpMode:"auto",indexMode:"hidden"};function isSelectable(e){return!Separator.isSeparator(e)&&!e.disabled}function normalizeChoices(e){return e.map(e=>{if(Separator.isSeparator(e))return e;if("string"==typeof e)return{value:e,name:e,short:e,disabled:!1};const t=e.name??String(e.value),r={value:e.value,name:t,short:e.short??t,disabled:e.disabled??!1};return e.description&&(r.description=e.description),r})}var select=createPrompt((e,t)=>{const{loop:r=!0,pageSize:n=7}=e,i=useRef(!0),s=makeTheme(selectTheme,e.theme),[o,a]=useState("idle"),c=usePrefix({status:o,theme:s}),u=useRef(),l=useMemo(()=>normalizeChoices(e.choices),[e.choices]),d=useMemo(()=>{const e=l.findIndex(isSelectable),t=l.findLastIndex(isSelectable);if(-1===e)throw new ValidationError$1("[select prompt] No selectable choices. All choices are disabled.");return{first:e,last:t}
|
|
2504
|
+
},[l]),p=useMemo(()=>"default"in e?l.findIndex(t=>isSelectable(t)&&t.value===e.default):-1,[e.default,l]),[h,A]=useState(-1===p?d.first:p),f=l[h];useKeypress((e,n)=>{if(clearTimeout(u.current),isEnterKey(e))a("done"),t(f.value);else if(isUpKey(e)||isDownKey(e)){if(n.clearLine(0),r||isUpKey(e)&&h!==d.first||isDownKey(e)&&h!==d.last){const t=isUpKey(e)?-1:1;let r=h;do{r=(r+t+l.length)%l.length}while(!isSelectable(l[r]));A(r)}}else if(isNumberKey(e)&&!Number.isNaN(Number(n.line))){const e=Number(n.line)-1;let t=-1;const r=l.findIndex(r=>!Separator.isSeparator(r)&&(t++,t===e)),i=l[r];null!=i&&isSelectable(i)&&A(r),u.current=setTimeout(()=>{n.clearLine(0)},700)}else if(isBackspaceKey(e))n.clearLine(0);else{const e=n.line.toLowerCase(),t=l.findIndex(t=>!(Separator.isSeparator(t)||!isSelectable(t))&&t.name.toLowerCase().startsWith(e));-1!==t&&A(t),u.current=setTimeout(()=>{n.clearLine(0)},700)}}),useEffect(()=>()=>{clearTimeout(u.current)},[]);const g=s.style.message(e.message,o)
|
|
2505
|
+
;let m="",y="";("always"===s.helpMode||"auto"===s.helpMode&&i.current)&&(i.current=!1,l.length>n?y=`\n${s.style.help(`(${e.instructions?.pager??"Use arrow keys to reveal more choices"})`)}`:m=s.style.help(`(${e.instructions?.navigation??"Use arrow keys"})`));let E=0;const b=usePagination({items:l,active:h,renderItem({item:e,isActive:t,index:r}){if(Separator.isSeparator(e))return E++,` ${e.separator}`;const n="number"===s.indexMode?r+1-E+". ":"";if(e.disabled){const t="string"==typeof e.disabled?e.disabled:"(disabled)";return s.style.disabled(`${n}${e.name} ${t}`)}return(t?s.style.highlight:e=>e)(`${t?s.icon.cursor:" "} ${n}${e.name}`)},pageSize:n,loop:r});if("done"===o)return`${c} ${g} ${s.style.answer(f.short)}`;const C=f.description?`\n${s.style.description(f.description)}`:"";return`${[c,g,m].filter(Boolean).join(" ")}\n${b}${y}${C}${cursorHide}`});function ensureAgentFiles(e,t){if(0===e.length)return[];const r=[],n=path__default.join(t,AGENTS_MD_FILENAME)
|
|
2506
|
+
;if(!fs$8.existsSync(n))throw new RequiresInitError;const i=path__default.join(t,"TESSL.md");for(const s of e){const e=AGENT_INFO[s].configFile,o=path__default.join(t,e);if(fs$8.existsSync(o)){if(o===n)continue;try{if(fs$8.lstatSync(o).isSymbolicLink()){const e=fs$8.readlinkSync(o);if(path__default.resolve(e)===path__default.resolve(n))continue;path__default.resolve(e)===path__default.resolve(i)&&fs$8.unlinkSync(o)}}catch(t){throw new AggregateError([t],`Failed to process existing file ${e}`)}}fs$8.existsSync(o)||(fs$8.writeFileSync(o,""),r.push({path:e,type:"file",description:"Created agent file"}));const a=`@${AGENTS_MD_FILENAME}`;fs$8.readFileSync(o,"utf-8").includes(a)||fs$8.appendFileSync(o,`\n${a}\n`)}for(const n of e){const e=AGENT_INFO[n];if("installCustomFiles"in e){const n=e.installCustomFiles(t);r.push(...n.map(e=>({path:e,type:"file",description:"Created custom agent file"})))}}return r}const AGENT_CHOICES=(()=>{
|
|
2507
|
+
const e=Object.entries(AGENT_INFO).filter(([,e])=>"experimental"!==e.level).map(([e,{label:t,level:r}])=>({name:"core"===r?t:`${t} (Alpha)`,value:e})),t=Object.entries(AGENT_INFO).filter(([,e])=>"experimental"===e.level).map(([e,{label:t}])=>({name:chalk.dim(t),value:e}));return[...e,new Separator("-- Experimental support --"),...t]})();async function promptForAgentSelection(e){if(e&&!RECOGNIZED_AGENTS.includes(e))throw new ExpectedError(`Unsupported agent: ${e}`);let t=e;return t||(t=await select({message:"Which agent would you like to set up?",choices:AGENT_CHOICES,loop:!1})),t}async function promptForMcpSetup(e,t,r){const{addMcpConfig:n,label:i}=AGENT_INFO[e];let s=!1;if(void 0!==n&&!r)try{s=t||await confirm({message:`Would you like to auto-configure Tessl's MCP integration for ${i}?`,default:!0})}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e}return s}async function promptForAgentSetup(e,t,r){try{const n=await promptForAgentSelection(e);return{
|
|
2508
|
+
selectedAgent:n,shouldSetupMcp:await promptForMcpSetup(n,t,r),agentLevel:AGENT_INFO[n].level}}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;return}}function performAgentSetup(e,t,r){const{selectedAgent:n,shouldSetupMcp:i}=e,{addMcpConfig:s}=AGENT_INFO[n],o=ensureAgentFiles([n],t),a=[];let c=!1;if(i&&s){const e=s(t);e&&a.push(e),c=!0}return r.agentSetup({agent:n}),c&&r.mcpSetup({client:n}),{agentFiles:o,mcpFiles:a,didSetupMcp:c}}function Link({url:e,children:t}){const r=`]8;;${e}${t}]8;;`;return jsxRuntimeExports.jsx(Text,{children:r})}function Success({children:e}){return jsxRuntimeExports.jsx(Log,{color:"green",children:e})}function Warning({children:e}){return jsxRuntimeExports.jsx(Log,{color:"yellow",children:e})}function logError$1(e){const t=getMessageFromMaybeError(e);getStackFromMaybeError(e),log(t,"red")}function Log({color:e="white",children:t}){return jsxRuntimeExports.jsx(Text,{color:e,children:t})}function log(e,t){
|
|
2509
|
+
render(jsxRuntimeExports.jsx(Log,{color:t,children:e}))}const flags$1={agent:{type:String,description:"The agent you would like to auto-configure",availableValues:RECOGNIZED_AGENTS},mcp:{type:Boolean,description:"Automatically configure Tessl MCP (if available)"},"no-mcp":{type:Boolean,description:"Do not automatically configure Tessl MCP"}},setupAgentCommand=new Command$1({name:"setup-agent",summary:"Connect your Tessl project context to AI agents and configure agents to use Tessl's MCP server",flags:flags$1,handler:async({args:{agent:e,mcp:t,"no-mcp":r},projectDir:n,monitoring:{analytics:i}})=>{try{const s=await promptForAgentSetup(e,t,r);if(!s)return SUCCESS;const{selectedAgent:o}=s,{agentFiles:a,mcpFiles:c,didSetupMcp:u}=performAgentSetup(s,n,i);return render(jsxRuntimeExports.jsx(Complete,{agent:o,createdFiles:a,createdMcpFiles:c,didSetupMcp:u})),SUCCESS}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;return SUCCESS}}})
|
|
2510
|
+
;function Complete({agent:e,createdFiles:t,didSetupMcp:r,createdMcpFiles:n}){const i=t.filter(e=>"symlink"===e.type),s=t.filter(e=>"file"===e.type),o=t.filter(e=>"subagent"===e.type),a=AGENT_INFO[e],{label:c}=a;return jsxRuntimeExports.jsx(Box,{gap:1,flexDirection:"column",children:jsxRuntimeExports.jsxs(Box,{flexDirection:"column",marginY:1,children:[jsxRuntimeExports.jsxs(Text,{color:"green",children:[c," configured successfully!"]}),jsxRuntimeExports.jsxs(Text,{children:[c," is now auto-configured to work with Tessl."]}),i.length+s.length+o.length>0&&jsxRuntimeExports.jsxs(Box,{flexDirection:"column",marginTop:1,children:[i.map(e=>jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{color:"green",children:"+"})," ",e.path," ",jsxRuntimeExports.jsxs(Text,{dimColor:!0,children:["â ",e.target]})]},e.path)),s.map(e=>jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{color:"green",children:"+"})," ",e.path," ",e.description&&jsxRuntimeExports.jsxs(Text,{
|
|
2511
|
+
dimColor:!0,children:["(",e.description,")"]})]},e.path)),o.length>0&&o.map(e=>jsxRuntimeExports.jsxs(Box,{flexDirection:"column",children:[jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{color:"green",children:"+"})," ",e.path," ",jsxRuntimeExports.jsx(Text,{dimColor:!0,children:"(Tessl subagent)"})]}),e.description&&jsxRuntimeExports.jsx(Box,{marginLeft:2,children:jsxRuntimeExports.jsx(Text,{dimColor:!0,children:e.description})})]},e.path))]}),r&&jsxRuntimeExports.jsxs(Box,{flexDirection:"column",marginTop:1,children:[jsxRuntimeExports.jsxs(Text,{children:["MCP has been auto-configured for ",c,"."]}),n.map(e=>jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{color:"green",children:"+"})," ",e," "]},e))]}),jsxRuntimeExports.jsx(AgentWarnings,{agentLevel:a.level})]})})}function AgentWarnings({agentLevel:e}){return e&&"core"!==e?jsxRuntimeExports.jsxs(Box,{flexDirection:"column",borderStyle:"single",padding:1,children:[jsxRuntimeExports.jsx(Warning,{
|
|
2512
|
+
children:`There are known issues with ${e} agents.`}),jsxRuntimeExports.jsxs(Text,{dimColor:!0,children:["Please refer to"," ",jsxRuntimeExports.jsx(Link,{url:`https://docs.tessl.io/reference/supported-platforms#${e}`,children:`https://docs.tessl.io/reference/supported-platforms#${e}`})," ","for more information."]})]}):null}function FilesCreated({base:e,filepaths:t}){return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:t.map(t=>jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{color:"green",children:"+"}),"Â ",e&&jsxRuntimeExports.jsxs(Text,{dimColor:!0,children:["/"!==e?e:"","/"]}),t]},t))})}function BigTessl(){return jsxRuntimeExports.jsx(Text,{children:"\n ______ ______ ______ ______ __\n /\\__ _\\/\\ ___\\ /\\ ___\\ /\\ ___\\ /\\ \\\n \\/_/\\ \\/\\ \\ __\\ \\ \\___ \\\\ \\___ \\\\ \\ \\____\n \\ \\_\\ \\ \\_____\\\\/\\_____\\\\/\\_____\\\\ \\_____\\\n \\/_/ \\/_____/ \\/_____/ \\/_____/ \\/_____/\n"})}
|
|
2513
|
+
function CommandText({children:e}){return jsxRuntimeExports.jsx(Text,{color:"blue",children:e})}const UPPERCASE=/[\p{Lu}]/u,LOWERCASE=/[\p{Ll}]/u,LEADING_CAPITAL=/^[\p{Lu}](?![\p{Lu}])/gu,IDENTIFIER=/([\p{Alpha}\p{N}_]|$)/u,SEPARATORS=/[_.\- ]+/,LEADING_SEPARATORS=new RegExp("^"+SEPARATORS.source),SEPARATORS_AND_IDENTIFIER=new RegExp(SEPARATORS.source+IDENTIFIER.source,"gu"),NUMBERS_AND_IDENTIFIER=new RegExp("\\d+"+IDENTIFIER.source,"gu"),preserveCamelCase=(e,t,r,n)=>{let i=!1,s=!1,o=!1,a=!1;for(let c=0;c<e.length;c++){const u=e[c];a=!(c>2)||"-"===e[c-3],i&&UPPERCASE.test(u)?(e=e.slice(0,c)+"-"+e.slice(c),i=!1,o=s,s=!0,c++):s&&o&&LOWERCASE.test(u)&&(!a||n)?(e=e.slice(0,c-1)+"-"+e.slice(c-1),o=s,s=!1,i=!0):(i=t(u)===u&&r(u)!==u,o=s,s=r(u)===u&&t(u)!==u)}return e},preserveConsecutiveUppercase=(e,t)=>(LEADING_CAPITAL.lastIndex=0,e.replaceAll(LEADING_CAPITAL,e=>t(e))),postProcess=(e,t)=>(SEPARATORS_AND_IDENTIFIER.lastIndex=0,NUMBERS_AND_IDENTIFIER.lastIndex=0,
|
|
2514
|
+
e.replaceAll(NUMBERS_AND_IDENTIFIER,(r,n,i)=>["_","-"].includes(e.charAt(i+r.length))?r:t(r)).replaceAll(SEPARATORS_AND_IDENTIFIER,(e,r)=>t(r)));function camelCase(e,t){if("string"!=typeof e&&!Array.isArray(e))throw new TypeError("Expected the input to be `string | string[]`");if(t={pascalCase:!1,preserveConsecutiveUppercase:!1,...t},0===(e=Array.isArray(e)?e.map(e=>e.trim()).filter(e=>e.length).join("-"):e.trim()).length)return"";const r=!1===t.locale?e=>e.toLowerCase():e=>e.toLocaleLowerCase(t.locale),n=!1===t.locale?e=>e.toUpperCase():e=>e.toLocaleUpperCase(t.locale);if(1===e.length)return SEPARATORS.test(e)?"":t.pascalCase?n(e):r(e);return e!==r(e)&&(e=preserveCamelCase(e,r,n,t.preserveConsecutiveUppercase)),e=e.replace(LEADING_SEPARATORS,""),e=t.preserveConsecutiveUppercase?preserveConsecutiveUppercase(e,r):r(e),t.pascalCase&&(e=n(e.charAt(0))+e.slice(1)),postProcess(e,n)}var stringWidth$1={exports:{}},ansiRegex$1,hasRequiredAnsiRegex$1,stripAnsi$1,hasRequiredStripAnsi$1
|
|
2515
|
+
;function requireAnsiRegex$1(){return hasRequiredAnsiRegex$1||(hasRequiredAnsiRegex$1=1,ansiRegex$1=({onlyFirst:e=!1}={})=>{const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}),ansiRegex$1}function requireStripAnsi$1(){if(hasRequiredStripAnsi$1)return stripAnsi$1;hasRequiredStripAnsi$1=1;const e=requireAnsiRegex$1();return stripAnsi$1=t=>"string"==typeof t?t.replace(e(),""):t,stripAnsi$1}var isFullwidthCodePoint$1={exports:{}},hasRequiredIsFullwidthCodePoint$1,emojiRegex$2,hasRequiredEmojiRegex$1,hasRequiredStringWidth$1,ansiAlign_1,hasRequiredAnsiAlign;function requireIsFullwidthCodePoint$1(){if(hasRequiredIsFullwidthCodePoint$1)return isFullwidthCodePoint$1.exports;hasRequiredIsFullwidthCodePoint$1=1
|
|
2516
|
+
;const e=e=>!Number.isNaN(e)&&(e>=4352&&(e<=4447||9001===e||9002===e||11904<=e&&e<=12871&&12351!==e||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141));return isFullwidthCodePoint$1.exports=e,isFullwidthCodePoint$1.exports.default=e,isFullwidthCodePoint$1.exports}function requireEmojiRegex$1(){return hasRequiredEmojiRegex$1?emojiRegex$2:(hasRequiredEmojiRegex$1=1,emojiRegex$2=function(){
|
|
2519
2517
|
return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g
|
|
2520
2518
|
})}function requireStringWidth$1(){if(hasRequiredStringWidth$1)return stringWidth$1.exports;hasRequiredStringWidth$1=1;const e=requireStripAnsi$1(),t=requireIsFullwidthCodePoint$1(),r=requireEmojiRegex$1(),n=n=>{if("string"!=typeof n||0===n.length)return 0;if(0===(n=e(n)).length)return 0;n=n.replace(r()," ");let i=0;for(let e=0;e<n.length;e++){const r=n.codePointAt(e);r<=31||r>=127&&r<=159||(r>=768&&r<=879||(r>65535&&e++,i+=t(r)?2:1))}return i};return stringWidth$1.exports=n,stringWidth$1.exports.default=n,stringWidth$1.exports}function requireAnsiAlign(){if(hasRequiredAnsiAlign)return ansiAlign_1;hasRequiredAnsiAlign=1;const e=requireStringWidth$1();function t(t,i){if(!t)return t;const s=(i=i||{}).align||"center";if("left"===s)return t;const o=i.split||"\n",a=i.pad||" ",c="right"!==s?r:n;let u,l=!1;Array.isArray(t)||(l=!0,t=String(t).split(o));let d=0;return t=t.map(function(t){return t=String(t),u=e(t),d=Math.max(u,d),{str:t,width:u}}).map(function(e){
|
|
2521
2519
|
return new Array(c(d,e.width)+1).join(a)+e.str}),l?t.join(o):t}function r(e,t){return Math.floor((e-t)/2)}function n(e,t){return e-t}return t.left=function(e){return t(e,{align:"left"})},t.center=function(e){return t(e,{align:"center"})},t.right=function(e){return t(e,{align:"right"})},ansiAlign_1=t}var ansiAlignExports=requireAnsiAlign(),ansiAlign=getDefaultExportFromCjs(ansiAlignExports);const NEWLINE="\n",PAD=" ",NONE="none",terminalColumns=()=>{const{env:e,stdout:t,stderr:r}=process$5;return t?.columns?t.columns:r?.columns?r.columns:e.COLUMNS?Number.parseInt(e.COLUMNS,10):80},getObject=e=>"number"==typeof e?{top:e,right:3*e,bottom:e,left:3*e}:{top:0,right:0,bottom:0,left:0,...e},getBorderWidth=e=>e===NONE?0:2,getBorderChars=e=>{const t=["topLeft","topRight","bottomRight","bottomLeft","left","right","top","bottom"];let r;if(e===NONE){e={};for(const r of t)e[r]=""}if("string"==typeof e){if(r=cliBoxes[e],!r)throw new TypeError(`Invalid border style: ${e}`)}else{
|
|
@@ -3297,11 +3295,11 @@ flexDirection:"column",marginTop:1,children:[t&&jsxRuntimeExports.jsx(Text,{bold
|
|
|
3297
3295
|
function Summary({messages:e}){const t=e.filter(e=>"report"===e.id&&"message"===e.data.type&&"summary"===e.data.message.type).map(({data:{message:e}})=>e).map(({id:e,content:t})=>t.map(t=>({id:e,text:t}))).flat().filter(Boolean);return 0===t.length?null:jsxRuntimeExports.jsxs(Box,{flexDirection:"column",children:[jsxRuntimeExports.jsx(Heading,{children:"Summary"}),t.map(({id:e,text:t})=>jsxRuntimeExports.jsx(Box,{children:jsxRuntimeExports.jsx(Text,{dimColor:!0,children:t})},`${e}-${t}`))]})}function ToolResults({mode:e,messages:t,activities:r,getTotalTokenCount:n,activeTypers:i,executionTree:s,fsd:o,staticMessages:a=!1,hideOverview:c=!1}){const u=a?jsxRuntimeExports.jsx(Static,{items:t,children:(t,r)=>jsxRuntimeExports.jsx(MessageEntry,{mode:e,event:t},r)}):jsxRuntimeExports.jsx(Box,{flexDirection:"column",children:t.map((t,r)=>jsxRuntimeExports.jsx(MessageEntry,{mode:e,event:t},r))});return jsxRuntimeExports.jsxs(Box,{flexDirection:"column",
|
|
3298
3296
|
children:[u,jsxRuntimeExports.jsx(Activities,{activities:r,activeTypers:i}),hasEnded(s)&&jsxRuntimeExports.jsxs(Box,{flexDirection:"column",children:[!c&&jsxRuntimeExports.jsx(Overview,{getTotalTokenCount:n,executionTree:s,fileDiff:isFsDiff(o)?o.diff():void 0}),jsxRuntimeExports.jsx(Summary,{messages:t})]})]})}function Sidecar({tailer:e}){const[t,r]=reactExports.useState(null),{messages:n,activities:i,hideOverview:s,handleManagementEvent:o,executionTree:a}=useReporterState(),c=reactExports.useRef(!1);return reactExports.useEffect(()=>{if(c.current)return;c.current=!0;(async()=>{try{await e.start({onEvent:e=>{o(e).catch(e=>{r(`Error handling event: ${String(e)}`)})},onError:e=>{r(`Error while tailing events: ${String(e)}`)},onShutdown:()=>{}})}catch(e){r(`Failed to start event observation: ${String(e)}`)}})().catch(e=>{r(`Failed to start tailing: ${String(e)}`)})},[e,o]),t?jsxRuntimeExports.jsx(Text,{children:t}):jsxRuntimeExports.jsx(ToolResults,{mode:"observe",messages:n,activities:i,
|
|
3299
3297
|
getTotalTokenCount:()=>0,activeTypers:new Map,executionTree:a,fsd:null,staticMessages:!0,hideOverview:s})}reactExports.createContext({marker:defaultMarker}),reactExports.createContext({depth:0}),chalk.inverse(" "),reactExports.createContext({marker:figures.line}),reactExports.createContext({marker:""}),chalk.inverse(" "),chalk.inverse(" ");const observeCommand=new Command$1({name:"observe",summary:"[Experimental] Provides a real-time view of Tessl activity for the current project. Run in a directory initialized with Tessl. Best used in a separate window.",requiresConfig:!1,flags:{},handler:async()=>{const e=getSessionDataPath(),t=path__default$1.join(e,"events.jsonl"),r=new EventTailer(t),n=render(jsxRuntimeExports.jsx(Sidecar,{tailer:r})),i=()=>{r.stop(),n.unmount()};process.on("SIGINT",i),process.on("SIGTERM",i);try{await n.waitUntilExit()}finally{process.removeListener("SIGINT",i),process.removeListener("SIGTERM",i)}return SUCCESS}});function createSpinner(e){return ora({
|
|
3300
|
-
hideCursor:!1,discardStdin:!1}).start(e)}const registryArchiveCommand=new Command$1({name:"registry-archive",summary:"Archive specs in the Tessl registry",allowArbitraryFlags:!1,flags:{
|
|
3301
|
-
version:o}},body:{archived:!0,archivedReason:i}});return l.error?(e.error({err:l.error},"Failed to archive spec"),u.fail(apiErrToString(l.error)),FAILURE):(u.succeed(`Archived ${a}/${c}@${o}`),SUCCESS)}});function _nullishCoalesce$i(e,t){return null!=e?e:t()}const installCommand=new Command$1({name:"registry-install",summary:"Install usage specs into your project",positionals:[{name:"name",description:"The name of the usage spec to install"}],allowArbitraryFlags:!1,requiresLogin:!1,requiresConfig:!1,handler:async({positionals:{name:e},monitoring:{analytics:t,logger:r},projectDir:n,isInteractive:i,tesslClient:s,isAuthenticated:o,monitoring:a})=>{const{isInitialized:c}=await ensureInit({targetDir:n,isAuthenticated:o,isInteractive:i,monitoring:a,args:{"no-mcp":!0}},"Usage specs require Tessl to be initialized. Would you like to initialize Tessl now?");if(!c)return SUCCESS;const u=openFsd(n);if(!e){
|
|
3302
|
-
;return t.success?(e.succeed("Installed usage specs"),SUCCESS):(r.error({err:t.error},"Failed to sync usage specs"),e.fail(t.error),FAILURE)}const l=createSpinner("Retrieving spec data"),d=e.split("@"),p=d[0];let h=d[1];const[A,f]=_nullishCoalesce$i(p,()=>"").split("/");if(!A||!f)return r.error({name:e},'The name argument must be in the format "workspace/tile" (or "workspace/tile@version")'),l.fail('The name argument must be in the format "workspace/tile" (or "workspace/tile@version")'),FAILURE;const g=await s.GET("/v1/tiles/{workspaceName}/{tileName}",{params:{path:{workspaceName:A,tileName:f}}});if(g.error)return r.error({name:e,err:g.error},"Failed to get tile"),l.fail(apiErrToString(g.error)),FAILURE;const m=g.data.data;if(!h){const e=m.attributes.latestVersion;if(!e)return r.error({fullName:p},"The tile does not have a latest version. Please specify a version"),
|
|
3303
|
-
const y=await s.GET("/v1/tiles/{workspaceName}/{tileName}/versions/{version}",{params:{path:{workspaceName:A,tileName:f,version:h}}});if(y.error)return r.error({fullName:p,version:h,err:y.error},"Failed to get tile version"),l.fail(apiErrToString(y.error)),FAILURE;const E=y.data.data;l.text=`Installing ${m.attributes.fullName}@${h}`;const b={workspaceName:A,tileName:f,version:E.attributes.version},C=await downloadTile(n,s,b);if(!C.success)return r.error({name:e,version:h,err:C.error},"Failed to download usage spec"),l.fail(C.error),FAILURE;const v=await updateTesslJsonDependencies(u,{add:[{workspaceName:A,tileName:f,newVersion:E.attributes.version}]});if(!v.success)return r.error({name:e,version:h,err:v.error},"Failed to update Tessl JSON dependencies"),l.fail(v.error),FAILURE;const I=await syncUsageSpecs(n,u,s);return I.success?(r.info({name:e,version:h},"Usage spec installed"),
|
|
3304
|
-
},"Failed to sync usage specs"),l.fail(stripIndents`${I.error}
|
|
3298
|
+
hideCursor:!1,discardStdin:!1}).start(e)}const registryArchiveCommand=new Command$1({name:"registry-archive",summary:"Archive specs in the Tessl registry",allowArbitraryFlags:!1,flags:{tile:{type:String,description:'The tile to archive, in the format "workspace/tile@version"'},reason:{type:String,description:"The reason for archiving the tile"}},requiresLogin:!0,requiresConfig:!1,handler:async({monitoring:{logger:e},args:t,tesslClient:r})=>{const{tile:n,reason:i}=t;if(!n)throw new ExpectedError('A --tile argument is required, in the format "workspace/tile@version"');if(!i)throw new ExpectedError("A --reason argument is required");const[s,o]=n.split("@");if(!s||!o)throw new ExpectedError('The tile must be in the format "workspace/tile@version"');const[a,c]=s.split("/");if(!a||!c)throw new ExpectedError('The spec must be in the format "workspace/tile"');const u=createSpinner("Archiving"),l=await r.POST("/v1/tiles/{workspaceName}/{tileName}/versions/{version}",{params:{path:{
|
|
3299
|
+
workspaceName:a,tileName:c,version:o}},body:{archived:!0,archivedReason:i}});return l.error?(e.error({err:l.error},"Failed to archive spec"),u.fail(apiErrToString(l.error)),FAILURE):(u.succeed(`Archived ${a}/${c}@${o}`),SUCCESS)}});function _nullishCoalesce$i(e,t){return null!=e?e:t()}const installCommand=new Command$1({name:"registry-install",summary:"Install usage specs into your project",positionals:[{name:"name",description:"The name of the usage spec to install"}],allowArbitraryFlags:!1,requiresLogin:!1,requiresConfig:!1,handler:async({positionals:{name:e},monitoring:{analytics:t,logger:r},projectDir:n,isInteractive:i,tesslClient:s,isAuthenticated:o,monitoring:a})=>{const{isInitialized:c}=await ensureInit({targetDir:n,isAuthenticated:o,isInteractive:i,monitoring:a,args:{"no-mcp":!0}},"Usage specs require Tessl to be initialized. Would you like to initialize Tessl now?");if(!c)return SUCCESS;const u=openFsd(n);if(!e){
|
|
3300
|
+
const e=createSpinner("Installing usage specs"),t=await syncUsageSpecs(n,u,s);return t.success?(e.succeed("Installed usage specs"),SUCCESS):(r.error({err:t.error},"Failed to sync usage specs"),e.fail(t.error),FAILURE)}const l=createSpinner("Retrieving spec data"),d=e.split("@"),p=d[0];let h=d[1];const[A,f]=_nullishCoalesce$i(p,()=>"").split("/");if(!A||!f)return r.error({name:e},'The name argument must be in the format "workspace/tile" (or "workspace/tile@version")'),l.fail('The name argument must be in the format "workspace/tile" (or "workspace/tile@version")'),FAILURE;const g=await s.GET("/v1/tiles/{workspaceName}/{tileName}",{params:{path:{workspaceName:A,tileName:f}}});if(g.error)return r.error({name:e,err:g.error},"Failed to get tile"),l.fail(apiErrToString(g.error)),FAILURE;const m=g.data.data;if(!h){const e=m.attributes.latestVersion;if(!e)return r.error({fullName:p},"The tile does not have a latest version. Please specify a version"),
|
|
3301
|
+
l.fail("The tile does not have a latest version. Please specify a version"),FAILURE;h=e}const y=await s.GET("/v1/tiles/{workspaceName}/{tileName}/versions/{version}",{params:{path:{workspaceName:A,tileName:f,version:h}}});if(y.error)return r.error({fullName:p,version:h,err:y.error},"Failed to get tile version"),l.fail(apiErrToString(y.error)),FAILURE;const E=y.data.data;l.text=`Installing ${m.attributes.fullName}@${h}`;const b={workspaceName:A,tileName:f,version:E.attributes.version},C=await downloadTile(n,s,b);if(!C.success)return r.error({name:e,version:h,err:C.error},"Failed to download usage spec"),l.fail(C.error),FAILURE;const v=await updateTesslJsonDependencies(u,{add:[{workspaceName:A,tileName:f,newVersion:E.attributes.version}]});if(!v.success)return r.error({name:e,version:h,err:v.error},"Failed to update Tessl JSON dependencies"),l.fail(v.error),FAILURE;const I=await syncUsageSpecs(n,u,s);return I.success?(r.info({name:e,version:h},"Usage spec installed"),
|
|
3302
|
+
l.succeed(`Installed ${m.attributes.fullName}@${h}`),t.tileInstall(b),SUCCESS):(r.error({name:e,err:I.error},"Failed to sync usage specs"),l.fail(stripIndents`${I.error}
|
|
3305
3303
|
|
|
3306
3304
|
${m.attributes.fullName}@${h} added to tessl.json, but dependency sync failed.
|
|
3307
3305
|
Your agent won't have access to the newly installed usage spec until this is fixed.
|
|
@@ -3543,28 +3541,30 @@ return[n,s]}s=skipUntil(e,t,",",r);let a=sliceAndTrimEndOf(e,t,s-+(","===e[s-1])
|
|
|
3543
3541
|
a=a[e].c}}if(i=e[t],(c=Object.hasOwn(o,i))&&0===a[i]?.t&&a[i]?.d)return null;c||("__proto__"===i&&(Object.defineProperty(o,i,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(a,i,{enumerable:!0,configurable:!0,writable:!0})),a[i]={t:t<e.length-1&&2===n?3:n,d:!1,i:0,c:{}})}if(s=a[i],s.t!==n&&(1!==n||3!==s.t))return null;if(2===n&&(s.d||(s.d=!0,o[i]=[]),o[i].push(o={}),s.c[s.i++]=s={t:1,d:!1,i:0,c:{}}),s.d)return null;if(s.d=!0,1===n)o=c?o[i]:o[i]={};else if(0===n&&c)return null;return[i,o,s.c]}function parse$2(e,{maxDepth:t=1e3,integersAsBigInt:r}={}){let n={},i={},s=n,o=i;for(let a=skipVoid(e,0);a<e.length;){if("["===e[a]){let t="["===e[++a],r=parseKey(e,a+=+t,"]");if(t){if("]"!==e[r[1]-1])throw new TomlError("expected end of table declaration",{toml:e,ptr:r[1]-1});r[1]++}let c=peekTable(r[0],n,i,t?2:1);if(!c)throw new TomlError("trying to redefine an already defined table or value",{toml:e,ptr:a});o=c[2],s=c[1],a=r[1]}else{let n=parseKey(e,a),i=peekTable(n[0],s,o,0)
|
|
3544
3542
|
;if(!i)throw new TomlError("trying to redefine an already defined table or value",{toml:e,ptr:a});let c=extractValue(e,n[1],void 0,t,r);i[1][i[0]]=c[0],a=c[1]}if(a=skipVoid(e,a,!0),e[a]&&"\n"!==e[a]&&"\r"!==e[a])throw new TomlError("each key-value declaration must be followed by an end-of-line",{toml:e,ptr:a});a=skipVoid(e,a)}return n}function _optionalChain$m(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}class PythonDetector{constructor(e){this.fsd=e}async getDependencies(){const e=[],t=[];let r=!1,n="requirements.txt",i="full",s=[];try{const e=await this.fsd.exists("requirements.txt"),t=await this.fsd.exists("setup.py");if(r=e||t,n=e?"requirements.txt":t?"setup.py":"requirements.txt",r){const{dependencies:e,supportLevel:t}=await this.extractPipDependencies();s=e,i=t}}catch(t){
|
|
3545
3543
|
e.push(t)}t.push({packageManager:"pip",manifestPath:n,detected:r,supportLevel:i,dependencies:s});let o=!1,a=[],c="experimental";try{if(o=await this.hasPoetryConfig(),o){const{dependencies:e,supportLevel:t}=await this.extractPoetryDependencies();a=e,c=t}}catch(t){e.push(t)}const u={packageManager:"poetry",manifestPath:"pyproject.toml",detected:o,supportLevel:c,dependencies:a};try{o&&await this.fsd.exists("poetry.lock")&&(u.lockfilePath="poetry.lock")}catch(t){e.push(t)}if(t.push(u),e.length>0)throw new AggregateError(e,"Failed to extract Python dependencies");return t}async hasPoetryConfig(){if(!await this.fsd.exists("pyproject.toml"))return!1;if(await this.fsd.exists("poetry.lock"))return!0;const e=await this.fsd.readText("pyproject.toml");if(!e)return!1;try{const t=parse$2(e);return!(!t.tool||!t.tool.poetry)}catch(e){return!1}}async extractPipDependencies(){try{const e=await exec({cmd:"pip list --format=json",cwd:this.fsd.root,timeoutSecs:30});if(0===e.code&&e.stdout.trim())try{
|
|
3546
|
-
const t=JSON.parse(e.stdout)
|
|
3547
|
-
;
|
|
3548
|
-
;if(""===e.trim())throw new Error("pyproject.toml is empty");let t;try{t=parse$2(e)}catch(e){throw new Error(`Failed to parse pyproject.toml: ${e.message}`)}const r=_optionalChain$m([t,"access",e=>e.tool,"optionalAccess",e=>e.poetry,"optionalAccess",e=>e.dependencies]);if(!r||"object"!=typeof r)return[];const n=[];for(const[e,t]of Object.entries(r)){if("python"===e)continue
|
|
3549
|
-
const e=await this.getMavenDependencies();t.push(e)}catch(t){e.push(t)}try{const e=await this.getGradleDependencies();t.push(e)}catch(t){e.push(t)}if(e.length>0)throw new AggregateError(e,"Failed to extract Java dependencies");return t}async getMavenDependencies(){const e="pom.xml";if(!await this.fsd.exists(e))return{packageManager:"maven",manifestPath:e,detected:!1,supportLevel:"full",
|
|
3550
|
-
|
|
3551
|
-
throw new Error(`Failed to parse Gradle files: ${e instanceof Error?e.message:"Unknown error"}`)}}}parseMavenCommandOutput(e){const t=[],r=new Set,n=/^\[INFO\]\s+([^:]+):([^:]+):[^:]+:([^:]+):/;for(const i of e.split("\n")){const e=n.exec(i.trim());if(e){const[,n,i,s]=e,o=`${n}:${i}:${s}`;r.has(o)||(r.add(o),t.push({displayName:`${n}:${i}@${s}`,namespace:n,name:i,version:s,packageType:"maven"}))}}return t}parseGradleCommandOutput(e){
|
|
3552
|
-
const
|
|
3553
|
-
throw new Error(`Malformed Gradle build file: ${e instanceof Error?e.message:"Unknown parsing error"}`)}}}class RustDetector{constructor(e){this._fsd=e}async getDependencies(){try{const e=await this._fsd.exists("Cargo.toml"),t=await this._fsd.exists("Cargo.lock");return[{packageManager:"cargo",manifestPath:"Cargo.toml",lockfilePath:"Cargo.lock",detected:e&&t,
|
|
3544
|
+
const t=JSON.parse(e.stdout),r=await this.fsd.readText("requirements.txt"),n=await this.fsd.readText("setup.py"),i=this.extractRequiredPackageNames(r),s=n?this.parseSetupPy(n):[],o=new Set(s.map(e=>e.name.toLowerCase())),a=new Set([...i,...o]);return{dependencies:t.filter(e=>a.has(e.name.toLowerCase())).map(e=>({displayName:`${e.name}@${e.version}`,name:e.name,version:e.version,packageType:"pypi"})),supportLevel:"full"}}catch(e){}}catch(e){}return{dependencies:await this.parsePipFiles(),supportLevel:"experimental"}}extractRequiredPackageNames(e){const t=new Set;if(!e)return t;const r=/^[A-Z0-9](?:[A-Z0-9._-]*[A-Z0-9])?/i,n=e.split("\n").map(e=>e.trim()).filter(e=>e&&!e.startsWith("#")&&!e.startsWith("-e")&&!e.startsWith("--")&&!e.startsWith("git+")&&!e.startsWith("http"));for(const e of n){const n=e.match(r);n&&t.add(n[0].toLowerCase())}return t}async extractPoetryDependencies(){try{const e=await exec({cmd:"poetry show --format=json",cwd:this.fsd.root,timeoutSecs:30})
|
|
3545
|
+
;if(0===e.code&&e.stdout.trim())try{const t=JSON.parse(e.stdout);return{dependencies:t.map(e=>({displayName:`${e.name}@${e.version}`,name:e.name,version:e.version,packageType:"pypi"})),supportLevel:"experimental"}}catch(e){}}catch(e){}return{dependencies:await this.parsePoetryFile(),supportLevel:"experimental"}}async parsePipFiles(){const e=[],t=await this.fsd.readText("requirements.txt");if(t){if(""===t.trim())throw new Error("requirements.txt is empty");e.push(...this.parseRequirementsTxt(t))}const r=await this.fsd.readText("setup.py");if(r){if(""===r.trim())throw new Error("setup.py is empty");e.push(...this.parseSetupPy(r))}if(0===e.length)throw new Error("No dependencies found in requirements.txt or setup.py");return e}parseRequirementsTxt(e){const t=e.split("\n").map(e=>e.trim()).filter(e=>e&&!e.startsWith("#")),r=[];for(const e of t){const t=e.match(/^([a-zA-Z0-9_-]+)([><=~!]+.*)?$/);if(!t)continue;const n=t[1],i=(t[2]||"").match(/[><=~!]*([0-9.]+)/),s=i?i[1]:"unknown";r.push({
|
|
3546
|
+
displayName:`${n}@${s}`,name:n,version:s,packageType:"pypi"})}return r}parseSetupPy(e){const t=e.match(/install_requires\s*=\s*\[(.*?)\]/s);if(!t)return[];const r=t[1].split(",").map(e=>e.trim().replace(/['"]/g,"")).filter(e=>e),n=[];for(const e of r){const t=e.match(/^([a-zA-Z0-9_-]+)([><=~!]+.*)?$/);if(!t)continue;const r=t[1],i=(t[2]||"").match(/[><=~!]*([0-9.]+)/),s=i?i[1]:"unknown";n.push({displayName:`${r}@${s}`,name:r,version:s,packageType:"pypi"})}return n}async parsePoetryFile(){const e=await this.fsd.readText("pyproject.toml");if(null==e)return[];if(""===e.trim())throw new Error("pyproject.toml is empty");let t;try{t=parse$2(e)}catch(e){throw new Error(`Failed to parse pyproject.toml: ${e.message}`)}const r=_optionalChain$m([t,"access",e=>e.tool,"optionalAccess",e=>e.poetry,"optionalAccess",e=>e.dependencies]);if(!r||"object"!=typeof r)return[];const n=[];for(const[e,t]of Object.entries(r)){if("python"===e)continue
|
|
3547
|
+
;const r="string"==typeof t?this.extractVersionFromSpec(t):"unknown";n.push({displayName:`${e}@${r}`,name:e,version:r,packageType:"pypi"})}return n}extractVersionFromSpec(e){const t=e.match(/[><=~^]*([0-9.]+)/);return t?t[1]:e}}function _optionalChain$l(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}class JavaDetector{constructor(e){this.fsd=e}async getDependencies(){const e=[],t=[];try{const e=await this.getMavenDependencies();t.push(e)}catch(t){e.push(t)}try{const e=await this.getGradleDependencies();t.push(e)}catch(t){e.push(t)}if(e.length>0)throw new AggregateError(e,"Failed to extract Java dependencies");return t}async getMavenDependencies(){const e="pom.xml";if(!await this.fsd.exists(e))return{packageManager:"maven",manifestPath:e,detected:!1,supportLevel:"full",
|
|
3548
|
+
dependencies:[]};try{const t=await this.fsd.exists("mvnw")?"./mvnw":"mvn",{stdout:r,error:n,code:i}=await exec({cmd:`${t} dependency:list -DexcludeTransitive=true`,cwd:this.fsd.root,timeoutSecs:30});if(n||0!==i)throw n||new Error(`Maven command failed with code ${i}`);return{packageManager:"maven",manifestPath:e,detected:!0,supportLevel:"full",dependencies:this.parseMavenCommandOutput(r)}}catch(t){try{return{packageManager:"maven",manifestPath:e,detected:!0,supportLevel:"experimental",dependencies:await this.parsePomXml()}}catch(e){throw new Error(`Failed to parse pom.xml: ${e instanceof Error?e.message:"Unknown error"}`)}}}async getGradleDependencies(){const e=await this.fsd.exists("build.gradle"),t=await this.fsd.exists("build.gradle.kts");let r;if(r=e?"build.gradle":t?"build.gradle.kts":"build.gradle",!e&&!t)return{packageManager:"gradle",manifestPath:r,detected:!1,supportLevel:"experimental",dependencies:[]};try{
|
|
3549
|
+
const e=await this.fsd.exists("gradlew")?"./gradlew":"gradle",{stdout:t,error:n,code:i}=await exec({cmd:`${e} dependencies --configuration=runtimeClasspath --quiet`,cwd:this.fsd.root,timeoutSecs:30});if(n||0!==i)throw n||new Error(`Gradle command failed with code ${i}`);return{packageManager:"gradle",manifestPath:r,detected:!0,supportLevel:"experimental",dependencies:this.parseGradleCommandOutput(t)}}catch(e){try{return{packageManager:"gradle",manifestPath:r,detected:!0,supportLevel:"experimental",dependencies:await this.parseGradleFiles()}}catch(e){throw new Error(`Failed to parse Gradle files: ${e instanceof Error?e.message:"Unknown error"}`)}}}parseMavenCommandOutput(e){const t=[],r=new Set,n=/^\[INFO\]\s+([^:]+):([^:]+):[^:]+:([^:]+):/;for(const i of e.split("\n")){const e=n.exec(i.trim());if(e){const[,n,i,s]=e,o=`${n}:${i}:${s}`;r.has(o)||(r.add(o),t.push({displayName:`${n}:${i}@${s}`,namespace:n,name:i,version:s,packageType:"maven"}))}}return t}parseGradleCommandOutput(e){
|
|
3550
|
+
const t=[],r=new Set,n=/^[+\\]---\s+([^:]+):([^:]+):([^\s]+)/;for(const i of e.split("\n")){const e=n.exec(i);if(e){const[,n,i,s]=e,o=`${n}:${i}:${s}`;r.has(o)||(r.add(o),t.push({displayName:`${n}:${i}@${s}`,namespace:n,name:i,version:s,packageType:"maven"}))}}return t}async parsePomXml(){const e=await this.fsd.readText("pom.xml");if(!e)throw new Error("pom.xml is empty or unreadable");try{const t=(new XMLParser).parse(e),r=[],n=_optionalChain$l([t,"optionalAccess",e=>e.project,"optionalAccess",e=>e.dependencies,"optionalAccess",e=>e.dependency]);if(n){const e=Array.isArray(n)?n:[n];for(const t of e)t.groupId&&t.artifactId&&t.version&&r.push({displayName:`${t.groupId}:${t.artifactId}@${t.version}`,namespace:t.groupId,name:t.artifactId,version:t.version,packageType:"maven"})}return r}catch(e){throw new Error(`Malformed pom.xml: ${e instanceof Error?e.message:"Unknown parsing error"}`)}}async parseGradleFiles(){
|
|
3551
|
+
const e=await this.fsd.readText("build.gradle"),t=await this.fsd.readText("build.gradle.kts"),r=e||t;if(!r)throw new Error("Gradle build files are empty or unreadable");try{const e=[],t=new Set,n=/(?:implementation|compile|api|runtimeOnly|testImplementation)\s+['"]([^:]+):([^:]+):([^'"]+)['"]/g,i=/(?:implementation|compile|api|runtimeOnly|testImplementation)\s*\(\s*["']([^:]+):([^:]+):([^"']+)["']\s*\)/g;for(const s of[n,i]){let n;for(;null!==(n=s.exec(r));){const[,r,i,s]=n,o=`${r}:${i}:${s}`;t.has(o)||(t.add(o),e.push({displayName:`${r}:${i}@${s}`,namespace:r,name:i,version:s,packageType:"maven"}))}}return e}catch(e){throw new Error(`Malformed Gradle build file: ${e instanceof Error?e.message:"Unknown parsing error"}`)}}}class RustDetector{constructor(e){this._fsd=e}async getDependencies(){try{const e=await this._fsd.exists("Cargo.toml"),t=await this._fsd.exists("Cargo.lock");return[{packageManager:"cargo",manifestPath:"Cargo.toml",lockfilePath:"Cargo.lock",detected:e&&t,
|
|
3552
|
+
supportLevel:"unsupported",dependencies:[]}]}catch(e){throw new AggregateError([e],"Failed to get Rust dependencies")}}}class RubyDetector{constructor(e){this.fsd=e}async getDependencies(){const e="Gemfile",t="Gemfile.lock";try{const r=await this.fsd.exists(e),n=await this.fsd.exists(t);return[{packageManager:"bundler",manifestPath:e,lockfilePath:t,detected:r&&n,supportLevel:"unsupported",dependencies:[]}]}catch(e){throw new AggregateError([e],"Error detecting Ruby Bundler project")}}}class GoDetector{constructor(e){this.fsd=e}async getDependencies(){try{const e=await this.fsd.exists("go.mod"),t=await this.fsd.exists("go.sum");return[{packageManager:"go",manifestPath:"go.mod",lockfilePath:"go.sum",detected:e&&t,supportLevel:"unsupported",dependencies:[]}]}catch(e){throw new AggregateError([e],"Error detecting Go dependencies")}}}class PhpDetector{constructor(e){this.fsd=e}async getDependencies(){const e=[];try{
|
|
3553
|
+
const[e,t]=await Promise.all([this.fsd.exists("composer.json"),this.fsd.exists("composer.lock")]);return[{packageManager:"composer",manifestPath:"composer.json",lockfilePath:"composer.lock",detected:e&&t,supportLevel:"unsupported",dependencies:[]}]}catch(t){e.push(t instanceof Error?t:new Error(String(t)))}if(e.length>0)throw new AggregateError(e,"Failed to detect PHP Composer dependencies");return[]}}class DepList{constructor(e){this.detectors=[new NpmDetector(e),new PythonDetector(e),new JavaDetector(e),new RustDetector(e),new RubyDetector(e),new GoDetector(e),new PhpDetector(e)]}async scan(){const e=[],t=[];for(const r of this.detectors)try{const e=await r.getDependencies();t.push(...e)}catch(t){e.push(t instanceof Error?t:new Error(String(t)))}if(e.length>0)throw new AggregateError(e,"One or more detectors failed");return{results:t}}}const cyan=e=>styleText("cyan",e.toString()),syncCommand=new Command$1({name:"registry-sync",
|
|
3554
3554
|
summary:"Check for newer versions of tiles and install them into your project",allowArbitraryFlags:!1,requiresLogin:!1,requiresConfig:!1,flags:{yes:{type:Boolean,description:"Automatically accept all installations and updates",short:"y"}},handler:async({monitoring:e,projectDir:t,isInteractive:r,tesslClient:n,isAuthenticated:i,args:s})=>{if(!r)throw new ExpectedError('"sync" does not support non-interactive mode');const{logger:o,analytics:a}=e,c={scanned:[],dependenciesWithoutTiles:[],tilesInstalled:[]},u=createSpinner("Scanning project dependencies..."),l=openFsd(t),d=await gatherDependencies({fsd:l,logger:o,analytics:a,trackingData:c});if(0===d.results.flatMap(e=>e.dependencies).length)return u.succeed('No dependencies found. Use "tessl registry search" to find and install usage specs.'),a.registrySync(c),SUCCESS;u.start("Finding candidates...");const p=await findCandidates({scanResult:d,tesslClient:n});u.stop()
|
|
3555
3555
|
;const h=p.some(e=>e.dependenciesWithCandidates.some(e=>null!==e.candidate));if(!h)return u.succeed("No suitable tiles found"),c.dependenciesWithoutTiles=d.results.flatMap(e=>e.dependencies.map(e=>({displayName:e.displayName,packageType:e.packageType}))),a.registrySync(c),SUCCESS;const{isInitialized:A}=await ensureInit({targetDir:t,isAuthenticated:i,isInteractive:r,monitoring:e,args:{"no-mcp":!0}},"Tiles require Tessl to be initialized. Would you like to initialize Tessl now?");if(!A)return c.refusedInit=!0,a.registrySync(c),SUCCESS;const f=await loadTesslManifest(l);for(const e of p){const t=analyzeDependencyGroup(e,f.dependencies||{});if(c.dependenciesWithoutTiles.push(...t.dependenciesWithoutTiles.map(e=>({displayName:e.displayName,packageType:e.packageType}))),0===t.tilesToInstall.length&&0===t.tilesToUpdate.length){u.succeed(`All tiles are up to date for ${cyan(t.packageManager)} manifest ${cyan(t.manifestPath)}`);continue}const r=await selectTiles({analysis:t,args:s,spinner:u,
|
|
3556
3556
|
logger:o});if("cancelled"in r)return c.cancelled=!0,a.registrySync(c),SUCCESS;if(!(await installTiles({chosen:r.chosen,analysis:t,fsd:l,tesslClient:n,spinner:u,analytics:a,logger:o})).success)return a.registrySync(c),FAILURE;c.tilesInstalled.push(...r.chosen)}return a.registrySync(c),SUCCESS}});async function gatherDependencies({fsd:e,logger:t,analytics:r,trackingData:n}){try{const t=new DepList(e),r=await t.scan();return n.scanned=r.results.map(({packageManager:e,manifestPath:t,lockfilePath:r,detected:n,supportLevel:i})=>({packageManager:e,manifestPath:t,lockfilePath:r,detected:n,supportLevel:i})),r}catch(e){return t.error({err:e},"Failed to gather dependencies"),r.cliError({command:"registry-sync",message:getMessageFromMaybeError(e),stack:getStackFromMaybeError(e)||"Unknown stack",expected:!1}),{results:[]}}}async function loadTesslManifest(e){const t=await readTesslJson(e);if(!t.success)throw new ExpectedError(`Failed to read tessl.json: ${t.error}`);return t.data}
|
|
3557
|
-
async function findCandidates({scanResult:e,tesslClient:t}){const r=[];for(const{packageManager:n,manifestPath:i,dependencies:s,detected:o}of e.results){if(!o)continue;const e=await cMap(s,async e=>({dependency:e,candidate:await findBestTile(t,e)}));r.push({packageManager:n,manifestPath:i,dependenciesWithCandidates:e})}return r}async function findBestTile(e,t){const r=new packageurlJsExports.PackageURL(t.packageType,t.namespace,t.name).toString(),n=await e.GET("/v1/tiles",{params:{query:{"filter[describes]":r,"page[size]":1}}});if(n.error)return null;const i=n.data.data;if(0===i.length)return null;const s=i[0],[o,a]=s.attributes.fullName.split("/"),c=r+`@${t.version.split(".")[0]}`,u=await e.GET("/v1/tiles/{workspaceName}/{tileName}/versions",{params:{path:{workspaceName:o,tileName:a},query:{"filter[describes][like]":c,"page[size]":1}}});if(u.error)return null;const l=u.data.data[0];return l?{workspaceName:o,tileName:a,version:l.attributes.version
|
|
3558
|
-
function analyzeDependencyGroup(e,t){const r=[],n=[],i=[];for(const{candidate:s,dependency:o}of e.dependenciesWithCandidates){if(!s){i.push(o);continue}const e=t[`${s.workspaceName}/${s.tileName}`];e?semverExports.gt(s.version,e.version)&&n.push({candidate:s,dependency:o,currentVersion:e.version}):r.push({candidate:s,dependency:o})}return{packageManager:e.packageManager,manifestPath:e.manifestPath,tilesToInstall:r,tilesToUpdate:n,dependenciesWithoutTiles:i}}function calculateDisplayPadding(e){const t={name:0,currentVersion:0,candidateVersion:0};for(const{candidate:r}of[...e.tilesToInstall,...e.tilesToUpdate]){const e=`${r.workspaceName}/${r.tileName}`;t.name=Math.max(t.name,e.length),t.candidateVersion=Math.max(t.candidateVersion,r.version.length)}for(const{currentVersion:r}of e.tilesToUpdate)t.currentVersion=Math.max(t.currentVersion,r.length);return t}function buildTileChoices(e,t){const r=[]
|
|
3559
|
-
r.push(...e.tilesToUpdate.map(({candidate:e,dependency:r,currentVersion:n})=>({name:`${`${e.workspaceName}/${e.tileName}`.padEnd(t.name)} ${n.padEnd(t.currentVersion)} -> ${e.version.padEnd(t.candidateVersion)} (${r.displayName})`,value:{...e,isUpdate:!0},checked:!0})))),e.tilesToInstall.length>0&&(r.push(new Separator("-- Select new tiles to install --")),r.push(...e.tilesToInstall.map(({candidate:e,dependency:r})=>({name:`${`${e.workspaceName}/${e.tileName}`.padEnd(t.name)} ${e.version.padEnd(t.candidateVersion)} (${r.displayName})`,value:{...e,isUpdate:!1},checked:!0})))),r}async function selectTiles({analysis:e,args:t,spinner:r,logger:n}){const{packageManager:i,manifestPath:s,tilesToInstall:o,tilesToUpdate:a}=e;r.info(`Found ${cyan(o.length)} tiles to install and ${cyan(a.length)} to update for ${cyan(i)} manifest ${cyan(s)}`);const c=buildTileChoices(e,calculateDisplayPadding(e));let u
|
|
3560
|
-
message:"Select tiles to install",choices:c,pageSize:12,loop:!1,theme:{style:{renderSelectedChoices:()=>""},helpMode:"always"}})}catch(e){if(e instanceof ExitPromptError)return{cancelled:!0};throw n.error({choices:c},"Error while selecting tiles to install"),e}return 0===u.length&&r.info(`0 tiles selected for ${cyan(i)} manifest ${cyan(s)}`),{chosen:u}}async function installTiles({fsd:e,chosen:t,analysis:r,tesslClient:n,spinner:i,analytics:s,logger:o}){const{packageManager:a,manifestPath:c}=r;if(0===t.length)return{success:!0};i.start(`Installing tiles for ${cyan(a)} manifest ${cyan(c)}...`);const u=await updateTesslJsonDependencies(e,{add:t.map(({workspaceName:e,tileName:t,version:r})=>({workspaceName:e,tileName:t,newVersion:r}))});if(!u.success)return o.error({err:u.error},"Failed to update Tessl JSON dependencies"),i.fail(u.error),{success:!1,error:u.error};const l=await syncUsageSpecs(e.root,e,n)
|
|
3561
|
-
i.fail(stripIndents`${l.error}
|
|
3557
|
+
async function findCandidates({scanResult:e,tesslClient:t}){const r=[];for(const{packageManager:n,manifestPath:i,dependencies:s,detected:o,supportLevel:a}of e.results){if(!o||"unsupported"===a)continue;const e=await cMap(s,async e=>({dependency:e,candidate:await findBestTile(t,e)}));r.push({packageManager:n,manifestPath:i,dependenciesWithCandidates:e})}return r}async function findBestTile(e,t){const r=new packageurlJsExports.PackageURL(t.packageType,t.namespace,t.name).toString(),n=await e.GET("/v1/tiles",{params:{query:{"filter[describes]":r,"page[size]":1}}});if(n.error)return null;const i=n.data.data;if(0===i.length)return null;const s=i[0],[o,a]=s.attributes.fullName.split("/"),c=r+`@${t.version.split(".")[0]}`,u=await e.GET("/v1/tiles/{workspaceName}/{tileName}/versions",{params:{path:{workspaceName:o,tileName:a},query:{"filter[describes][like]":c,"page[size]":1}}});if(u.error)return null;const l=u.data.data[0];return l?{workspaceName:o,tileName:a,version:l.attributes.version
|
|
3558
|
+
}:null}function analyzeDependencyGroup(e,t){const r=[],n=[],i=[];for(const{candidate:s,dependency:o}of e.dependenciesWithCandidates){if(!s){i.push(o);continue}const e=t[`${s.workspaceName}/${s.tileName}`];e?semverExports.gt(s.version,e.version)&&n.push({candidate:s,dependency:o,currentVersion:e.version}):r.push({candidate:s,dependency:o})}return{packageManager:e.packageManager,manifestPath:e.manifestPath,tilesToInstall:r,tilesToUpdate:n,dependenciesWithoutTiles:i}}function calculateDisplayPadding(e){const t={name:0,currentVersion:0,candidateVersion:0};for(const{candidate:r}of[...e.tilesToInstall,...e.tilesToUpdate]){const e=`${r.workspaceName}/${r.tileName}`;t.name=Math.max(t.name,e.length),t.candidateVersion=Math.max(t.candidateVersion,r.version.length)}for(const{currentVersion:r}of e.tilesToUpdate)t.currentVersion=Math.max(t.currentVersion,r.length);return t}function buildTileChoices(e,t){const r=[]
|
|
3559
|
+
;return e.tilesToUpdate.length>0&&(r.push(new Separator("-- Select tiles to update --")),r.push(...e.tilesToUpdate.map(({candidate:e,dependency:r,currentVersion:n})=>({name:`${`${e.workspaceName}/${e.tileName}`.padEnd(t.name)} ${n.padEnd(t.currentVersion)} -> ${e.version.padEnd(t.candidateVersion)} (${r.displayName})`,value:{...e,isUpdate:!0},checked:!0})))),e.tilesToInstall.length>0&&(r.push(new Separator("-- Select new tiles to install --")),r.push(...e.tilesToInstall.map(({candidate:e,dependency:r})=>({name:`${`${e.workspaceName}/${e.tileName}`.padEnd(t.name)} ${e.version.padEnd(t.candidateVersion)} (${r.displayName})`,value:{...e,isUpdate:!1},checked:!0})))),r}async function selectTiles({analysis:e,args:t,spinner:r,logger:n}){const{packageManager:i,manifestPath:s,tilesToInstall:o,tilesToUpdate:a}=e;r.info(`Found ${cyan(o.length)} tiles to install and ${cyan(a.length)} to update for ${cyan(i)} manifest ${cyan(s)}`);const c=buildTileChoices(e,calculateDisplayPadding(e));let u
|
|
3560
|
+
;if(t.yes)u=c.filter(e=>"value"in e).map(e=>e.value);else try{u=await checkbox({message:"Select tiles to install",choices:c,pageSize:12,loop:!1,theme:{style:{renderSelectedChoices:()=>""},helpMode:"always"}})}catch(e){if(e instanceof ExitPromptError)return{cancelled:!0};throw n.error({choices:c},"Error while selecting tiles to install"),e}return 0===u.length&&r.info(`0 tiles selected for ${cyan(i)} manifest ${cyan(s)}`),{chosen:u}}async function installTiles({fsd:e,chosen:t,analysis:r,tesslClient:n,spinner:i,analytics:s,logger:o}){const{packageManager:a,manifestPath:c}=r;if(0===t.length)return{success:!0};i.start(`Installing tiles for ${cyan(a)} manifest ${cyan(c)}...`);const u=await updateTesslJsonDependencies(e,{add:t.map(({workspaceName:e,tileName:t,version:r})=>({workspaceName:e,tileName:t,newVersion:r}))});if(!u.success)return o.error({err:u.error},"Failed to update Tessl JSON dependencies"),i.fail(u.error),{success:!1,error:u.error};const l=await syncUsageSpecs(e.root,e,n)
|
|
3561
|
+
;if(!l.success)return o.error({err:l.error},"Failed to sync usage specs"),i.fail(stripIndents`${l.error}
|
|
3562
3562
|
|
|
3563
3563
|
Tiles added to tessl.json, but dependency sync failed.
|
|
3564
3564
|
Your agent won't have access to the newly installed usage specs until this is fixed.
|
|
3565
3565
|
|
|
3566
|
-
Once the issue is fixed, run: \`${getTesslCmdName()} registry sync\`.`),{success:!1,error:l.error};for(const e of t)s.tileInstall(e);const d=t.filter(e=>e.isUpdate).length,p=t.length-d;return i.succeed(`Installed ${cyan(p)} and updated ${cyan(d)} tiles for ${cyan(a)} manifest ${cyan(c)}`),{success:!0}}const registryUnpublishCommand=new Command$1({name:"registry-unpublish",summary:"Unpublish specs in the Tessl registry",allowArbitraryFlags:!1,
|
|
3567
|
-
;const
|
|
3566
|
+
Once the issue is fixed, run: \`${getTesslCmdName()} registry sync\`.`),{success:!1,error:l.error};for(const e of t)s.tileInstall(e);const d=t.filter(e=>e.isUpdate).length,p=t.length-d;return i.succeed(`Installed ${cyan(p)} and updated ${cyan(d)} tiles for ${cyan(a)} manifest ${cyan(c)}`),{success:!0}}const registryUnpublishCommand=new Command$1({name:"registry-unpublish",summary:"Unpublish specs in the Tessl registry",allowArbitraryFlags:!1,flags:{tile:{type:String,description:'The tile to unpublish, in the format "workspace/tile@version"'}},requiresLogin:!0,requiresConfig:!1,handler:async({monitoring:{logger:e},args:t,tesslClient:r})=>{const{tile:n}=t;if(!n)throw new ExpectedError('A --tile argument is required, in the format "workspace/tile@version"');const[i,s]=n.split("@");if(!i||!s)throw new ExpectedError('The tile must be in the format "workspace/tile@version"');const[o,a]=i.split("/");if(!o||!a)throw new ExpectedError('The spec must be in the format "workspace/tile"')
|
|
3567
|
+
;const c=createSpinner("Unpublishing"),u=await r.DELETE("/v1/tiles/{workspaceName}/{tileName}/versions/{version}",{params:{path:{workspaceName:o,tileName:a,version:s}}});return u.error?(e.error({err:u.error},"Failed to unpublish spec"),c.fail(apiErrToString(u.error)),FAILURE):(c.succeed(`Unpublished ${o}/${a}@${s}`),SUCCESS)}}),safeNormalizeFileUrl=(e,t)=>{const r=normalizeFileUrl(normalizeDenoExecPath(e));if("string"!=typeof r)throw new TypeError(`${t} must be a string or a file URL: ${r}.`);return r},normalizeDenoExecPath=e=>isDenoExecPath(e)?e.toString():e,isDenoExecPath=e=>"string"!=typeof e&&e&&Object.getPrototypeOf(e)===String.prototype,normalizeFileUrl=e=>e instanceof URL?fileURLToPath$1(e):e,normalizeParameters=(e,t=[],r={})=>{const n=safeNormalizeFileUrl(e,"First argument"),[i,s]=isPlainObject$2(t)?[[],t]:[t,r];if(!Array.isArray(i))throw new TypeError(`Second argument must be either an array of arguments or an options object: ${i}`)
|
|
3568
3568
|
;if(i.some(e=>"object"==typeof e&&null!==e))throw new TypeError(`Second argument must be an array of strings: ${i}`);const o=i.map(String),a=o.find(e=>e.includes("\0"));if(void 0!==a)throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${a}`);if(!isPlainObject$2(s))throw new TypeError(`Last argument must be an options object: ${s}`);return[n,o,s]},{toString:objectToString$1}=Object.prototype,isArrayBuffer=e=>"[object ArrayBuffer]"===objectToString$1.call(e),isUint8Array=e=>"[object Uint8Array]"===objectToString$1.call(e),bufferToUint8Array=e=>new Uint8Array(e.buffer,e.byteOffset,e.byteLength),textEncoder$1=new TextEncoder,stringToUint8Array=e=>textEncoder$1.encode(e),textDecoder=new TextDecoder,uint8ArrayToString=e=>textDecoder.decode(e),joinToString=(e,t)=>uint8ArraysToStrings(e,t).join(""),uint8ArraysToStrings=(e,t)=>{if("utf8"===t&&e.every(e=>"string"==typeof e))return e
|
|
3569
3569
|
;const r=new StringDecoder(t),n=e.map(e=>"string"==typeof e?stringToUint8Array(e):e).map(e=>r.write(e)),i=r.end();return""===i?n:[...n,i]},joinToUint8Array=e=>1===e.length&&isUint8Array(e[0])?e[0]:concatUint8Arrays(stringsToUint8Arrays(e)),stringsToUint8Arrays=e=>e.map(e=>"string"==typeof e?stringToUint8Array(e):e),concatUint8Arrays=e=>{const t=new Uint8Array(getJoinLength(e));let r=0;for(const n of e)t.set(n,r),r+=n.length;return t},getJoinLength=e=>{let t=0;for(const r of e)t+=r.length;return t},isTemplateString=e=>Array.isArray(e)&&Array.isArray(e.raw),parseTemplates=(e,t)=>{let r=[];for(const[n,i]of e.entries())r=parseTemplate({templates:e,expressions:t,tokens:r,index:n,template:i});if(0===r.length)throw new TypeError("Template script must not be empty");const[n,...i]=r;return[n,i,{}]},parseTemplate=({templates:e,expressions:t,tokens:r,index:n,template:i})=>{if(void 0===i)throw new TypeError(`Invalid backslash sequence: ${e.raw[n]}`)
|
|
3570
3570
|
;const{nextTokens:s,leadingWhitespaces:o,trailingWhitespaces:a}=splitByWhitespaces(i,e.raw[n]),c=concatTokens(r,s,o);if(n===t.length)return c;const u=t[n],l=Array.isArray(u)?u.map(e=>parseExpression(e)):[parseExpression(u)];return concatTokens(c,l,a)},splitByWhitespaces=(e,t)=>{if(0===t.length)return{nextTokens:[],leadingWhitespaces:!1,trailingWhitespaces:!1};const r=[];let n=0;const i=DELIMITERS.has(t[0]);for(let i=0,s=0;i<e.length;i+=1,s+=1){const o=t[s];if(DELIMITERS.has(o))n!==i&&r.push(e.slice(n,i)),n=i+1;else if("\\"===o){const e=t[s+1];"\n"===e?(i-=1,s+=1):"u"===e&&"{"===t[s+2]?s=t.indexOf("}",s+3):s+=ESCAPE_LENGTH[e]??1}}const s=n===e.length;return s||r.push(e.slice(n)),{nextTokens:r,leadingWhitespaces:i,trailingWhitespaces:s}},DELIMITERS=new Set([" ","\t","\r","\n"]),ESCAPE_LENGTH={x:3,u:5},concatTokens=(e,t,r)=>r||0===e.length||0===t.length?[...e,...t]:[...e.slice(0,-1),`${e.at(-1)}${t[0]}`,...t.slice(1)],parseExpression=e=>{const t=typeof e;if("string"===t)return e
|
|
@@ -3706,8 +3706,8 @@ const{stdout:r}=await execa("which",["tessl"],{encoding:"utf8"});t=r.trim(),e.de
|
|
|
3706
3706
|
description:"Inverse of --dry-run."}},requiresConfig:!1,handler:async({args:{"no-dry-run":e,"dry-run":t,target:r},monitoring:{logger:n}})=>{const i=!e&&_nullishCoalesce$g(t,()=>dryRunDefault),s=getCurrentVersion(),o=await getLatestVersion({logger:n,timeout:5e3}),a=r||o;if(s===a)return a===o?console.log(`You are already running the latest version (${chalk.green(s)}).`):console.log(`You are already running version ${chalk.green(s)}.`),Promise.resolve(SUCCESS);let c;console.log(`${i?"[DRY RUN] ":""}You are running ${chalk.red(s)}. ${r?`Updating to specified version ${chalk.green(a)}.`:`The latest version is ${chalk.green(o)}.`}`);try{const e=await detectInstallMethod(n);i?console.log("Command that would be executed:"):console.log(`Commencing update via ${chalk.cyan(e)}âĻ`),c=await performUpdate(e,i,a)}catch(e){c=`Error updating: ${e instanceof Error?e.message:String(e)}`}return console.log(chalk.dim(c)+"\n"),
|
|
3707
3707
|
i?console.log(`To perform the actual update, run ${chalk.blue("tessl update --no-dry-run")}.`):c.includes("Error")?(console.log(chalk.red("Update failed."),"Please try again or update manually by re-running the installation instructions:"),console.log("https://docs.tessl.io/introduction-to-tessl/installation")):console.log("Update to",chalk.green(a),"complete!"),Promise.resolve(SUCCESS)}}),versionCommand=new Command$1({name:"version",summary:"Print the current version",requiresConfig:!1,flags:{},handler:async({monitoring:{logger:e}})=>(await printVersion({logger:e}),SUCCESS)});async function resolveUser(e,t,r){if(t.text="Fetching user",validate$1(r)){const t=await e.GET("/v1/users/{userId}",{params:{path:{userId:r}}});if(t.error)return{success:!1,error:apiErrToString(t.error)};const n=t.data.data;return{success:!0,user:{id:n.id,username:n.attributes.username}}}const n=await e.GET("/v1/users",{params:{query:{"filter[username]":r,"page[size]":1}}});if(n.error)return{success:!1,
|
|
3708
3708
|
error:apiErrToString(n.error)};const i=n.data.data[0];return i?{success:!0,user:{id:i.id,username:i.attributes.username}}:{success:!1,error:`User not found: ${r}`}}async function resolveWorkspace(e,t,r){if(!r){t.text="Fetching workspaces";const r=await e.GET("/v1/workspaces");if(r.error)return{success:!1,error:apiErrToString(r.error)};const n=r.data.data.map(e=>{const t=e.attributes.name;return{name:t,value:{id:e.id,name:t}}});t.stop();return{success:!0,workspace:await select({message:"Select a workspace",choices:n})}}if(t.text="Fetching workspace",validate$1(r)){const t=await e.GET("/v1/workspaces/{workspaceId}",{params:{path:{workspaceId:r}}});if(t.error)return{success:!1,error:apiErrToString(t.error)};const n=t.data.data;return{success:!0,workspace:{id:n.id,name:n.attributes.name}}}const n=await e.GET("/v1/workspaces",{params:{query:{"filter[name]":r,"page[size]":1}}});if(n.error)return{success:!1,error:apiErrToString(n.error)};const i=n.data.data[0];return i?{success:!0,workspace:{
|
|
3709
|
-
id:i.id,name:i.attributes.name}}:{success:!1,error:`Workspace not found: ${r}`}}const roles=["viewer","member","owner"],roleChoices=roles.map(e=>({name:e,value:e})),addWorkspaceMemberCommand=new Command$1({name:"workspace-add-member",summary:"Add a member to a workspace",allowArbitraryFlags:!1,requiresLogin:!0,requiresConfig:!1,flags:{workspace:{type:String,description:"The name or ID of the workspace"},user:{type:String,description:"The
|
|
3710
|
-
;const o=s.user,a=await resolveWorkspace(r,i,t.workspace);if(!a.success)return e.error({args:t},a.error),i.fail(a.error),FAILURE;const c=a.workspace;if(!n)try{n=await select({message:"What role should the user have?",choices:roleChoices,default:"viewer"})}catch(e){if(e instanceof ExitPromptError)return SUCCESS;throw e}i.start(`Adding ${o.username} as ${n} to ${c.name}`);const u=await r.POST("/v1/workspaces/{workspaceId}/members",{params:{path:{workspaceId:c.id}},body:{memberId:o.id,role:n}});return u.error?(i.fail(apiErrToString(u.error)),e.error({err:u.error},"Failed to add member"),FAILURE):(e.info({workspaceId:c.id,workspaceName:c.name,role:n},"Added member to workspace"),i.succeed(`Added ${o.username} as ${n} to ${c.name}`),SUCCESS)}}),createWorkspaceCommand=new Command$1({name:"workspace-create",summary:"Create a new workspace",positionals:[{name:"name",description:"The name of the workspace"}],requiresConfig:!1,allowArbitraryFlags:!1,requiresLogin:!0,
|
|
3709
|
+
id:i.id,name:i.attributes.name}}:{success:!1,error:`Workspace not found: ${r}`}}const roles=["viewer","member","owner"],roleChoices=roles.map(e=>({name:e,value:e})),addWorkspaceMemberCommand=new Command$1({name:"workspace-add-member",summary:"Add a member to a workspace",allowArbitraryFlags:!1,requiresLogin:!0,requiresConfig:!1,flags:{workspace:{type:String,description:"The name or ID of the workspace"},user:{type:String,description:"The username or ID of the user to add"},role:{type:String,description:`The role of the user to add. Can be one of "${roles.join('", "')}"`}},handler:async({monitoring:{logger:e},args:t,tesslClient:r})=>{let n=t.role;if(n&&!roles.includes(n))throw new ExpectedError(`Invalid role: ${n}. Must be one of: ${roles.join(", ")}`);const i=createSpinner();if(!t.user)return i.fail(`Missing user argument: ${chalk.cyan("--user")} must be provided as a user ID or username`),FAILURE;const s=await resolveUser(r,i,t.user);if(!s.success)return e.error({args:t},s.error),
|
|
3710
|
+
i.fail(s.error),FAILURE;const o=s.user,a=await resolveWorkspace(r,i,t.workspace);if(!a.success)return e.error({args:t},a.error),i.fail(a.error),FAILURE;const c=a.workspace;if(!n)try{n=await select({message:"What role should the user have?",choices:roleChoices,default:"viewer"})}catch(e){if(e instanceof ExitPromptError)return SUCCESS;throw e}i.start(`Adding ${o.username} as ${n} to ${c.name}`);const u=await r.POST("/v1/workspaces/{workspaceId}/members",{params:{path:{workspaceId:c.id}},body:{memberId:o.id,role:n}});return u.error?(i.fail(apiErrToString(u.error)),e.error({err:u.error},"Failed to add member"),FAILURE):(e.info({workspaceId:c.id,workspaceName:c.name,role:n},"Added member to workspace"),i.succeed(`Added ${o.username} as ${n} to ${c.name}`),SUCCESS)}}),createWorkspaceCommand=new Command$1({name:"workspace-create",summary:"Create a new workspace",positionals:[{name:"name",description:"The name of the workspace"}],requiresConfig:!1,allowArbitraryFlags:!1,requiresLogin:!0,
|
|
3711
3711
|
handler:async({positionals:{name:e},tesslClient:t})=>{if(!e)return process.stderr.write(`${styleText("red",figures.cross)} A name is required as the first argument\n`),FAILURE;const r=createSpinner("Creating workspace"),n=await t.POST("/v1/workspaces",{body:{name:e}});return n.error?(r.fail(apiErrToString(n.error)),FAILURE):(r.succeed(`Created workspace ${e} (${n.data.data.id})`),SUCCESS)}}),deleteWorkspaceCommand=new Command$1({name:"workspace-delete",summary:"Delete a workspace",positionals:[{name:"workspace",description:"The name or ID of the workspace"}],allowArbitraryFlags:!1,requiresConfig:!1,requiresLogin:!0,handler:async({positionals:e,monitoring:{logger:t},tesslClient:r})=>{const n=ora({hideCursor:!1,discardStdin:!1}).start("Deleting workspace"),i=await resolveWorkspace(r,n,e.workspace);if(!i.success)return t.error({positionals:e},i.error),n.fail(i.error),FAILURE;const s=i.workspace;n.start(`Deleting workspace ${s.name}`);const o=await r.DELETE("/v1/workspaces/{workspaceId}",{
|
|
3712
3712
|
params:{path:{workspaceId:s.id}}});return o.error?(n.fail(apiErrToString(o.error)),FAILURE):(n.succeed(`Deleted workspace ${s.name}`),SUCCESS)}}),listWorkspaceMembersCommand=new Command$1({name:"workspace-list-members",summary:"List all members of a workspace",allowArbitraryFlags:!1,requiresLogin:!0,requiresConfig:!1,positionals:[{name:"workspace",description:"The name or ID of the workspace"}],handler:async({monitoring:{logger:e},positionals:t,tesslClient:r})=>{const n=createSpinner(),i=await resolveWorkspace(r,n,t.workspace);if(!i.success)return e.error({positionals:t},i.error),n.fail(i.error),FAILURE;const s=i.workspace;n.start("Fetching workspace members");const o=await r.GET("/v1/workspaces/{workspaceId}/members",{params:{path:{workspaceId:s.id}}});if(o.error)return e.error({err:o.error},"Failed to fetch workspace members"),n.fail(apiErrToString(o.error)),FAILURE;n.stop();const a=[["Username","Role","ID"],...o.data.data.map(e=>[e.attributes.username,e.attributes.role,e.id])]
|
|
3713
3713
|
;return process.stdout.write(srcExports.table(a)),SUCCESS}}),listWorkspacesCommand=new Command$1({name:"workspace-list",summary:"List all workspaces that you are a member of",allowArbitraryFlags:!1,requiresConfig:!1,requiresLogin:!0,handler:async({tesslClient:e})=>{const t=createSpinner("Fetching workspaces"),r=await e.GET("/v1/workspaces");if(r.error)return t.fail(apiErrToString(r.error)),FAILURE;t.stop();const n=[["Name","ID"],...r.data.data.map(e=>[e.attributes.name,e.id])];return process.stdout.write(srcExports.table(n)),SUCCESS}}),removeWorkspaceMemberCommand=new Command$1({name:"workspace-remove-member",summary:"Remove a user from a workspace",allowArbitraryFlags:!1,requiresLogin:!0,requiresConfig:!1,flags:{workspace:{type:String,description:"The name or ID of the workspace"},user:{type:String,description:"The name or ID of the user to remove"}},handler:async({monitoring:{logger:e},args:t,tesslClient:r})=>{const n=createSpinner()
|
|
@@ -3718,8 +3718,8 @@ summary:t||`Run the ${e} tool`},e)),[observeCommand].map(({name:e,summary:t})=>j
|
|
|
3718
3718
|
children:[[initCommand].map(({name:e,summary:t})=>jsxRuntimeExports.jsx(CommandRow,{command:e,summary:t},e)),Object.entries(structuredCommands).filter(([e])=>!["registry","workspace"].includes(e)).map(([e,t])=>jsxRuntimeExports.jsx(Box,{flexDirection:"column",children:Object.entries(t).map(([t,r])=>jsxRuntimeExports.jsx(CommandRow,{command:`${e} ${t}`,summary:r.summary},`${e} ${t}`))},e))]})]})})}function Header$2({children:e}){return jsxRuntimeExports.jsx(Text,{bold:!0,children:e})}function Section$1({title:e,children:t,...r}){return jsxRuntimeExports.jsxs(Box,{flexDirection:"column",...r,children:[jsxRuntimeExports.jsx(Header$2,{children:e}),jsxRuntimeExports.jsx(Box,{flexDirection:"column",children:t})]})}function QuickstartSection({frameworkType:e}){return"full"===e?jsxRuntimeExports.jsx(Section$1,{title:"Quickstart Guide",children:jsxRuntimeExports.jsxs(Box,{flexDirection:"column",gap:1,children:[jsxRuntimeExports.jsxs(Text,{
|
|
3719
3719
|
children:["First, run ",jsxRuntimeExports.jsx(CommandText,{children:"tessl login"})," to authenticate and ",jsxRuntimeExports.jsx(CommandText,{children:"tessl init"})," to add Tessl-related context to your project and integrate it with AGENTS.md and optionally set up your agent's rules file and the Tessl MCP server."]}),jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{bold:!0,children:"đĄ Tip:"})," When running"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl init"})," you can configure your agent to use Tessl's MCP server, and ask it to execute the following commands:"]}),jsxRuntimeExports.jsx(Text,{children:"Now you can use Tessl's spec-driven development tools in your project. Here's a simple flow to get started:"}),jsxRuntimeExports.jsxs(Box,{flexDirection:"column",children:[jsxRuntimeExports.jsxs(Text,{children:["1. Add documentation for your open-source dependencies with"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry sync"})]
|
|
3720
3720
|
}),jsxRuntimeExports.jsxs(Text,{children:["2. Create a spec to describe your project with"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl create"})]}),jsxRuntimeExports.jsxs(Text,{children:["3. Generate code from your spec with"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl build"})]}),jsxRuntimeExports.jsxs(Text,{children:["4. Iterate on your spec with ",jsxRuntimeExports.jsx(CommandText,{children:"tessl edit"}),", and rebuild your code with"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl build"})]})]}),jsxRuntimeExports.jsxs(Text,{children:["Check out the commands below for more details and inspiration, along with documentation at"," ",jsxRuntimeExports.jsx(Text,{bold:!0,underline:!0,children:"https://docs.tessl.io/"})]})]})}):jsxRuntimeExports.jsx(Section$1,{title:"Quickstart Guide",children:jsxRuntimeExports.jsxs(Box,{flexDirection:"column",gap:1,children:[jsxRuntimeExports.jsxs(Text,{children:[jsxRuntimeExports.jsx(Text,{bold:!0,children:"Usage specs"
|
|
3721
|
-
})," are downloadable files that provide coding agents with documentation for open-source libraries; see"," ",jsxRuntimeExports.jsx(Text,{bold:!0,underline:!0,children:"https://tessl.io/registry"})," ","to learn more."]}),jsxRuntimeExports.jsxs(Text,{children:["To download usage specs for your project, first run"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl init"}),", which installs instructions into your project's agent configuration files (i.e. AGENTS.md), and optionally configures your preferred coding agent to use Tessl's MCP server."]}),jsxRuntimeExports.jsxs(Text,{children:["Then, you or your agent can use"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry search"}),","," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry install"}),"
|
|
3722
|
-
children:["See below for more information on these and other commands, and visit"," ",jsxRuntimeExports.jsx(Text,{bold:!0,underline:!0,children:"https://docs.tessl.io/"})," ","for full documentation."]})]})})}const helpCommand=new Command$1({name:"help",summary:"Print information on how to use this CLI",requiresConfig:!1,handler:async({isAuthenticated:e,projectDir:t})=>{const r=getExistingFrameworkType(t);return render(jsxRuntimeExports.jsx(GlobalHelp,{isLoggedIn:e,frameworkType:r})),Promise.resolve(SUCCESS)}});function _nullishCoalesce$f(e,t){return null!=e?e:t()}const listCommand=new Command$1({name:"list",summary:"List details of the files associated with specs, whether code implementations or tests",positionals:[{name:"spec",description:"The path of the spec we want to list files for. If not provided, lists files for all specs in the project"}],flags:{tests:{type:[String],
|
|
3721
|
+
})," are downloadable files that provide coding agents with documentation for open-source libraries; see"," ",jsxRuntimeExports.jsx(Text,{bold:!0,underline:!0,children:"https://tessl.io/registry"})," ","to learn more."]}),jsxRuntimeExports.jsxs(Text,{children:["To download usage specs for your project, first run"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl init"}),", which installs instructions into your project's agent configuration files (i.e. AGENTS.md), and optionally configures your preferred coding agent to use Tessl's MCP server."]}),jsxRuntimeExports.jsxs(Text,{children:["Then, you or your agent can use"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry search"}),","," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry install"}),","," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry uninstall"})," and"," ",jsxRuntimeExports.jsx(CommandText,{children:"tessl registry sync"
|
|
3722
|
+
})," to find, install, uninstall and upgrade usage specs in your project."]}),jsxRuntimeExports.jsxs(Text,{children:["See below for more information on these and other commands, and visit"," ",jsxRuntimeExports.jsx(Text,{bold:!0,underline:!0,children:"https://docs.tessl.io/"})," ","for full documentation."]})]})})}const helpCommand=new Command$1({name:"help",summary:"Print information on how to use this CLI",requiresConfig:!1,handler:async({isAuthenticated:e,projectDir:t})=>{const r=getExistingFrameworkType(t);return render(jsxRuntimeExports.jsx(GlobalHelp,{isLoggedIn:e,frameworkType:r})),Promise.resolve(SUCCESS)}});function _nullishCoalesce$f(e,t){return null!=e?e:t()}const listCommand=new Command$1({name:"list",summary:"List details of the files associated with specs, whether code implementations or tests",positionals:[{name:"spec",description:"The path of the spec we want to list files for. If not provided, lists files for all specs in the project"}],flags:{tests:{type:[String],
|
|
3723
3723
|
description:'Select which kind of test links to list: "none" (default) shows no test files, "draft" shows only draft test files, "locked" shows only locked test files, and "all" shows all kinds of test files',hidden:!1,defaultValue:["all"],availableValues:["none","draft","locked","all"]},code:{type:String,description:'Select which kind code link to show: "none" shows no code links, "generate" shows only `@generate` links, "describe" shows only `@describe` links, and "all" shows both kinds of links',hidden:!1,defaultValue:"all",availableValues:["none","generate","describe","all"]},"include-specs":{type:Boolean,description:"Select whether to include spec files themselves. By default, shows spec files only when a specific spec file is not provided",hidden:!1},"include-missing":{type:Boolean,description:"Include files which have not been generated yet",hidden:!1}},allowArbitraryFlags:!0,requiresLogin:!0,
|
|
3724
3724
|
handler:async({positionals:{spec:e},projectDir:t,args:{tests:r,code:n,"include-specs":i,"include-missing":s},flagConfig:o})=>{const a=await findFiles({projectDir:t,spec:e,tests:_nullishCoalesce$f(r,()=>o.tests.defaultValue),code:_nullishCoalesce$f(n,()=>o.code.defaultValue),includeMissing:s}),c=!!i||!i&&!e;return Object.entries(a).forEach(([e,{tests:t,code:r}])=>{c&&console.log(e),t.forEach(e=>console.log(e)),r.forEach(e=>console.log(e))}),SUCCESS}});function createTestsFilter(e){if(e.includes("none")&&e.length>1)throw new Error('Cannot specify "none" with other test types');if(e.includes("all")&&e.length>1)throw new Error('Cannot specify "all" with other test types');if(0===e.length)throw new Error("At least one test type must be specified");return t=>"all"===e[0]||"none"!==e[0]&&(t.locked?e.includes("locked"):e.includes("draft"))}const findFiles=async({projectDir:e,spec:t,tests:r,code:n,includeMissing:i})=>{
|
|
3725
3725
|
const s=openFsd(e),o=t?[t]:await listSpecs(s),a={},c=createTestsFilter(r),u=i?e=>!0:t=>existsSync$1(join$1(e,t)),l=codeExtractor(n);for(const t of o)a[t]={tests:[],code:[]},a[t].tests=(await specLinkedPaths(s,t,[findTests],e)).filter(c).map(e=>e.path).filter(u),a[t].code=(await specLinkedPaths(s,t,l,e)).filter(u);return a};function codeExtractor(e){switch(e){case"all":return[findGeneratePaths,findDescribePaths];case"generate":return[findGeneratePaths];case"describe":return[findDescribePaths];case"none":return[];default:assertUnreachable(e)}}const LATEST_PROTOCOL_VERSION$1="2025-06-18",SUPPORTED_PROTOCOL_VERSIONS$1=[LATEST_PROTOCOL_VERSION$1,"2025-03-26","2024-11-05","2024-10-07"],JSONRPC_VERSION$1="2.0",ProgressTokenSchema$1=unionType$1([stringType$1(),numberType$1().int()]),CursorSchema$1=stringType$1(),RequestMetaSchema$1=objectType$1({progressToken:optionalType$1(ProgressTokenSchema$1)}).passthrough(),BaseRequestParamsSchema$1=objectType$1({_meta:optionalType$1(RequestMetaSchema$1)
|
|
@@ -4712,9 +4712,15 @@ function createAuthenticatedToolWrapper(e,t){return async(r,n)=>await isAuthed(t
|
|
|
4712
4712
|
return this.mcpServerStartTime?Date.now()-this.mcpServerStartTime:null}static reset(){this.mcpServerRunId=null,this.mcpServerStartTime=null,this.shutdownInProgress=!1,this.terminatorInstance=null}static async shutdownServer(e=SUCCESS,t="MCP server shutdown requested"){const r=this.getTerminator();return r?r.shutdown(e,t):Promise.resolve()}}McpServerManager.__initStatic(),McpServerManager.__initStatic2(),McpServerManager.__initStatic3(),McpServerManager.__initStatic4();const POST_END_EVENT_TIMEOUT=1e3;async function trackMcpServerStart(e,t){McpServerManager.startRun(t),e.analytics.mcpServerStart(),await SessionManager.setMcpParentRunId(t)}async function trackMcpServerEnd(e,t=!0,r=0,n){const i=McpServerManager.getRunId(),s=McpServerManager.getDurationMs();null!==i&&null!==s?e.analytics.mcpServerEnd({success:t,exitCode:r,durationMs:s,...n?{error:n}:{}}):e.logger.error({runId:i,durationMs:s},"Expected runId and durationMs to be defined while shutting down MCP server");try{
|
|
4713
4713
|
await new Promise(e=>setTimeout(e,POST_END_EVENT_TIMEOUT)),await e.shutdown()}catch(t){e.logger.error({err:t},"Failed to retry flushing analytics events")}McpServerManager.reset()}function registerMcpServerShutdownHandlers(e){const t=new Terminator({logger:e.logger,shutdownTimeout:2*POST_END_EVENT_TIMEOUT});return McpServerManager.setTerminator(t),process.on("exit",()=>{McpServerManager.getRunId()&&!McpServerManager.isShuttingDown()&&trackMcpServerEnd(e)}),t.addHandler(async()=>{McpServerManager.getRunId()?(McpServerManager.markShutdownInProgress(),e.logger.info({},"Terminator executing shutdown handler, tracking MCP server end"),await trackMcpServerEnd(e,!0,SUCCESS),await new Promise(e=>setTimeout(e,POST_END_EVENT_TIMEOUT))):e.logger.info({},"Terminator executing shutdown handler, no active MCP server")}),t.addHandler(async()=>{McpServerManager.getRunId()&&!McpServerManager.isShuttingDown()&&(McpServerManager.markShutdownInProgress(),
|
|
4714
4714
|
e.logger.info({},"Tracking MCP server end due to error"),await trackMcpServerEnd(e,!1,FAILURE))}),t.registerShutdownHandlers(),t}const mcpCommand=new Command$1({name:"mcp",summary:"Start the MCP server",requiresConfig:!1,handler:async({monitoring:e,projectConfig:t,projectDir:r,globalConfigDir:n,env:i})=>{const{logger:s}=e;try{const o=e.analytics.getRunId();o?await trackMcpServerStart(e,o):s.error({},"No active runId while trying to track server start");const a=registerMcpServerShutdownHandlers(e),c=new Promise(e=>{a.addHandler(async t=>new Promise(r=>{queueMicrotask(()=>{e(t),r()})}))});return await startMcpServer({monitoring:e,projectConfig:t,projectDir:r,globalConfigDir:n,env:i}),c}catch(t){const r=t.message;s.error({err:t},"Failed to start MCP server");const n=new Terminator({logger:s,shutdownTimeout:1e3});return n.addHandler(async()=>{try{await trackMcpServerEnd(e,!1,FAILURE,r)}catch(e){s.error({err:e},"Failed to track MCP server end event")}try{await e.shutdown()}catch(e){
|
|
4715
|
-
s.error({err:e},"Failed to flush analytics events")}}),await n.shutdown(FAILURE,`Failed to start MCP server: ${r}`),FAILURE}}})
|
|
4716
|
-
|
|
4717
|
-
|
|
4715
|
+
s.error({err:e},"Failed to flush analytics events")}}),await n.shutdown(FAILURE,`Failed to start MCP server: ${r}`),FAILURE}}}),uninstallCommand=new Command$1({name:"registry-uninstall",summary:"Uninstall usage specs from your project",positionals:[{name:"name",description:'The name of the usage spec to uninstall (e.g., "workspace/tile")'}],allowArbitraryFlags:!1,requiresLogin:!1,requiresConfig:!1,handler:async({positionals:{name:e},monitoring:{analytics:t,logger:r},projectDir:n,isInteractive:i,tesslClient:s,isAuthenticated:o,monitoring:a})=>{const{isInitialized:c}=await ensureInit({targetDir:n,isAuthenticated:o,isInteractive:i,monitoring:a,args:{"no-mcp":!0}},"Usage specs require Tessl to be initialized. Would you like to initialize Tessl now?");if(!c)return SUCCESS;const u=openFsd(n);if(!e)return r.error({name:e},"The name argument is required"),FAILURE;const l=createSpinner("Uninstalling usage spec"),[d,p]=e.split("/");if(!d||!p)return r.error({name:e
|
|
4716
|
+
},'The name argument must be in the format "workspace/tile"'),l.fail('The name argument must be in the format "workspace/tile"'),FAILURE;const h=`${d}/${p}`,A=await updateTesslJsonDependencies(u,{remove:[h]});if(!A.success)return r.error({name:e,err:A.error},"Failed to update Tessl JSON dependencies"),l.fail(A.error),FAILURE;const f=await syncUsageSpecs(n,u,s);return f.success?(r.info({name:e},"Usage spec uninstalled"),l.succeed(`Uninstalled ${h}`),t.tileUninstall({workspaceName:d,tileName:p}),SUCCESS):(r.error({name:e,err:f.error},"Failed to sync usage specs"),l.fail(stripIndents`${f.error}
|
|
4717
|
+
|
|
4718
|
+
${h} removed from tessl.json, but dependency sync failed.
|
|
4719
|
+
Your agent may still have access to the removed usage spec until this is fixed.
|
|
4720
|
+
|
|
4721
|
+
Once the issue is fixed, run: \`${getTesslCmdName()} registry install\`.`),FAILURE)}});function conditionalLogger(e,t){const r=`LOG_LEVEL_${t}`,n=process.env[r],i={trace:0,debug:1,info:2,warn:3,error:4};let s;if(null==n)s=1/0;else{const r=n.toLowerCase();r in i?s=i[r]:(s=i.info,e.warn({},`Invalid log level "${n}" for LOG_LEVEL_${t}. Defaulting to "info"`))}return function e(t){return{trace:(e,r)=>{i.trace>=s&&t.trace(e,r)},debug:(e,r)=>{i.debug>=s&&t.debug(e,r)},info:(e,r)=>{i.info>=s&&t.info(e,r)},warn:(e,r)=>{i.warn>=s&&t.warn(e,r)},error:(e,r)=>{i.error>=s&&t.error(e,r)},child:r=>e(t.child(r))}}(e)}const fsdReadTextRequestSchema=objectType$1({type:literalType$1("fsd.readText"),path:stringType$1().nonempty().describe("Path to the file to read")}),fsdWriteTextRequestSchema=objectType$1({type:literalType$1("fsd.writeText"),path:stringType$1().nonempty().describe("Path to the file to write"),content:stringType$1().describe("Content to write to the file")
|
|
4722
|
+
}),fsdGlobRequestSchema=objectType$1({type:literalType$1("fsd.glob"),pattern:stringType$1().nonempty().describe("Glob pattern to match files")}),fsdDestroyRequestSchema=objectType$1({type:literalType$1("fsd.destroy"),path:stringType$1().nonempty().describe("Path to the file or directory to delete")});discriminatedUnionType$1("type",[fsdReadTextRequestSchema,fsdWriteTextRequestSchema,fsdGlobRequestSchema,fsdDestroyRequestSchema]);const fsdReadTextResponseSchema=stringType$1().optional(),fsdGlobResponseSchema=arrayType$1(stringType$1()),fsdVoidResponseSchema=voidType();function _nullishCoalesce$9(e,t){return null!=e?e:t()}function isResult(e){return!(!e||"object"!=typeof e)&&"err"in e!="content"in e}unionType$1([fsdReadTextResponseSchema,fsdGlobResponseSchema,fsdVoidResponseSchema]);const tryTo=async e=>{try{return{content:_nullishCoalesce$9(await e(),()=>null)}}catch(e){return{err:serializeError(e)}}},utilExecRequestSchema=objectType$1({type:literalType$1("util.exec"),
|
|
4723
|
+
command:stringType$1().nonempty().describe("Name of the command to execute"),args:arrayType$1(stringType$1()).describe("Arguments to pass to the command"),cwd:stringType$1().optional().describe("Working directory for execution"),timeoutSecs:numberType$1().optional().describe("Timeout in seconds"),env:recordType$1(stringType$1()).optional().describe("Environment variables for execution")}),utilExecResponseSchema=objectType$1({type:literalType$1("util.exec.response"),command:stringType$1().nonempty().describe("Name of the executed command"),exitCode:numberType$1().describe("Exit code of the command execution"),stdout:stringType$1().optional().describe("Standard output from the command"),stderr:stringType$1().optional().describe("Standard error from the command"),error:unknownType$1().optional().describe("Error information if execution failed")});function isDisconnectMessage(e){
|
|
4718
4724
|
return"object"==typeof e&&null!==e&&"type"in e&&"disconnect"===e.type&&"reason"in e&&("finished"===e.reason||"error"===e.reason)}function isTunnelRequest(e){return"object"==typeof e&&null!==e&&"type"in e&&"request"===e.type&&"requestId"in e&&"request"in e}function isTunnelResponse(e){return"object"==typeof e&&null!==e&&"type"in e&&"response"===e.type&&"requestId"in e&&"result"in e}function isHandshakeResponse(e){return!!isTunnelResponse(e)&&(!!isResult(e.result)&&("err"in e.result||"content"in e.result&&"object"==typeof e.result.content&&"type"in e.result.content&&"handshake.result"===e.result.content.type))}function isHandshakeRequest(e){return isTunnelRequest(e)&&"handshake"===e.request.type&&"version"in e.request&&"number"==typeof e.request.version}function isToolRunRequest(e){
|
|
4719
4725
|
return e.request&&"type"in e.request&&"tool.run"===e.request.type&&"name"in e.request&&"string"==typeof e.request.name&&"params"in e.request&&"object"==typeof e.request.params&&null!==e.request.params&&"config"in e.request&&"object"==typeof e.request.config&&null!==e.request.config&&"projectDir"in e.request&&"string"==typeof e.request.projectDir}function isToolLookupRequest(e){return e.request&&"type"in e.request&&"tool.lookup"===e.request.type&&"name"in e.request&&"string"==typeof e.request.name}function isUtilExecRequest(e){if(!e.request||"object"!=typeof e.request)return!1;return utilExecRequestSchema.safeParse(e.request).success}function isEmitLogline(e){return"object"==typeof e&&null!==e&&"type"in e&&"log"===e.type&&"level"in e&&"message"in e&&"data"in e&&"string"==typeof e.message&&["trace","debug","info","warn","error"].includes(e.level)}function isEmitManagementEvent(e){
|
|
4720
4726
|
return"object"==typeof e&&null!==e&&"type"in e&&"managementEvent"===e.type&&"event"in e&&"object"==typeof e.event&&null!==e.event&&"id"in e.event&&"string"==typeof e.event.id}function isFsdReadTextRequest(e){if(!e.request||"object"!=typeof e.request)return!1;return fsdReadTextRequestSchema.safeParse(e.request).success}function isFsdWriteTextRequest(e){if(!e.request||"object"!=typeof e.request)return!1;return fsdWriteTextRequestSchema.safeParse(e.request).success}function isFsdGlobRequest(e){if(!e.request||"object"!=typeof e.request)return!1;return fsdGlobRequestSchema.safeParse(e.request).success}function isFsdDestroyRequest(e){if(!e.request||"object"!=typeof e.request)return!1;return fsdDestroyRequestSchema.safeParse(e.request).success}function validateMessageType(e){if(!e||"object"!=typeof e||!("type"in e))throw new Error("Invalid message: missing type field");const t=e.type
|
|
@@ -4774,8 +4780,8 @@ projectConfig:await r.list(),projectDir:n,globalConfigDir:i,isInteractive:!1,cal
|
|
|
4774
4780
|
;if("error"in r)return e.error({err:r.error},"Failed to fetch logs"),console.error("Error fetching logs:",r.error),FAILURE;const s=r.data.data;if(0===s.length){process.stdout.write("."),await sleep$2(1e3);continue}console.log();for(const e of s){const{createdAt:t,chunk:r}=e;console.log(`[${t}]`),console.log(r)}const o=_optionalChain$4([s,"access",e=>e[s.length-1],"optionalAccess",e=>e.createdAt]);o&&(i=o),await sleep$2(400)}}});function _nullishCoalesce$2(e,t){return null!=e?e:t()}
|
|
4775
4781
|
const invocationCommand=e=>`tessl run ${e} --name "Tess"`,basicToolTemplate=e=>`\nimport { type CustomTool } from "tessl-alpha";\nimport { z } from "zod";\n\n\nexport const paramsSchema = z.object({\n name: z.string().describe('The name of the person you would like to instruct').optional()\n})\n\nconst myTool: CustomTool<typeof paramsSchema> = async ({ rc, fsd, tools, params }) => {\n rc.reporter.message(\`Implement your own tool here\${params.name ? \`, \${params.name}\` : ''}\`);\n\n // Call LLM:\n // const response = await tools.script('System Prompt').user('User Prompt').text();\n\n // Return an exit code:\n return rc.reporter.success();\n};\n\n// The description is optional, you can delete it if you wish.\nexport const description = "You can add some explanatory text here. It will be shown in \`tessl list.\`."\n\n// This file must default export the tool function, which is of type CustomTool<typeof paramsSchema>\nexport default myTool;\n\n// Invoke with:\n// ${invocationCommand(e)}\n`,addToolCommand=new Command$1({
|
|
4776
4782
|
name:"add-tool",summary:"Add a new custom tool",flags:{name:{type:String,short:"n",description:"The name of the tool"}},handler:async({args:{name:e},projectDir:t})=>{const r=DEFAULT_TESSL_DIRS.customToolDirectory;fs$8.existsSync(r)||fs$8.mkdirSync(r,{recursive:!0});const n=t=>`${_nullishCoalesce$2(e,()=>"custom")}${t?`-${t}`:""}${CUSTOM_TOOL_FILE_EXTENSION}`;let i=0;for(;fs$8.existsSync(path__default.join(r,n(i)));)i++;const s=n(i),o=s.replace(CUSTOM_TOOL_FILE_EXTENSION,""),a=path__default.join(r,s);return fs$8.writeFileSync(a,basicToolTemplate(o)),render(jsxRuntimeExports.jsx(ToolTemplateAdded,{name:o,base:t,path:a})),Promise.resolve(SUCCESS)}});function ToolTemplateAdded({name:e,base:t,path:r}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Text,{children:"Tool added!"}),jsxRuntimeExports.jsx(FilesCreated,{base:t,filepaths:[r]}),jsxRuntimeExports.jsxs(Text,{children:["âšī¸ ",jsxRuntimeExports.jsx(Text,{dimColor:!0,children:"Invoke with:"
|
|
4777
|
-
})," ",invocationCommand(e)]})]})}const hiddenCommands={[cluckCommand.name]:cluckCommand,[tailCommand.name]:tailCommand,[tokenCommand.name]:tokenCommand,[mcpCommand.name]:mcpCommand},standaloneGeneralCommands={[helpCommand.name]:helpCommand,[initCommand.name]:initCommand,[versionCommand.name]:versionCommand,[updateCommand.name]:updateCommand,[listCommand.name]:listCommand,[loginCommand.name]:loginCommand,[logoutCommand.name]:logoutCommand,[whoamiCommand.name]:whoamiCommand,[feedbackCommand.name]:feedbackCommand,[observeCommand.name]:observeCommand},standaloneToolCommands={[runCommand.name]:runCommand},standaloneCommands={...standaloneGeneralCommands,...standaloneToolCommands},hiddenStructuredCommands={add:{tool:addToolCommand}},structuredCommands={setup:{agent:setupAgentCommand,"project-info":setupProjectInfoCommand,framework:setupFrameworkCommand},registry:{install:installCommand,list:registryListCommand,search:searchCommand,sync:syncCommand,
|
|
4778
|
-
archive:registryArchiveCommand,unpublish:registryUnpublishCommand},workspace:{list:listWorkspacesCommand,create:createWorkspaceCommand,delete:deleteWorkspaceCommand,"list-members":listWorkspaceMembersCommand,"add-member":addWorkspaceMemberCommand,"remove-member":removeWorkspaceMemberCommand},config:{list:listConfigCommand,get:getConfigCommand,set:setConfigCommand,unset:unsetConfigCommand}};function isValidActionName(e){return e in structuredCommands||e in hiddenStructuredCommands}function isValidResourceName(e,t){return e in structuredCommands?t in structuredCommands[e]:e in hiddenStructuredCommands&&t in hiddenStructuredCommands[e]}function isValidCommandName(e,t){return!(!isValidStandaloneCommandName(e)&&!isBuiltInToolName(e))||isValidActionName(e)&&void 0!==t&&isValidResourceName(e,t)}function isValidStandaloneCommandName(e){return(e in standaloneCommands||e in hiddenCommands)&&"setup"!==e}function getCommand(e,t){
|
|
4783
|
+
})," ",invocationCommand(e)]})]})}const hiddenCommands={[cluckCommand.name]:cluckCommand,[tailCommand.name]:tailCommand,[tokenCommand.name]:tokenCommand,[mcpCommand.name]:mcpCommand},standaloneGeneralCommands={[helpCommand.name]:helpCommand,[initCommand.name]:initCommand,[versionCommand.name]:versionCommand,[updateCommand.name]:updateCommand,[listCommand.name]:listCommand,[loginCommand.name]:loginCommand,[logoutCommand.name]:logoutCommand,[whoamiCommand.name]:whoamiCommand,[feedbackCommand.name]:feedbackCommand,[observeCommand.name]:observeCommand},standaloneToolCommands={[runCommand.name]:runCommand},standaloneCommands={...standaloneGeneralCommands,...standaloneToolCommands},hiddenStructuredCommands={add:{tool:addToolCommand}},structuredCommands={setup:{agent:setupAgentCommand,"project-info":setupProjectInfoCommand,framework:setupFrameworkCommand},registry:{install:installCommand,uninstall:uninstallCommand,list:registryListCommand,search:searchCommand,sync:syncCommand,
|
|
4784
|
+
publish:registryPublishCommand,archive:registryArchiveCommand,unpublish:registryUnpublishCommand},workspace:{list:listWorkspacesCommand,create:createWorkspaceCommand,delete:deleteWorkspaceCommand,"list-members":listWorkspaceMembersCommand,"add-member":addWorkspaceMemberCommand,"remove-member":removeWorkspaceMemberCommand},config:{list:listConfigCommand,get:getConfigCommand,set:setConfigCommand,unset:unsetConfigCommand}};function isValidActionName(e){return e in structuredCommands||e in hiddenStructuredCommands}function isValidResourceName(e,t){return e in structuredCommands?t in structuredCommands[e]:e in hiddenStructuredCommands&&t in hiddenStructuredCommands[e]}function isValidCommandName(e,t){return!(!isValidStandaloneCommandName(e)&&!isBuiltInToolName(e))||isValidActionName(e)&&void 0!==t&&isValidResourceName(e,t)}function isValidStandaloneCommandName(e){return(e in standaloneCommands||e in hiddenCommands)&&"setup"!==e}function getCommand(e,t){
|
|
4779
4785
|
if(isBuiltInToolName(e))return standaloneToolCommands[runCommand.name];if(e in hiddenStructuredCommands&&t&&t in hiddenStructuredCommands[e])return hiddenStructuredCommands[e][t];if(e in structuredCommands&&t)return structuredCommands[e][t];if(e in hiddenCommands)return hiddenCommands[e];if(e in standaloneCommands)return standaloneCommands[e];throw new ExpectedError(`${[e,t].filter(e=>void 0!==e).join(" ")} is not a valid command`)}function isBuiltInToolName(e){return builtInTools().some(t=>t.name===e)}const PROJECT_METADATA_TIMESTAMP_KEY="project-metadata-updated-at",PROJECT_ID_KEY="project-id";function generateProjectId(e,t){const r=`${path__default.normalize(e)}:${t}`,n=createHash("sha256").update(r).digest("hex");return[n.substring(0,8),n.substring(8,12),n.substring(12,16),n.substring(16,20),n.substring(20,32)].join("-")}async function getCurrentProjectId(e,t){return await e.readOrWriteText(PROJECT_ID_KEY,()=>generateProjectId(process.cwd(),t))}
|
|
4780
4786
|
async function checkAndUpdateProjectMetadata({monitoring:{logger:e,analytics:t},projectCache:r,projectConfig:n,projectDir:i}){const s=(new Date).getTime(),o=await r.readText(PROJECT_METADATA_TIMESTAMP_KEY);let a=!1;if(void 0!==o){e.debug({},"Checking session data for last project metadata update timestamp...");const t=new Date(o).getTime();s-t>864e5?(e.debug({lastUpdateTime:t},"Last update was over 24 hours ago, commencing capture..."),a=!0):e.debug({lastUpdateTime:t},"Skipping metadata capture, last update was within the last 24 hours")}else e.debug({},"No project metadata timestamp entry found in session data, commencing capture..."),a=!0;if(a){const o=new Date(s).toISOString();await r.writeText(PROJECT_METADATA_TIMESTAMP_KEY,o);const a=await hasTesslJson(i);let c=null;if(n)try{c=await n.list()}catch(t){e.debug({err:t},"Encountered an error while calling projectConfig.list(), some project metadata will be missing.")}t.trackProject({isInitialized:a,languages:[],
|
|
4781
4787
|
framework:getExistingFrameworkType(i),config:c,firstSeenAt:(new Date).toISOString(),lastEditedAt:(new Date).toISOString()})}}function Header$1({children:e}){return jsxRuntimeExports.jsx(Text,{bold:!0,children:e})}function ActionHelp({action:e}){const t=structuredCommands[e];return t?jsxRuntimeExports.jsxs(Box,{flexDirection:"column",gap:1,width:DEFAULT_WRAP_WIDTH,minWidth:DEFAULT_WRAP_WIDTH,children:[jsxRuntimeExports.jsx(Header$1,{children:`${e} commands`}),jsxRuntimeExports.jsx(Box,{flexDirection:"column",children:Object.entries(t).map(([e,t])=>jsxRuntimeExports.jsx(CommandRow,{command:e,summary:t.summary},e))}),jsxRuntimeExports.jsxs(Text,{children:["Run ",jsxRuntimeExports.jsxs(CommandText,{children:["tessl ",e," COMMAND --help"]})," for more information on a command."]})]}):jsxRuntimeExports.jsxs(Box,{flexDirection:"column",gap:1,children:[jsxRuntimeExports.jsxs(Text,{color:"red",children:["Unknown action '",e,"'"]}),jsxRuntimeExports.jsxs(Text,{
|
|
@@ -4854,12 +4860,12 @@ url:`${DASH0_OTLP_ENDPOINT}/v1/logs`,headers:{Authorization:t}}}}),r.push({targe
|
|
|
4854
4860
|
r}function _nullishCoalesce(e,t){return null!=e?e:t()}const CLI_PROJECT_GROUP_TYPE="CLI Project";class PosthogAnalytics{__init(){this.toolSessionMap=new Map}constructor(e,t,r,n){PosthogAnalytics.prototype.__init.call(this),this.posthog=e,this.distinctId=t,this.projectCache=n,this.runId=null,this.sessionId="",this.shareUsageData=r,this.cliVersion="unknown",this.osType="unknown",this.osRelease="unknown",this.nodeVersion="unknown",this.platformInfo=_nullishCoalesce(platform$1(),()=>"unknown"),this.archInfo=_nullishCoalesce(arch(),()=>"unknown"),this.projectId=""}async initialize(){this.projectId=await getCurrentProjectId(this.projectCache,this.distinctId);const e=getSysinfo();this.cliVersion=_nullishCoalesce(e.version,()=>"unknown"),this.osType=_nullishCoalesce(e.osImplementation,()=>"unknown"),this.osRelease=_nullishCoalesce(e.osRelease,()=>"unknown"),this.nodeVersion=_nullishCoalesce(e.nodeVersion,()=>"unknown");const t=await SessionManager.getCliSessionInfo();this.sessionId=t.sessionId
|
|
4855
4861
|
}static async create(e,t,r,n){const i=new PosthogAnalytics(e,t,r,n);return await i.initialize(),i}captureEvent(e,t){this.runId||(this.runId=v4()),this.captureEventBase(e,{source:"cli",runId:this.runId,sessionId:this.sessionId,...t})}captureEventBase(e,t){if(!this.shareUsageData)return;const r={...t,source:"cli",cliVersion:this.cliVersion,osType:this.osType,osRelease:this.osRelease,nodeVersion:this.nodeVersion,platform:this.platformInfo,arch:this.archInfo,timestamp:(new Date).toISOString()};this.posthog.capture({distinctId:this.distinctId,event:e,properties:r,groups:{[CLI_PROJECT_GROUP_TYPE]:this.projectId}})}capture(e,t){this.captureEvent(e,t)}async refreshCliSession(){const e=await SessionManager.getCliSessionInfo();this.sessionId=e.sessionId}mcpServerStart(){this.captureEvent("cli:mcp:server:start",{})}mcpServerEnd(e){this.captureEvent("cli:mcp:server:end",{...e})}async mcpToolStart(e){const t=await SessionManager.getMcpToolInfo();await this.refreshCliSession();const r={...e,
|
|
4856
4862
|
runId:t.runId,sessionId:t.sessionId,parentRunId:t.parentRunId};return this.captureEventBase("cli:mcp:tool:start",r),t.runId}mcpToolEnd(e){this.captureEventBase("cli:mcp:tool:end",e)}cliStart(e){this.runId=v4(),this.captureEvent("cli:start",e)}runCommand(e,t){this.captureEvent("cli:run",{commandName:e,...t})}getDistinctId(){return this.distinctId}getRunId(){return this.runId}getSessionId(){return this.sessionId}getProjectId(){return this.projectId}runTool(e,t,r){const n=String(e);this.captureEvent("cli:run",{commandName:"tool",toolName:n,params:t,...r})}toolStart(e){const t=`${e.toolName}:${this.runId}`;this.toolSessionMap.set(t,this.sessionId),this.captureEvent("cli:tool:start",e)}toolEnd(e){const t=`${e.toolName}:${this.runId}`,r=this.toolSessionMap.get(t);if(r){const n={...e,originalSessionId:r};this.captureEventBase("cli:tool:end",{source:"cli",runId:this.runId,sessionId:r,...n,timestamp:(new Date).toISOString()}),this.toolSessionMap.delete(t)
|
|
4857
|
-
}else this.captureEvent("cli:tool:end",e)}cliEnd(e){this.captureEvent("cli:end",e),this.runId=null}cliError(e){this.captureEvent("cli:error",e)}runHelp(e){this.captureEvent("cli:run",{commandName:"help",...e})}tileSearch(e){this.captureEvent("cli:tile:search",e)}tileInstall(e){this.captureEvent("cli:tile:install",e)}registrySync(e){this.captureEvent("cli:registry:sync",e)}runVersion(e){this.captureEvent("cli:run",{commandName:"version",...e})}init(e){this.captureEvent("cli:project:init",e)}agentSetup(e){this.captureEvent("cli:agent:setup",e)}frameworkSetup(e){this.captureEvent("cli:framework:setup",e)}mcpSetup(e){this.captureEvent("cli:mcp:setup",e)}trackProjectGroup(e){this.shareUsageData&&this.posthog.groupIdentify({groupType:CLI_PROJECT_GROUP_TYPE,groupKey:e.projectId,properties:{isInitialized:e.isInitialized,$group_set_once:{firstSeenAt:e.firstSeenAt},lastEditedAt:(new Date).toISOString(),nodeVersion:this.nodeVersion,
|
|
4858
|
-
cliVersion:this.cliVersion,osType:this.osType,osRelease:this.osRelease}})}projectMetadata(e){this.captureEventBase("cli:project:metadata",e)}trackProject(e){const t={projectId:this.projectId,distinctId:this.distinctId,...e,nodeVersion:this.nodeVersion,platform:this.platformInfo,arch:this.archInfo,cliVersion:this.cliVersion,osType:this.osType,osRelease:this.osRelease,firstSeenAt:(new Date).toISOString(),lastEditedAt:(new Date).toISOString()};this.trackProjectGroup(t),this.projectMetadata(t)}}async function createPosthogAnalytics(e,t,r,n){return PosthogAnalytics.create(e,t,r,n)}async function _asyncNullishCoalesce(e,t){return null!=e?e:await t()}function _optionalChain(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}
|
|
4859
|
-
const t=getProvisionedEnvPath("production");if(fs__default.existsSync(t))try{validateEnv(cliMonitoringSchema,process.env)}catch(e){e instanceof Error?console.error(formatValidationError(e)):console.error("Failed to validate environment variables: please review the install instructions."),process.exit(FAILURE)}const r=getDefaultGlobalConfigDir(),n=new ConfigManager(join(r,GLOBAL_CONFIG_FILE_NAME),GlobalConfigSchema),{logger:i,logBus:s}=await constructLogger("cli",n),o=await _asyncNullishCoalesce(await n.get("shareUsageData"),async()=>!0);let a,c;try{a=(await readAuth(r)).user}catch(e){i.debug({err:e},"failed to read auth")}if(o&&process.env.LANGFUSE_PROXY_TOKEN){const[e,t]=process.env.LANGFUSE_PROXY_TOKEN.split(":");c=quietLangfuse({publicKey:e,secretKey:t,baseUrl:process.env.LANGFUSE_BASE_URL||"https://42957.tessl.io/",flushAt:1,flushInterval:0})}else c=quietLangfuse();const u=new PostHog("phc_S8tHJaPxa5ORnP0RVyyTaJHeCcft6XMqfjx9ZlJWvkO",{
|
|
4863
|
+
}else this.captureEvent("cli:tool:end",e)}cliEnd(e){this.captureEvent("cli:end",e),this.runId=null}cliError(e){this.captureEvent("cli:error",e)}runHelp(e){this.captureEvent("cli:run",{commandName:"help",...e})}tileSearch(e){this.captureEvent("cli:tile:search",e)}tileInstall(e){this.captureEvent("cli:tile:install",e)}tileUninstall(e){this.captureEvent("cli:tile:uninstall",e)}registrySync(e){this.captureEvent("cli:registry:sync",e)}runVersion(e){this.captureEvent("cli:run",{commandName:"version",...e})}init(e){this.captureEvent("cli:project:init",e)}agentSetup(e){this.captureEvent("cli:agent:setup",e)}frameworkSetup(e){this.captureEvent("cli:framework:setup",e)}mcpSetup(e){this.captureEvent("cli:mcp:setup",e)}trackProjectGroup(e){this.shareUsageData&&this.posthog.groupIdentify({groupType:CLI_PROJECT_GROUP_TYPE,groupKey:e.projectId,properties:{isInitialized:e.isInitialized,$group_set_once:{firstSeenAt:e.firstSeenAt},lastEditedAt:(new Date).toISOString(),nodeVersion:this.nodeVersion,
|
|
4864
|
+
platform:this.platformInfo,arch:this.archInfo,cliVersion:this.cliVersion,osType:this.osType,osRelease:this.osRelease}})}projectMetadata(e){this.captureEventBase("cli:project:metadata",e)}trackProject(e){const t={projectId:this.projectId,distinctId:this.distinctId,...e,nodeVersion:this.nodeVersion,platform:this.platformInfo,arch:this.archInfo,cliVersion:this.cliVersion,osType:this.osType,osRelease:this.osRelease,firstSeenAt:(new Date).toISOString(),lastEditedAt:(new Date).toISOString()};this.trackProjectGroup(t),this.projectMetadata(t)}}async function createPosthogAnalytics(e,t,r,n){return PosthogAnalytics.create(e,t,r,n)}async function _asyncNullishCoalesce(e,t){return null!=e?e:await t()}function _optionalChain(e){let t,r=e[0],n=1;for(;n<e.length;){const i=e[n],s=e[n+1];if(n+=2,("optionalAccess"===i||"optionalCall"===i)&&null==r)return;"access"===i||"optionalAccess"===i?(t=r,r=s(r)):"call"!==i&&"optionalCall"!==i||(r=s((...e)=>r.call(t,...e)),t=void 0)}return r}
|
|
4865
|
+
async function startMonitoring(e){const t=getProvisionedEnvPath("production");if(fs__default.existsSync(t))try{validateEnv(cliMonitoringSchema,process.env)}catch(e){e instanceof Error?console.error(formatValidationError(e)):console.error("Failed to validate environment variables: please review the install instructions."),process.exit(FAILURE)}const r=getDefaultGlobalConfigDir(),n=new ConfigManager(join(r,GLOBAL_CONFIG_FILE_NAME),GlobalConfigSchema),{logger:i,logBus:s}=await constructLogger("cli",n),o=await _asyncNullishCoalesce(await n.get("shareUsageData"),async()=>!0);let a,c;try{a=(await readAuth(r)).user}catch(e){i.debug({err:e},"failed to read auth")}if(o&&process.env.LANGFUSE_PROXY_TOKEN){const[e,t]=process.env.LANGFUSE_PROXY_TOKEN.split(":");c=quietLangfuse({publicKey:e,secretKey:t,baseUrl:process.env.LANGFUSE_BASE_URL||"https://42957.tessl.io/",flushAt:1,flushInterval:0})}else c=quietLangfuse();const u=new PostHog("phc_S8tHJaPxa5ORnP0RVyyTaJHeCcft6XMqfjx9ZlJWvkO",{
|
|
4860
4866
|
host:process.env.POSTHOG_HOST||"https://app.posthog.com"});"yes"===process.env.TESSL_DEBUG_MONITORING&&u.debug(!0);const l=userIdentifier(a);setOtelUser(a),u.identify({distinctId:l,properties:{...o?getSysinfo():{},email:a?a.email:void 0}}),a&&u.alias({distinctId:a.id,alias:loggedOutUserIdentifier()}),_optionalChain([a,"optionalAccess",e=>e.email])&&u.alias({distinctId:a.id,alias:a.email});const d=await createPosthogAnalytics(u,l,o,e);return{monitoring:{shareUsageData:o,user:a?{id:a.id,email:a.email}:void 0,langfuse:c,logger:i,logBus:s,reporter:new ReportEmitter,posthogCapture:(e,t)=>{(o||_optionalChain([t,"optionalAccess",e=>e.bypassOptOut]))&&u.capture({distinctId:l,event:e.event,properties:e.properties})},analytics:d,shutdown:async()=>{i.debug({},"Shutting down monitoring services");const e=async()=>new Promise((e,t)=>setTimeout(()=>t(new Error("Monitoring shutdown timed out")),2e3));try{await Promise.race([u.flush(),e()])}catch(e){i.error({err:e},"Failed to flush PostHog events")}
|
|
4861
|
-
try{await Promise.race([c.flushAsync(),e()]),i.debug({},"Successfully flushed Langfuse events")}catch(e){i.error({err:e},"Failed to flush Langfuse events")}try{await flushLogger(i.originalLogger),i.debug({},"Successfully flushed logger")}catch(e){}}},globalConfig:n}}async function entry(){if(!await checkLegal())return
|
|
4862
|
-
console.error("Error occurred during exit:",e),process.exit(1)});const execAsync=require$$1$6.promisify(require$$0$8.exec);async function getMachineId$4(){try{const e=(await execAsync('ioreg -rd1 -c "IOPlatformExpertDevice"')).stdout.split("\n").find(e=>e.includes("IOPlatformUUID"));if(!e)return;const t=e.split('" = "');if(2===t.length)return t[1].slice(0,-1)}catch(e){diag.debug(`error reading machine id: ${e}`)}}var getMachineIdDarwin=Object.freeze({__proto__:null,
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
e instanceof Error&&console.error(e.message)}try{const{zodToJsonSchema:e}=await Promise.resolve().then(function(){return index$1});t=e}catch(e){e instanceof Error&&console.error(e.message)}return async r=>"_zod"in r?e(r):t(r)};var zodBw_60DVU=Object.freeze({__proto__:null,getToJsonSchemaFn});export{entry};
|
|
4867
|
+
try{await Promise.race([c.flushAsync(),e()]),i.debug({},"Successfully flushed Langfuse events")}catch(e){i.error({err:e},"Failed to flush Langfuse events")}try{await flushLogger(i.originalLogger),i.debug({},"Successfully flushed logger")}catch(e){}}},globalConfig:n}}async function entry(){let e;const t=Date.now()-1e3*process.uptime();let r;try{r=await withSpan("cli.complete",async()=>{try{const t=await withSpan("cli.startup",async()=>{if(!await withSpan("cli.checkLegal",async()=>checkLegal()))return{exitCode:145};withSpan("cli.initSysinfo",async()=>initSysinfo());const t=await withSpan("cli.checkDeprecation",async()=>checkDeprecationStatusWithCache());if(t)return console.error(t.message),console.error(t.installUrl),{exitCode:DEPRECATED_EXIT_CODE};const r=sessionData(),n=projectCache(),i=await withSpan("cli.startMonitoring",async()=>startMonitoring(n));e=i.monitoring;const s=i.globalConfig;return{sd:r,pc:n,monitoring:e,globalConfig:s}});if("exitCode"in t)return t.exitCode;try{
|
|
4868
|
+
return await withSpan("cli.main",async()=>main(t.monitoring,t.globalConfig,t.sd,t.pc))}catch(t){return e.logger.error({err:t},"critical error during main"),e.analytics.cliError({command:process.argv.slice(2).join(" "),message:t instanceof Error?t.message:String(t),stack:t instanceof Error&&t.stack||"",expected:t instanceof ExpectedError}),144}}finally{e&&await withSpan("cli.shutdown.monitoring",async()=>e.shutdown())}},t)}finally{await sdk.shutdown(),showCursor()}return r}entry().then(e=>{process.exit(e)}).catch(e=>{console.error("Error occurred during exit:",e),process.exit(1)});const execAsync=require$$1$6.promisify(require$$0$8.exec);async function getMachineId$4(){try{const e=(await execAsync('ioreg -rd1 -c "IOPlatformExpertDevice"')).stdout.split("\n").find(e=>e.includes("IOPlatformUUID"));if(!e)return;const t=e.split('" = "');if(2===t.length)return t[1].slice(0,-1)}catch(e){diag.debug(`error reading machine id: ${e}`)}}var getMachineIdDarwin=Object.freeze({__proto__:null,
|
|
4869
|
+
getMachineId:getMachineId$4});async function getMachineId$3(){const e=["/etc/machine-id","/var/lib/dbus/machine-id"];for(const t of e)try{return(await promises.readFile(t,{encoding:"utf8"})).trim()}catch(e){diag.debug(`error reading machine id: ${e}`)}}var getMachineIdLinux=Object.freeze({__proto__:null,getMachineId:getMachineId$3});async function getMachineId$2(){try{return(await promises.readFile("/etc/hostid",{encoding:"utf8"})).trim()}catch(e){diag.debug(`error reading machine id: ${e}`)}try{return(await execAsync("kenv -q smbios.system.uuid")).stdout.trim()}catch(e){diag.debug(`error reading machine id: ${e}`)}}var getMachineIdBsd=Object.freeze({__proto__:null,getMachineId:getMachineId$2});async function getMachineId$1(){let e="%windir%\\System32\\REG.exe";"ia32"===process$4.arch&&"PROCESSOR_ARCHITEW6432"in process$4.env&&(e="%windir%\\sysnative\\cmd.exe /c "+e);try{
|
|
4870
|
+
const t=(await execAsync(`${e} QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid`)).stdout.split("REG_SZ");if(2===t.length)return t[1].trim()}catch(e){diag.debug(`error reading machine id: ${e}`)}}var getMachineIdWin=Object.freeze({__proto__:null,getMachineId:getMachineId$1});async function getMachineId(){diag.debug("could not read machine-id: unsupported platform")}var getMachineIdUnsupported=Object.freeze({__proto__:null,getMachineId});const getToJsonSchemaFn$4=async()=>e=>e.toJsonSchema();var arktypeCGObzDh=Object.freeze({__proto__:null,getToJsonSchemaFn:getToJsonSchemaFn$4});const getToJsonSchemaFn$3=async()=>{const{JSONSchema:e}=await tryImport(import("effect"),"effect");return t=>e.make(t)};var effect_Zg3C1LQ=Object.freeze({__proto__:null,getToJsonSchemaFn:getToJsonSchemaFn$3});const getToJsonSchemaFn$2=async()=>{const{toJSONSchema:e}=await tryImport(import("sury"),"sury");return t=>e(t)};var suryS6AklOc=Object.freeze({__proto__:null,
|
|
4871
|
+
getToJsonSchemaFn:getToJsonSchemaFn$2});const getToJsonSchemaFn$1=async()=>{const{toJsonSchema:e}=await tryImport(import("@valibot/to-json-schema"),"@valibot/to-json-schema");return t=>e(t)};var valibotDBCeetIe=Object.freeze({__proto__:null,getToJsonSchemaFn:getToJsonSchemaFn$1});const getToJsonSchemaFn=async()=>{let e=e=>{throw new Error(`xsschema: Missing zod v4 dependencies "zod". see ${missingDependenciesUrl}`)},t=e=>{throw new Error(`xsschema: Missing zod v3 dependencies "zod-to-json-schema". see ${missingDependenciesUrl}`)};try{const{toJSONSchema:t}=await Promise.resolve().then(function(){return index});e=t}catch(e){e instanceof Error&&console.error(e.message)}try{const{zodToJsonSchema:e}=await Promise.resolve().then(function(){return index$1});t=e}catch(e){e instanceof Error&&console.error(e.message)}return async r=>"_zod"in r?e(r):t(r)};var zodBw_60DVU=Object.freeze({__proto__:null,getToJsonSchemaFn});export{entry};
|